Google Admob Reward Video callback called mutiple times after reloading scene in Unity

筅森魡賤 提交于 2020-01-03 04:54:15

问题


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.

callback function example:

// 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;

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

scene loaded again: callback functions are called 2 times.

scene loaded again: callback functions are called 3 times.

...

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

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


回答1:


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

First install the google ad SDK as shown by Google

Follow the Google's admonb unity integration tutotrial here

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

SaveManager and related are some scripts used in my function

Ignore them

You have to update and call ads in update function and use bool to check if the event handlers are called or not.

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

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

}

Place the above script on a GameObject in Hierachy

To call an ad use

adMob.ins.DestroyBanner();

or any other function

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



回答2:


You need to unsubscribe handles from events after using:

    // 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;

Do it in OnDestroy method, for example.



来源:https://stackoverflow.com/questions/50290851/google-admob-reward-video-callback-called-mutiple-times-after-reloading-scene-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!