简体   繁体   中英

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

  • I've set up my game at the AdMob console and created a reward-based video ad.
  • I've added the GoogleMobileAds.framework into my built project in Xcode.
  • I've made sure I'm linking against the newly-added framework too.
  • Downloaded the Unity package and integrated it into my project as required.
  • I've hooked up to event handlers: My ad gets loaded with no problem, no failure.

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 (eg 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM