首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何访问方法从一个GameObject到另一个谷歌OnAdclosed on Unity?

如何访问方法从一个GameObject到另一个谷歌OnAdclosed on Unity?
EN

Stack Overflow用户
提问于 2019-10-08 16:54:53
回答 2查看 430关注 0票数 0

我有一个GameScreenManger,可以根据游戏状态显示或隐藏面板。我有一个AdManager gameObject,它包含一个处理广告的脚本。我可以显示广告,但在onAdclosed上,如果我尝试引用GameScreenManager,并在onAdclosed事件侦听器函数时调用函数,则调用正在触发,但操作不起作用。有人能在这方面帮我吗?

代码语言:javascript
复制
using UnityEngine;
using GoogleMobileAds.Api;
using System;

public class AdManager : MonoBehaviour
{
    public static AdManager instance;

    private string appId = "";

    private InterstitialAd InterstitialAd;
    private string InterstitialAdId = "interstitial_Ad_Id";


    private RewardedAd RewardedVideoAd;
    private string RewardedVideoAdId = "rewarded_video_ad_Id ";

    public GameObject RewardPanel;
    public GameScreenManager gameManager;

    public bool isRewardedVideo;

    private bool RewardedVideoLoaded = false;

    public void Awake()
    {
        if(instance == null)
        {                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
            instance = this;
        } else
        {
            Destroy(this);
        }

        MobileAds.Initialize(initStatus => { });
    }

    private void Start()
    {
        RequestInterstitial();

        RewardedVideoAd = new RewardedAd(RewardedVideoAdId);

        RequestRewardedVideo();

        // Called when an ad request has successfully loaded.
        this.RewardedVideoAd.OnAdLoaded += HandleRewardedAdLoaded;

        // Called when an ad request failed to load.
        this.RewardedVideoAd.OnAdFailedToLoad += HandleRewardedAdFailedToLoad;

        // Called when an ad is shown.
        this.RewardedVideoAd.OnAdOpening += HandleRewardedAdOpening;

        // Called when an ad request failed to show.
        this.RewardedVideoAd.OnAdFailedToShow += HandleRewardedAdFailedToShow;

        // Called when the user should be rewarded for interacting with the ad.
        this.RewardedVideoAd.OnUserEarnedReward += HandleUserEarnedReward;

        // Called when the ad is closed.
        this.RewardedVideoAd.OnAdClosed += HandleRewardedAdClosed;

    }

    private void Update()
    {
        if (RewardedVideoLoaded == false)
        {
            RequestRewardedVideo();
        }
    }

    private void RequestInterstitial()
    {
        string adUnitId = InterstitialAdId;

        // Initialize an InterstitialAd.
        this.InterstitialAd = new InterstitialAd(adUnitId);

        // Create an empty ad request.
        AdRequest request = new AdRequest.Builder().Build();
        // Load the interstitial with the request.
        this.InterstitialAd.LoadAd(request);
    }

    public void ShowInterstitial()
    {
        if (this.InterstitialAd.IsLoaded())
        {
            this.InterstitialAd.Show();
        }
    }

    public void RequestRewardedVideo()
    {
        // Create an empty ad request.
        AdRequest request = new AdRequest.Builder().Build();
        // Load the interstitial with the request.
        this.RewardedVideoAd.LoadAd(request);

        if (this.RewardedVideoAd.IsLoaded())
        {
            isRewardedVideo = true;
            RewardedVideoLoaded = true;
        } else
        {
            isRewardedVideo = false;
            RewardedVideoLoaded = false;
        }
    }

    public void ShowRewardedVideo()
    {
        if (this.RewardedVideoAd.IsLoaded())
        {
            this.RewardedVideoAd.Show();
        }
    }

    public void HandleRewardedAdLoaded(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleRewardedAdLoaded event received");
    }

    public void HandleRewardedAdFailedToLoad(object sender, AdErrorEventArgs args)
    {
        MonoBehaviour.print(
            "HandleRewardedAdFailedToLoad event received with message: "
                             + args.Message);
    }

    public void HandleRewardedAdOpening(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleRewardedAdOpening event received");
    }

    public void HandleRewardedAdFailedToShow(object sender, AdErrorEventArgs args)
    {
        MonoBehaviour.print(
            "HandleRewardedAdFailedToShow event received with message: "
                             + args.Message);
    }

    public void HandleRewardedAdClosed(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleRewardedAdClosed event received");

        Debug.Log("{lo} OnClosed called sender = " + sender);

        RequestRewardedVideo();

        gameManager.CheckForLives(); //This is not working.

        this.RewardPanel.SetActive(true);

    }

    public void HandleUserEarnedReward(object sender, Reward args)
    {

        Debug.Log("{lo} Earned a Reward  HandleUserEarnedReward called!");

        string type = args.Type;
        double amount = args.Amount;
        this.RewardPanel.SetActive(true);

    }
}

GameScreen脚本

代码语言:javascript
复制
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class GameScreenManager : MonoBehaviour
{
    public GameObject PauseScreen;
    public GameObject OutOfLifeScreen;
    public GameObject PauseButton;
    public GameObject Scoretext;
    public GameObject Livesbutton;

    public Text MusicText;

    public void LoadPause()
    {
        PauseScreen.SetActive(true);
        bool audioPlaying = FindObjectOfType<AudioManager>().audioPlaying;

        MusicText.text = audioPlaying ? "MUSIC ON" : "MUSIC OFF";
        Time.timeScale = 0f;
    }

    public void ShowResume()
    {
        PauseScreen.SetActive(false);
        Time.timeScale = 1f;
    }

    public void ShowMainMenu()
    {
        Time.timeScale = 1f;
        SceneManager.LoadScene("Menu");
    }

    public void ShowOutOfLives()
    {
        OutOfLifeScreen.SetActive(true);
        PauseButton.SetActive(false);
        Time.timeScale = 0f;

    }

    public void CloseOutOfLives()
    {

       Debug.Log(" {lo} Entered CloseOutOfLives");
       OutOfLifeScreen.SetActive(false);
       PauseButton.SetActive(true);
       Time.timeScale = 1f;
    }

    public void TogggleSound()
    {
        FindObjectOfType<AudioManager>().ToggleMute();
        bool audioPlaying = FindObjectOfType<AudioManager>().audioPlaying;

        MusicText.text = audioPlaying ? "MUSIC ON" : "MUSIC OFF";
        PlayerPrefs.SetInt("audioNeeded", audioPlaying ? 1 : 0);
    }

    public void Quit()
    {
        Application.Quit();
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-08 17:32:18

因为回调来自非主线程,而unity是单线程环境,所以一些unity API不能从非主线程访问,例如,除了主线程之外,您不能使用GameObject.SetActive或更多组件函数,所以您需要做的是首先将回调分派到主线程,然后函数中的所有语句都将执行。

下面是如何实现的。

1)一个简单的调度程序,它在unity的主线程上执行方法。在场景中创建一个空游戏对象,并将其附加到该对象。

代码语言:javascript
复制
using System;
using System.Collections.Generic;

/// <summary>
/// Helps dispatch task results to the main thread to be able to operate on unity's API like SetActive, enabled etc...
/// </summary>
public class MainThreadDispatcher : MonoBehaviour
{
    Queue<Action> jobs = new Queue<Action>();
    static MainThreadDispatcher Instance = null;

    private void Awake()
    {
        Instance = this;
    }
    private void Update()
    {
        while (jobs.Count > 0)
        {
            var next = jobs.Dequeue();
            if(next != null)
            {
                next.Invoke();
            }
        }
    }
    /// <summary>
    /// Dispatches a function to be executed on unity's main thread to be able to use unity's API.
    /// </summary>
    /// <param name="newJob"></param>
    public static void Dispatch(Action newJob)
    {
        if (newJob == null)
            return;
        Instance.jobs.Enqueue(newJob);
    }
}

2)编辑on ad closed回调,调度到主线程。

代码语言:javascript
复制
    public void HandleRewardedAdClosed(object sender, EventArgs args)
    {
        // simply give unity control back.
        // you can pick and choose to execute what on main thread,
        // but I'm just gonna dispatch the whole block.
        MainThreadDispatcher.Dispatch(() =>
        {
            MonoBehaviour.print("HandleRewardedAdClosed event received");

            Debug.Log("{lo} OnClosed called sender = " + sender);

            RequestRewardedVideo();

            gameManager.CheckForLives();

            this.RewardPanel.SetActive(true);
        });
    }
票数 3
EN

Stack Overflow用户

发布于 2019-10-08 17:00:00

在第二个脚本中似乎没有对对象的引用:

广告脚本

代码语言:javascript
复制
public GameScreenManager gsmanagerRef; //drag and drop on the editor or find it on initialization

然后,您应该能够调用

代码语言:javascript
复制
gsmanagerRef.ShowResume(); //or any other function

希望这能有所帮助!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58283080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档