Can Poyrazoğlu
Can Poyrazoğlu

Reputation: 34780

Unity AdMob ads not displayed

I'm making a game on Unity 5.5 and I've followed Google's Official AdMob Getting Started Guide to integrate AdMob into my game (currently iOS-only, but Android will also follow when I get this working).

When I try to display the ad on iOS, ad.IsLoaded(); returns false even though it has just loaded (my OnAdLoaded event of the ad is firing). In Unity editor, I'm seeing the expected dummy methods being called at correct order (though nothing is being displayed, which I think is the expected behavior on Unity's own editor).

Here is my code for loading ads (of course, my publisher and ad unit IDs are redacted):

public class AdManager : MonoBehaviour {

    static RewardBasedVideoAd ad;
    static UIManager uiManager;

    #if UNITY_ANDROID
    static string adUnitId = "ca-app-pub-XXX/YYY";
    #elif UNITY_IPHONE
    static string adUnitId = "ca-app-pub-XXX/YYY";
    #else
    static string adUnitId = "unexpected_platform";
    #endif

    static int headstartPoints;


    // Use this for initialization
    void Start () {
        uiManager = GameObject.Find("Scripts").GetComponent<UIManager>();
        ad = RewardBasedVideoAd.Instance;
        ad.OnAdRewarded += Ad_OnAdRewarded;
        ad.OnAdClosed += Ad_OnAdClosed;
        ad.OnAdFailedToLoad += Ad_OnAdFailedToLoad;
        ad.OnAdLoaded += Ad_OnAdLoaded;
        headstartPoints = 0;
        RequestNewAd();
    }

    void Ad_OnAdFailedToLoad (object sender, AdFailedToLoadEventArgs e)
    {
        Debug.Log("Ad failed to load.");
    }

    void Ad_OnAdLoaded (object sender, System.EventArgs e)
    {
        Debug.Log("Ad loaded.");
    }

    void Ad_OnAdClosed (object sender, System.EventArgs e)
    {
        Debug.Log("Ad was closed, proceeding to game without rewards...");
    }

    void Ad_OnAdRewarded (object sender, Reward e)
    {
        Debug.Log("Ad rewarded.");
        headstartPoints = (int)e.Amount;
    }

    public static int GetAndConsumeRewards(){
        int points = headstartPoints;
        headstartPoints = 0;
        return points;
    }

    public static void RequestNewAd(){
        Debug.Log("Requested new ad.");
        AdRequest request = new AdRequest.Builder().Build();
        ad.LoadAd(request, adUnitId);
    }

    public static void DisplayAdOrProceed(){
        if(ad.IsLoaded()){
            ad.Show();
            Debug.Log("Ad was loaded, displaying ad...");
        }else{
            Debug.Log("Ad wasn't loaded, skipping ad...");
            uiManager.ProceedToGame();
        }
    }

    // Update is called once per frame
    void Update () {

    }
}

I've never seen OnAdFailedToLoad method being called, and I always see OnAdLoaded being called, so there doesn't seem to be a problem there. But when I check ad.IsLoaded() after ad is loaded, for some weird reason it's false. Please note that RewardBasedVideoAd is a singleton object as stated in Google's docs.

What am I doing wrong?

UPDATE: I am calling RequestNewAd() as soon as the app starts and also on each "level" start (think of it like one level is roughly ~30 seconds) and DisplayAdOrProceed() on death (e.g. end of the level). When DisplayAdOrProceed() is called, the ad's loaded method is always called (unless I have a connection problem but that's not the case here).

UPDATE 2: Just noticed that there is a really suspicious stack trace on "ad load" event:

Ad loaded.
UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:Log(Object)
AdManager:Ad_OnAdLoaded(Object, EventArgs)
System.EventHandler`1:Invoke(Object, TEventArgs)
GoogleMobileAds.Api.RewardBasedVideoAd:<RewardBasedVideoAd>m__8(Object, AdFailedToLoadEventArgs)
System.EventHandler`1:Invoke(Object, TEventArgs)
GoogleMobileAds.iOS.RewardBasedVideoAdClient:RewardBasedVideoAdDidFailToReceiveAdWithErrorCallback(IntPtr, String)

I can see that the ad load event is fired from a method named for a failure handler (RewardBasedVideoAdDidFailToReceiveAdWithErrorCallback, GoogleMobileAds.Api.RewardBasedVideoAd:<RewardBasedVideoAd>m__8(Object, AdFailedToLoadEventArgs)). However, it's calling the ad load event and not any failure handler. I have no idea what's going on or if it's a poorly-designed naming convention or not.

Upvotes: 2

Views: 1798

Answers (1)

Can Poyrazoğlu
Can Poyrazoğlu

Reputation: 34780

Okay after diving literally into the IL2CPP-generated C++ code in the Xcode project, I've realized that the SDK is calling the incorrect method. The ad is failing to load with error "No ad to show", but incorrectly firing up the ad load method. I'll make additional changes to my code to detect if it's being loaded correctly.

Terrible bug (or design decision), Google. I hope this gets fixed soon.

Upvotes: 4

Related Questions