admob interstitial 回调事件只工作一次而不是第二次

admob interstitial callback events only work once and not the second time

我做了一个简单的设置。我有一个带有播放按钮的主菜单场景。

当我按下它时,它会显示一个插页式广告,当我关闭广告时,回调事件会正确触发,游戏场景开始。 现在当我输了,游戏就结束了,游戏结束的场景开始了,有一个重播按钮。

当我按下重播按钮时,再次显示一个插页式广告,但当我关闭广告时,没有触发任何回调事件,我仍然停留在游戏结束的场景中。

如果我再次按下回复按钮,则什么也不会发生,甚至连广告都不会出现。我在我的 admanager 脚本中使用了 dontdestroyonload。

如何在每次展示广告时触发回调事件?
我做错了什么吗?
有没有更好的方法来编写 admob admanager 脚本?

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using System;
 using GoogleMobileAds.Api;
 using UnityEngine.SceneManagement;
 using TMPro;


 public class AdManager : MonoBehaviour
 {
     private BannerView bannerView;
     private InterstitialAd interstitial;
     private RewardedAd rewardAd;
     public static AdManager instance;
     //public TextMeshProUGUI testText;
     //bool adClosed = false;
     int bannerAdStatus = 0;
     int interstitialAdStatus = 0;
     int rewardAdStatus = 0;
     //bool destroyObject = false;
     float retryInterval = 1f;
     float initTime;
     bool mBound = false;
     //bool adFailed = false;

     public void Awake()
     {
         Debug.Log("AdManager..Awake");
         Debug.Log("AdManager.instance = "+ GetInstanceID());


         if (instance == null)
         {
             Debug.Log("AdManager..Awake..if" + GetInstanceID());

             instance = this;
             DontDestroyOnLoad(gameObject);
         }
         else
         {
             if (instance != this)
             {
                 Debug.Log("AdManager..Awake..else" + GetInstanceID());

                 Debug.Log("More than one AdManager in scene");
                 Destroy(this.gameObject);
                 return;
             }
         }
         Debug.Log("AdManager.instance = " + GetInstanceID());


         /*if (instance == null)
         {
             instance = this;
         }*/
         // Initialize the Google Mobile Ads SDK.
         MobileAds.Initialize(initStatus => { });

         RequestAd();

     }

     void RequestAd()
     {
         Debug.Log("AdManager..RequestAd" + GetInstanceID());

         this.RequestBanner();
         this.RequestInterstitial();
         this.RequestRewardAd();
     }

     private void Update()
     {
         switch (bannerAdStatus)
         {
             case 0:
                 break;
             case 1:
                 break;

             case 2:
                 if (Time.time - initTime >= retryInterval)
                 {
                     RequestBanner();
                 }
                 break;

             case 3:
                 break;

             case 4:
                 //MainMenuUI.Play();
                 bannerAdStatus = 0;
                 RequestBanner();
                 break;

             case 5:
                 break;



             default:
                 break;
         }
         switch (interstitialAdStatus)
         {
             case 0:
                 break;
             case 1:
                 break;

             case 2:
                 if (Time.time - initTime >= retryInterval)
                 {
                     RequestInterstitial();
                 }
                 break;

             case 3:
                 break;

             case 4:                
                 interstitialAdStatus = 0;
                 RequestInterstitial();
                 SceneManager.LoadScene(SceneIndexer.Gameplay);
                 break;

             case 5:
                 break;



             default:
                 break;
         }
         switch (rewardAdStatus)
         {
             case 0:
                 break;
             case 1:
                 break;

             case 2:
             case 4:
                 if (Time.time - initTime >= retryInterval)
                 {
                     RequestRewardAd();
                 }                
                 break;

             case 3:
                 break;

             case 5:
                 rewardAdStatus = 0;
                 RequestRewardAd();
                 break;

             case 6:
                 break;


             default:
                 break;
         }

     }

     private void Start()
     {
         Debug.Log("AdManager..Start");
         Debug.Log("AdManager..Start..mBound = " + mBound + GetInstanceID());
         if (!mBound)
         {
             mBound = true;
             HandleBannerAdEvents(true);
             HandleInterstitialAdEvents(true);
             HandleRewardAdEvents(true);
         }

     }

     private void OnDestroy()
     {
         Debug.Log("AdManager..OnDestroy");
         Debug.Log("AdManager..OnDestroy..mBound = "+ mBound + GetInstanceID());
         interstitial.Destroy();

         if (mBound)
         {
             mBound = false;
             HandleBannerAdEvents(false);
             HandleInterstitialAdEvents(false);
             HandleRewardAdEvents(false);
         }

     }

     #region BannerAd
     private void RequestBanner()
     {
         Debug.Log("AdManager..RequestBanner" + GetInstanceID());

 #if UNITY_EDITOR
         string adUnitId = "unused";
 #elif UNITY_ANDROID
             string adUnitId = "ca-app-pub-3940256099942544/6300978111";
 #elif UNITY_IPHONE
             string adUnitId = "ca-app-pub-3212738706492790/5381898163";
 #else
             string adUnitId = "unexpected_platform";
 #endif

         // Clean up banner ad before creating a new one.
         if (this.bannerView != null)
         {
             Debug.Log("AdManager..RequestBanner..if" + GetInstanceID());

             this.bannerView.Destroy();
         }

         AdSize adaptiveSize =
                 AdSize.GetCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(AdSize.FullWidth);

         this.bannerView = new BannerView(adUnitId, adaptiveSize, AdPosition.Bottom);



         /*AdRequest adRequest = new AdRequest.Builder()
             .AddTestDevice(AdRequest.TestDeviceSimulator)
             .AddTestDevice("0123456789ABCDEF0123456789ABCDEF")
             .Build();*/

         AdRequest adRequest = new AdRequest.Builder().Build();

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

     public void DisplayBanner()
     {
         Debug.Log("AdManager..DisplayBanner" + GetInstanceID());

         bannerView.Show();
     }

     public void HideBanner()
     {
         Debug.Log("AdManager..HideBanner" + GetInstanceID());

         bannerView.Hide();
     }

     void HandleBannerAdEvents(bool subscribe)
     {
         Debug.Log("AdManager..HandleBannerAdEvents" + GetInstanceID());
         Debug.Log("AdManager..HandleBannerAdEvents..subscribe = "+ subscribe + GetInstanceID());

         if (subscribe)
         {
             Debug.Log("AdManager..HandleBannerAdEvents..if" + GetInstanceID());

             // 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;
         }
         else
         {
             Debug.Log("AdManager..HandleBannerAdEvents..else" + GetInstanceID());

             // 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;
         }
     }
     #region Banner Callback Methods
     public void HandleAdLoaded(object sender, EventArgs args)
     {
         MonoBehaviour.print("HandleAdLoaded event received" + GetInstanceID());
         MonoBehaviour.print(String.Format("Ad Height: {0}, width: {1}",
             this.bannerView.GetHeightInPixels(),
             this.bannerView.GetWidthInPixels()));
         bannerAdStatus = 1;
     }

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

     }

     public void HandleAdOpened(object sender, EventArgs args)
     {
         MonoBehaviour.print("HandleAdOpened event received" + GetInstanceID());
         bannerAdStatus = 3;

     }

     public void HandleAdClosed(object sender, EventArgs args)
     {
         MonoBehaviour.print("HandleAdClosed event received" + GetInstanceID());
         bannerAdStatus = 4;

     }

     public void HandleAdLeftApplication(object sender, EventArgs args)
     {
         MonoBehaviour.print("HandleAdLeftApplication event received" + GetInstanceID());
         bannerAdStatus = 5;

     }
     #endregion

     #endregion

     #region InterstitialAd

     private void RequestInterstitial()
     {
         Debug.Log("AdManager..RequestInterstitial" + GetInstanceID());

 #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
         // Initialize an InterstitialAd.
         this.interstitial = new InterstitialAd(adUnitId);



         // Create an empty ad request.
         AdRequest request = new AdRequest.Builder().Build();
         // Load the interstitial with the request.
         this.interstitial.LoadAd(request);
         //testText.text = "RequestingInterstitial";

     }

     public void DisplayInterstitial()
     {
         Debug.Log("AdManager..DisplayInterstitial" + GetInstanceID());
         if (interstitial.IsLoaded())
         {
             Debug.Log("AdManager..DisplayInterstitial..IsLoaded" + GetInstanceID());

             interstitial.Show();
         }
         else
         {
             Debug.Log("AdManager..DisplayInterstitial..NotLoaded" + GetInstanceID());

             SceneManager.LoadScene(SceneIndexer.Gameplay);

         }
     }

     void HandleInterstitialAdEvents(bool subscribe)
     {
         Debug.Log("AdManager..HandleInterstitialAdEvents" + GetInstanceID());

         if (subscribe)
         {
             Debug.Log("AdManager..HandleInterstitialAdEvents..if" + GetInstanceID());

             // Called when an ad request has successfully loaded.
             this.interstitial.OnAdLoaded += HandleOnAdLoaded;
             // Called when an ad request failed to load.
             this.interstitial.OnAdFailedToLoad += HandleOnAdFailedToLoad;
             // Called when an ad is shown.
             this.interstitial.OnAdOpening += HandleOnAdOpened;
             // Called when the ad is closed.
             this.interstitial.OnAdClosed += HandleOnAdClosed;
             // Called when the ad click caused the user to leave the application.
             this.interstitial.OnAdLeavingApplication += HandleOnAdLeavingApplication;
         }
         else
         {
             Debug.Log("AdManager..HandleInterstitialAdEvents..else" + GetInstanceID());

             // Called when an ad request has successfully loaded.
             this.interstitial.OnAdLoaded -= HandleOnAdLoaded;
             // Called when an ad request failed to load.
             this.interstitial.OnAdFailedToLoad -= HandleOnAdFailedToLoad;
             // Called when an ad is shown.
             this.interstitial.OnAdOpening -= HandleOnAdOpened;
             // Called when the ad is closed.
             this.interstitial.OnAdClosed -= HandleOnAdClosed;
             // Called when the ad click caused the user to leave the application.
             this.interstitial.OnAdLeavingApplication -= HandleOnAdLeavingApplication;
         }
     }

     #region Interstitial Callback Methods
     public void HandleOnAdLoaded(object sender, EventArgs args)
     {
         MonoBehaviour.print("HandleAdLoaded event received");
         Debug.Log("HandleAdLoaded event received in debug" + GetInstanceID());
         interstitialAdStatus = 1;
     }

     public void HandleOnAdFailedToLoad(object sender, AdFailedToLoadEventArgs args)
     {
         MonoBehaviour.print("HandleFailedToReceiveAd event received with message: "
                             + args.Message);
         Debug.Log("HandleOnAdFailedToLoad event received in debug" + GetInstanceID());

         initTime = Time.time;
         interstitialAdStatus = 2;
     }

     public void HandleOnAdOpened(object sender, EventArgs args)
     {
         MonoBehaviour.print("HandleAdOpened event received");
         Debug.Log("HandleOnAdOpened event received in debug" + GetInstanceID());

         interstitialAdStatus = 3;
     }

     public void HandleOnAdClosed(object sender, EventArgs args)
     {
         MonoBehaviour.print("HandleAdClosed event received");
         Debug.Log("HandleOnAdClosed event received in debug" + GetInstanceID());

         //interstitial.Destroy();
         interstitialAdStatus = 4;
     }

     public void HandleOnAdLeavingApplication(object sender, EventArgs args)
     {
         MonoBehaviour.print("HandleAdLeavingApplication event received");
         Debug.Log("HandleOnAdLeavingApplication event received in debug" + GetInstanceID());

         interstitialAdStatus = 5;


     }
     #endregion

     #endregion

     #region RewardAd
     private void RequestRewardAd()
     {
         Debug.Log("AdManager..RequestRewardAd");

 #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

         this.rewardAd = new RewardedAd(adUnitId);


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

     public void DisplayRewardAd()
     {
         Debug.Log("AdManager..DisplayRewardAd");

         if (rewardAd.IsLoaded())
         {
             Debug.Log("AdManager..DisplayRewardAd..if");

             rewardAd.Show();
         }
     }

     void HandleRewardAdEvents(bool subscribe)
     {
         Debug.Log("AdManager..HandleRewardAdEvents");

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

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

         }
     }

     #region RewardAd Callback Methods
     public void HandleRewardedAdLoaded(object sender, EventArgs args)
     {
         MonoBehaviour.print("HandleRewardedAdLoaded event received");
         rewardAdStatus = 1;
     }

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

     }

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

     }

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

     }

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

         //RequestRewardAd();

     }

     public void HandleUserEarnedReward(object sender, Reward args)
     {
         string type = args.Type;
         double amount = args.Amount;
         MonoBehaviour.print(
             "HandleRewardedAdRewarded event received for "
                         + amount.ToString() + " " + type);
         rewardAdStatus = 6;

     }
     #endregion

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

为什么需要注销这些活动?

对于插页式广告,您可能不会注销这些事件。只需在需要时调用 loadad 方法即可。文档说您应该小心,不要在加载失败时滥用该函数调用...

...
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
        MobileAds.initialize(this,
            "ca-app-pub-3940256099942544~3347511713");
    mInterstitialAd = new InterstitialAd(this);
    mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712");
    mInterstitialAd.loadAd(new AdRequest.Builder().build());

    mInterstitialAd.setAdListener(new AdListener() {
        @Override
        public void onAdClosed() {
            // Load the next interstitial.
            mInterstitialAd.loadAd(new AdRequest.Builder().build());
        }

    });
}
...

对于奖励广告,您必须创建另一个 mrewardedad 对象,但对于插页式广告,您只需调用 loadAd ..

注意在您的 class 中将 mitrestital 对象声明为静态属性。 参考:https://developers.google.com/admob/android/interstitial