Search code examples
unity-game-engineadmobadmob-rewardedvideoad

Unity + Admob rewarded ads : event not firing


I am stuck with admob rewarded ads, i can't figurate how to make event working. The problem is that my quiz game reload the scene every questions and even if i prevent the ad from destroy, the event are not firing at all. The ads are showing perfectly. I have tried multiple things but i must make a mistake somewhere... Anyone have an idea ?

Thank you very much!

using System;
using System.Collections;
using UnityEngine;
using GoogleMobileAds.Api;


public class RewardedScriptRow : MonoBehaviour
{
    private RewardBasedVideoAd rewardBasedVideo;
    public AudioClip GiftSound;

    // Use this for initialization
    void Start()
    {    
        RequestInterstitial();
        Debug.Log("Load at start");
    }

    public void LaunchAd() //Called from another script
    {
        StartCoroutine("Load");
    }

    private void RequestInterstitial()
    {

        string adUnitId = "";
#if UNITY_ANDROID
        adUnitId = "ca-app-pub-00000/00000000";
#elif UNITY_IOS
         adUnitId = "ca-app-pub-0000000000000";
#else
         adUnitId = "unexpected_platform";
#endif

        // Get singleton reward based video ad reference.
        this.rewardBasedVideo = RewardBasedVideoAd.Instance;

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

        rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoClosed;
        rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
    }


    IEnumerator Load()
    {
        while (!rewardBasedVideo.IsLoaded())
            yield return new WaitForEndOfFrame();

        yield return new WaitForSeconds(0.0f);
        rewardBasedVideo.Show();  
        yield break;
    }



    //EVENT
    public void HandleRewardBasedVideoRewarded(object sender, Reward args)
    {
        GetComponent<AudioSource>().PlayOneShot(GiftSound, 1.0F);
        RequestInterstitial();
    }

    public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
    {
        GetComponent<AudioSource>().PlayOneShot(GiftSound, 1.0F);
        RequestInterstitial();
    }
}

EDIT 1 :

using System;
using System.Collections;
using UnityEngine;
using GoogleMobileAds.Api;


public class RewardedScriptRow : MonoBehaviour
{
    private RewardBasedVideoAd rewardBasedVideo;
    public AudioClip GiftSound;
    public static RewardedScriptRow Instance;

    // Use this for initialization
    void Start()
    {
         Instance = this;
         DontDestroyOnLoad(this);
         RequestRewardBasedVideo();

        rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoClosed;
        rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;

     }

    //Called after 10 questions
    public void LaunchAd() 
    {
        StartCoroutine("Load");
    }

    private void RequestRewardBasedVideo()
    {

        string adUnitId = "";
#if UNITY_ANDROID
        adUnitId = "ca-app-pub-0000000/0000000000";
#elif UNITY_IOS
         adUnitId = "ca-app-pub-00000/00000000";
#else
         adUnitId = "unexpected_platform";
#endif

        // Get singleton reward based video ad reference.
        this.rewardBasedVideo = RewardBasedVideoAd.Instance;
        // Create an empty ad request.
        AdRequest request = new AdRequest.Builder().Build();
        // Load the interstitial with the request.
        this.rewardBasedVideo.LoadAd(request, adUnitId);

    }

    //EVENT
    public void HandleRewardBasedVideoRewarded(object sender, Reward args)
    {
        GetComponent<AudioSource>().PlayOneShot(GiftSound, 1.0F); 
        RequestRewardBasedVideo();

    }
    public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
    {
        GetComponent<AudioSource>().PlayOneShot(GiftSound, 1.0F);
        RequestRewardBasedVideo();
    }

    IEnumerator Load()
    {
        while (!rewardBasedVideo.IsLoaded())
            yield return new WaitForEndOfFrame();

        yield return new WaitForSeconds(0.0f);
        rewardBasedVideo.Show();
        yield break;
    }
}

And this how the game work with the scenes :

SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);

Solution

  • First of all: It seems very unwise/ illogical to call the RequestInterstial method in your event. Because by doing so, you are creating multiple subscriptions to the same events that you are already subscribed to! This can lead to very undesired/ unwanted behaviour as well as leading to Stackoverflow exceptions

    It is unclear to me why you would even call RequestInterstial when the event fires. It seems to me that you would want to load a new video after the first one has been shown. Refactor your method so that you do not add the subscription events.

    Move the subscription events and initialization code to your Start or Awake method.

    Also you are not requesting an interstial, but a rewardbasedvideo. I'd suggest renaming to keep the code logical.

    Public static RewardedScriptRow Instance;
    
    void Start()
    {    
        Instance = this;
        DontDestroyOnLoad(this);
        RequestRewardBasedVideo();
    
        // Get singleton reward based video ad reference.
        this.rewardBasedVideo = RewardBasedVideoAd.Instance;
    
        rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoClosed;
        rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
    }
    
    private void RequestRewardBasedVideo()
        {
            #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
    
            // Create an empty ad request.
            AdRequest request = new AdRequest.Builder().Build();
            // Load the rewarded video ad with the request.
            this.rewardBasedVideo.LoadAd(request, adUnitId);
        }
    
    public void HandleRewardBasedVideoRewarded(object sender, Reward args)
    {
        GetComponent<AudioSource>().PlayOneShot(GiftSound, 1.0F);
        RequestRewardBasedVideo();
    }
    

    Other than that, it should work. If you are still not getting the desirable result, try setting breakpoints while debugging and/ or use Debug.Log() inside the subscribed methods to see what's happening.

    Edit: Also, if it is happening because of reloading scenes, you could try adding DontDestroyOnLoad(this); to prevent the "AdObject" from getting destroyed. I'd suggest creating this script in your very first scene and removing it from all others (to prevent duplicates).

    You can then even apply the singleton pattern so you can easily access the script from within other classes.

    Example:

    StartCoroutine(RewardedScriptRow.Instance.LaunchAd());