Как получить доступ к методу от одного GameObject к другому на Google OnAdclosed на Unity? - PullRequest
0 голосов
/ 08 октября 2019

У меня есть GameScreenManger, который будет отображать или скрывать панель в зависимости от статуса игры. У меня есть AdManager gameObject, который содержит скрипт, который обрабатывает рекламу. Я могу показать объявление, но в onAdclosed, если я попытался сделать ссылку на GameScreenManager, который содержит скрипт в Admanager Script, и вызвать функцию, когда функция прослушивателей события onAdclosed, вызов инициируется, но действия не работают. Может ли кто-нибудь помочь мне в этом?

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

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();
    }
}

Ответы [ 2 ]

3 голосов
/ 08 октября 2019

Поскольку обратные вызовы поступают из неосновного потока, а Unity - это однопотоковая среда, поэтому некоторые API Unity недоступны из неосновных потоков, например, вы не можете использовать GameObject.SetActive или многие другие функции компонентов. кроме основного потока, то, что вам нужно сделать, это сначала отправить обратный вызов в основной поток, а затем будут выполнены все операторы в вашей функции.

Вот как.

1) Простойдиспетчер, который выполняет методы в главном потоке единицы. создайте пустой игровой объект на своей сцене и прикрепите его к нему.

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) Отредактируйте закрытый обратный вызов по объявлению для отправки в основной поток.

    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);
        });
    }
0 голосов
/ 08 октября 2019

Похоже, что у вас нет ссылки на ваш объект во втором сценарии:

Рекламный скрипт

public GameScreenManager gsmanagerRef; //drag and drop on the editor or find it on initialization

, тогда вы сможете вызвать

gsmanagerRef.ShowResume(); //or any other function

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...