在 Unity 中重新加载场景后多次调用 Google Admob Reward Video 回调

Google Admob Reward Video callback called mutiple times after reloading scene in Unity(在 Unity 中重新加载场景后多次调用 Google Admob Reward Video 回调)
本文介绍了在 Unity 中重新加载场景后多次调用 Google Admob Reward Video 回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Unity 中开发一个安卓游戏 apk.我已经在我的项目中集成了 Google Admob SDK,并通过引用 https://developers.google.com/admob/unity/rewarded-video.

I'm developing an android game apk in Unity. I've integrated Google Admob SDK in my project and succeeded to show the Google admob reward video ads in my android apk by referring https://developers.google.com/admob/unity/rewarded-video.

但是当重新加载场景以重新开始游戏时回调函数被多次调用.

However when scene is reloaded to restart game callback functions called multiple times.

回调函数示例:

// Called when an ad request has successfully loaded.
rewardBasedVideo.OnAdLoaded += HandleRewardBasedVideoLoaded;
// Called when an ad request failed to load.
rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoFailedToLoad;
// Called when an ad is shown.
rewardBasedVideo.OnAdOpening += HandleRewardBasedVideoOpened;
// Called when the ad starts to play.
rewardBasedVideo.OnAdStarted += HandleRewardBasedVideoStarted;
// Called when the user should be rewarded for watching a video.
rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;

第一次加载场景:回调函数被调用了 1 次.

scene loaded first time: callback functions are called 1 time.

再次加载场景:回调函数被调用了 2 次.

scene loaded again: callback functions are called 2 times.

再次加载场景:回调函数被调用 3 次.

scene loaded again: callback functions are called 3 times.

...

我认为根本原因是即使重新加载Unity场景也会累积回调函数.

I think the root cause is that callback functions are accumulated even reloading Unity scenes.

如何让这样的回调函数即使改变场景也只调用1次?

How can I make such callback functions be called only 1 time even changing scene?

推荐答案

所以我终于想出了让广告正常工作的解决方案

So I finally figured out the solution to get the ads working properly

首先安装谷歌显示的谷歌广告SDK

First install the google ad SDK as shown by Google

在此处关注 Google 的 admonb unity 集成教程

然后将以下脚本用于横幅广告、插页式广告以及激励视频广告

Then use the following script for Banner,Interstitial as well as Rewarded Video Ads

SaveManager 和相关的是我的函数中使用的一些脚本

SaveManager and related are some scripts used in my function

忽略它们

update 函数中,您必须不断检查布尔值以查看广告是否已加载.我们将使用 Google Admob 提供的回调来更改这个布尔值,因为广告是在其他线程上并行加载的.我不是多线程或并行处理方面的专家,但我发现你不能从这些回调中调用 Unity 函数,而是可以在那里设置一些 bool,然后继续检查 update 函数中的 bool 值

In the update function you have to check a boolean continuously to see if the ads are loaded or not. We will change this boolean's value using callbacks provided by Google Admob, as ads are being loaded paralelly on some other thread. I am not an expert in multithreading or parallel processing, but what I have found is you cannot call Unity functions from those callbacks, instead you can set some bool there, and then keep on checking the bool's value in update function

查看插页式广告和激励广告的 onAdFailedToLoad 事件处理程序

See the onAdFailedToLoad event handlers of interstitial and rewarded ads

    using System;
    using UnityEngine;
    using UnityEngine.UI;
    using GoogleMobileAds.Api;

    // Example script showing how to invoke the Google Mobile Ads Unity plugin.

    public class adMob : MonoBehaviour
    {
    private BannerView bannerView;
    private InterstitialAd interstitial;
    private RewardedAd rewardedAd;
    private float deltaTime = 0.0f;
    private static string outputMessage = string.Empty;

    public Text coinValueHolder;
    int rewardAmount;

    private bool reqInterstitial = true;
    private bool reqRewardedAdVideo = true;

    public static adMob ins;

    public static string OutputMessage
    {
        set { outputMessage = value; }
    }

    public void Start()
    {

        #if UNITY_ANDROID
        string appId = "ca-app-pub-3940256099942544~3347511713";
        #elif UNITY_IPHONE
        string appId = "ca-app-pub-3940256099942544~1458002511";
        #else
        string appId = "unexpected_platform";
        #endif

        MobileAds.SetiOSAppPauseOnBackground(true);

        // Initialize the Google Mobile Ads SDK.
        MobileAds.Initialize(appId);

        this.CreateAndLoadRewardedAd();
    }

    // making the current object a singleton
    public void Awake()
    {
        if (ins == null)
        {
            ins = this;
            DontDestroyOnLoad(gameObject);
        }
        else if (ins != null)
        {
            Destroy(gameObject);
        }
    }

    public void Update()
    {
        // Calculate simple moving average for time to render screen. 0.1 factor used as 
        smoothing
        // value.
        this.deltaTime += (Time.deltaTime - this.deltaTime) * 0.1f;

        if (rewardAmount > 0)
        {
            coinValueHolder = 
            GameObject.FindGameObjectWithTag("coinText").GetComponent<Text>();

            SaveManager.coins += 100;
            SaveManager.ins.SaveDataFromDataObjects();
            coinValueHolder.text = SaveManager.coins.ToString();
            rewardAmount = 0;
        }

        if(reqInterstitial)
        {
            this.RequestInterstitial();
            reqInterstitial = false;
        }

        if(reqRewardedAdVideo)
        {
            this.CreateAndLoadRewardedAd();
            reqRewardedAdVideo = false;
        }
    }

    // Returns an ad request with custom ad targeting.
    public AdRequest CreateAdRequest()
    {
        return new AdRequest.Builder().Build();
    }

    public void RequestBanner()
    {
        // These ad units are configured to always serve test ads.
        #if UNITY_EDITOR
        string adUnitId = "unused";
        #elif UNITY_ANDROID
        string adUnitId = "ca-app-pub-3940256099942544/6300978111";
        #elif UNITY_IPHONE
        string adUnitId = "ca-app-pub-3940256099942544/2934735716";
        #else
        string adUnitId = "unexpected_platform";
        #endif

        // Clean up banner ad before creating a new one.
        if (this.bannerView != null)
        {
            this.bannerView.Destroy();
        }

        // Create a 320x50 banner at the top of the screen.
        this.bannerView = new BannerView(adUnitId, AdSize.Banner, AdPosition.Bottom);

        // Register for ad events.
        this.bannerView.OnAdLoaded += this.HandleAdLoaded;
        this.bannerView.OnAdFailedToLoad += this.HandleAdFailedToLoad;
        this.bannerView.OnAdOpening += this.HandleAdOpened;
        this.bannerView.OnAdClosed += this.HandleAdClosed;
        this.bannerView.OnAdLeavingApplication += this.HandleAdLeftApplication;

        // Load a banner ad.
        this.bannerView.LoadAd(this.CreateAdRequest());
    }

    public void DestroyBanner()
    {
        this.bannerView.Destroy();
    }

    public void RequestInterstitial()
    {
        // These ad units are configured to always serve test ads.
        #if UNITY_EDITOR
        string adUnitId = "unused";
        #elif UNITY_ANDROID
        string adUnitId = "ca-app-pub-3940256099942544/1033173712";
        #elif UNITY_IPHONE
        string adUnitId = "ca-app-pub-3940256099942544/4411468910";
        #else
        string adUnitId = "unexpected_platform";
        #endif

        // Clean up interstitial ad before creating a new one.
        if (this.interstitial != null)
        {
            this.interstitial.Destroy();
        }

        // Create an interstitial.
        this.interstitial = new InterstitialAd(adUnitId);

        // Register for ad events.
        this.interstitial.OnAdLoaded += this.HandleInterstitialLoaded;
        this.interstitial.OnAdFailedToLoad += this.HandleInterstitialFailedToLoad;
        this.interstitial.OnAdOpening += this.HandleInterstitialOpened;
        this.interstitial.OnAdClosed += this.HandleInterstitialClosed;
        this.interstitial.OnAdLeavingApplication += 
        this.HandleInterstitialLeftApplication;

        // Load an interstitial ad.
        this.interstitial.LoadAd(this.CreateAdRequest());
    }

    public void CreateAndLoadRewardedAd()
    {
        #if UNITY_EDITOR
        string adUnitId = "unused";
        #elif UNITY_ANDROID
        string adUnitId = "ca-app-pub-3940256099942544/5224354917";
        #elif UNITY_IPHONE
        string adUnitId = "ca-app-pub-3940256099942544/1712485313";
        #else
        string adUnitId = "unexpected_platform";
        #endif
        // Create new rewarded ad instance.
        this.rewardedAd = new RewardedAd(adUnitId);

        // Called when an ad request has successfully loaded.
        this.rewardedAd.OnAdLoaded += HandleRewardedAdLoaded;
        // Called when an ad request failed to load.
        this.rewardedAd.OnAdFailedToLoad += HandleRewardedAdFailedToLoad;
        // Called when an ad is shown.
        this.rewardedAd.OnAdOpening += HandleRewardedAdOpening;
        // Called when an ad request failed to show.
        this.rewardedAd.OnAdFailedToShow += HandleRewardedAdFailedToShow;
        // Called when the user should be rewarded for interacting with the ad.
        this.rewardedAd.OnUserEarnedReward += HandleUserEarnedReward;
        // Called when the ad is closed.
        this.rewardedAd.OnAdClosed += HandleRewardedAdClosed;

        // Create an empty ad request.
        AdRequest request = this.CreateAdRequest();
        // Load the rewarded ad with the request.
        this.rewardedAd.LoadAd(request);
    }

    public void ShowInterstitial()
    {
        if (this.interstitial.IsLoaded())
        {
            this.interstitial.Show();
        }
        else
        {
            MonoBehaviour.print("Interstitial is not ready yet");
        }
    }

    public void ShowRewardedAd()
    {
        if (this.rewardedAd.IsLoaded())
        {
            this.rewardedAd.Show();
        }
        else
        {
            MonoBehaviour.print("Rewarded ad is not ready yet");
        }
    }

    #region Banner callback handlers

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

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

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

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

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

    #endregion

    #region Interstitial callback handlers

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

    public void HandleInterstitialFailedToLoad(object sender, AdFailedToLoadEventArgs args)
    {
        MonoBehaviour.print(
            "HandleInterstitialFailedToLoad event received with message: " + args.Message);
        this.reqInterstitial = true;
    }

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

    public void HandleInterstitialClosed(object sender, EventArgs args)
    {
        MonoBehaviour.print("HandleInterstitialClosed event received");
        this.reqInterstitial = true;
    }

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

    #endregion

    #region RewardedAd callback handlers

    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);
        this.reqRewardedAdVideo = true;
    }

    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");
        this.reqRewardedAdVideo = true;
    }

    public void HandleUserEarnedReward(object sender, Reward args)
    {
        string type = args.Type;
        double amount = args.Amount;
        rewardAmount = (int)amount;

        MonoBehaviour.print(
            "HandleRewardedAdRewarded event received for "
                        + amount.ToString() + " " + type);
    }

    #endregion
}

将上述脚本放在 Hierachy 中的 GameObject 上

Place the above script on a GameObject in Hierachy

调用广告使用

    adMob.ins.DestroyBanner();

或任何其他功能(声明静态ins并引用游戏对象称为单例模式,用于声音管理器、场景管理器、添加管理器等管理器)

or any other function ( declaring a static ins and referring the gameobject is known as singleton pattern, which is used in Managers like sound manager, Scene Manager, Add Managers )

    adMob.ins._Your-Function-Name_();

你需要在使用后取消订阅事件句柄,否则你会得到意想不到的行为:

You need to unsubscribe handles from events after using it or you will get unexpected behaviours:

void OnDestroy()
{
        // Called when an ad request has successfully loaded.
        rewardBasedVideo.OnAdLoaded -= HandleRewardBasedVideoLoaded;
        // Called when an ad request failed to load.
        rewardBasedVideo.OnAdFailedToLoad -= HandleRewardBasedVideoFailedToLoad;
        // Called when an ad is shown.
        rewardBasedVideo.OnAdOpening -= HandleRewardBasedVideoOpened;
        // Called when the ad starts to play.
        rewardBasedVideo.OnAdStarted -= HandleRewardBasedVideoStarted;
        // Called when the user should be rewarded for watching a video.
        rewardBasedVideo.OnAdRewarded -= HandleRewardBasedVideoRewarded;
}

以 OnDestroy 方法为例.

Do it in OnDestroy method, for example.

这篇关于在 Unity 中重新加载场景后多次调用 Google Admob Reward Video 回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

How to target newer versions in .gitlab-ci.yml using auto devops (java 11 instead of 8 and Android 31 instead of 29)(如何在.gitlab-ci.yml中使用自动开发工具(Java 11而不是8,Android 31而不是29)瞄准较新的版本)
Android + coreLibraryDesugaring: which Java 11 APIs can I expect to work?(Android+core LibraryDesugering:我可以期待哪些Java 11API能够工作?)
How to render something in an if statement React Native(如何在If语句中呈现某些内容Reaction Native)
How can I sync two flatList scroll position in react native(如何在本机Reaction中同步两个平面列表滚动位置)
Using Firebase Firestore in offline only mode(在仅脱机模式下使用Firebase FiRestore)
Crash on Google Play Pre-Launch Report: java.lang.NoSuchMethodError(Google Play发布前崩溃报告:java.lang.NoSuchMethodError)