Reward ad callback is not firing

2019-07-26 05:30发布

问题:

i have a game and when the player loses their lives, i want them to be able to watch a video for a second chance.

I am using unity version 2018.1.1f1 person and i have downloaded the admob unity plugin version 3.13.1

So if the player agrees to watch an ad, the ad will play and then resume the game without firing the callback that rewards the player. This is my code:

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

public class RewardAd : MonoBehaviour {
    private BannerView bannerView;
    private InterstitialAd interstitial;
    private RewardBasedVideoAd rewardBasedVideo;
    private float deltaTime = 0.0f;
    private static string outputMessage = string.Empty;

    public AudioSource musicPlayer;
    public Player player;

    public Text UIText;

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

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

        // RewardBasedVideoAd is a singleton, so handlers should only be registered once.
        this.rewardBasedVideo.OnAdLoaded += this.HandleRewardBasedVideoLoaded;
        this.rewardBasedVideo.OnAdFailedToLoad += this.HandleRewardBasedVideoFailedToLoad;
        this.rewardBasedVideo.OnAdOpening += this.HandleRewardBasedVideoOpened;
        this.rewardBasedVideo.OnAdStarted += this.HandleRewardBasedVideoStarted;
        this.rewardBasedVideo.OnAdRewarded += this.HandleRewardBasedVideoRewarded;
        this.rewardBasedVideo.OnAdClosed += this.HandleRewardBasedVideoClosed;
        this.rewardBasedVideo.OnAdLeavingApplication += this.HandleRewardBasedVideoLeftApplication;
    }

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

    // Returns an ad request with custom ad targeting.
    private AdRequest CreateAdRequest()
    {
        return new AdRequest.Builder()
            .AddTestDevice(AdRequest.TestDeviceSimulator)
            .AddTestDevice("0123456789ABCDEF0123456789ABCDEF")
            .AddKeyword("game")
            .SetGender(Gender.Male)
            .SetBirthday(new DateTime(1985, 1, 1))
            .TagForChildDirectedTreatment(false)
            .AddExtra("color_bg", "9B30FF")
            .Build();
    }

    private void RequestRewardBasedVideo()
    {
#if UNITY_EDITOR
        string adUnitId = "unused";
#elif UNITY_ANDROID
        string adUnitId = "ca-app-pub-3940256099942544/5224354917";
#elif UNITY_IPHONE
        string adUnitId = "ca-app-pub-7624023175090985/4535603801";
#else
        string adUnitId = "unexpected_platform";
#endif

        this.rewardBasedVideo.LoadAd(this.CreateAdRequest(), adUnitId);
    }

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

    private void ShowRewardBasedVideo()
    {
        if (this.rewardBasedVideo.IsLoaded())
        {
            this.rewardBasedVideo.Show();
        }
        else
        {
            MonoBehaviour.print("Reward based video ad is not ready yet");
        }
    }

    #region RewardBasedVideo callback handlers

    public void HandleRewardBasedVideoLoaded(object sender, EventArgs args)
    {
        this.rewardBasedVideo.Show();
        UIText.text = "Watch a short video\nfor an extra life ?";
    }

    public void HandleRewardBasedVideoFailedToLoad(object sender, AdFailedToLoadEventArgs args)
    {
        UIText.text = "Watch a short video\nfor an extra life ?";
    }

    public void HandleRewardBasedVideoOpened(object sender, EventArgs args)
    {
        musicPlayer.Pause();
        player.disableMovment = true;
    }

    public void HandleRewardBasedVideoStarted(object sender, EventArgs args)
    {
        musicPlayer.Pause();
        player.disableMovment = true;
    }

    public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
    {
        UIText.text = "Watch a short video\nfor an extra life ?";
    }

    public void HandleRewardBasedVideoRewarded(object sender, Reward args)
    {
        player.rewardAdUI.SetActive(false);
        UIText.text = "Watch a short video\nfor an extra life ?";
        player.disableMovment = false;

        if (PlayerPrefs.GetInt("music") == 1)
        {
            musicPlayer.Play();
        }

        Lives.addLives(1);
        player.RespawnPlayer();
    }

    public void HandleRewardBasedVideoLeftApplication(object sender, EventArgs args)
    {
        UIText.text = "Watch a short video\nfor an extra life ?";
    }

    public void secondChance()
    {
        UIText.text = "Loading video...\nplease wait.";
        this.RequestRewardBasedVideo();
    }

    public void GameOver()
    {
        player.disableMovment = false;

        if (PlayerPrefs.GetInt("music") == 1)
        {
            musicPlayer.Play();
        }

        player.gameOver();
    }

    #endregion
}

So the 2nd to last function called secondChance() is what runs to play the ad. On my android device, this plays the test rewarded video.

After the ad plays, the HandleRewardBasedVideoRewarded function should be called but it doesnt. Any help at all is appriciated

回答1:

I found a Silent Error after debugging in Android Studio, its due to threading issues in Unity.

Solution : Call your handling event in main thread (in Update Method)

bool isAdClosed = false;
bool isRewarded = false;
void Update()
{
    if (isAdClosed)
    {
        if (isRewarded)
        {
            // do all the actions
            // reward the player
            isRewarded = false;
        }
        else
        {
            // Ad closed but user skipped ads, so no reward 
           // Ad your action here 
        }
        isAdClosed = false;  // to make sure this action will happen only once.
    }
}

public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
{
    print("HandleRewardBasedVideoClosed event received");

    RequestRewardBasedVideo(); // to load Next Videoad
    isAdClosed = true;

}

public void HandleRewardBasedVideoRewarded(object sender, Reward args)
{
    string type = args.Type;
    double amount = args.Amount;
    print("HandleRewardBasedVideoRewarded event received for " + amount.ToString() + " " +
            type);
        isRewarded = true;
 }


标签: unity3d admob