Баннер Admob невидим, но по-прежнему доступен для кликов в Unity

Я работаю над приложением, которое отображает баннер в зависимости от сцены. Я использую Показать и Скрыть, чтобы управлять этим поведением.

Он отлично работает в первый раз, когда баннер показывается, но во второй раз (после того, как он был скрыт) баннер не появляется. Тем не менее, зона баннера по-прежнему активна и работает так, как ожидалось.

Я использую последний выпуск плагина AdMob для единства (v3.15.1) и не смог найти решения проблемы.

Это мой код:

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

public class AdsManager //Ads information: https://developers.google.com/admob/unity (see left menu fo detailed info of each ad type)
{
    public static AdsManager instance;
    public BannerView bannerAd;
    public InterstitialAd  interstitialAd;
    public RewardBasedVideoAd rewardedVideoAd;

    #if UNITY_EDITOR
    private static String appId = "unused";
    private static String bannerAdId = "unused";
    private static String interistitialAdId = "unused";
    private static String rewardedVideAdId = "TBD";
    #elif UNITY_ANDROID
    private static String appId = "ca-app-pub-6685658831663319~7807395346";
    private static String bannerAdId = "ca-app-pub-3940256099942544/6300978111"; //"ca-app-pub-6685658831663319/9607562172";
    private static String interistitialAdId = "ca-app-pub-3940256099942544/1033173712"; //"ca-app-pub-6685658831663319/4875778545";
    private static String rewardedVideAdId = "ca-app-pub-3940256099942544/5224354917"; //"ca-app-pub-6685658831663319/2971919290";
    #elif UNITY_IOS
    private static String appId = "ca-app-pub-6685658831663319~7807395346";
    private static String bannerAdId = "ca-app-pub-6685658831663319/9607562172";
    private static String interistitialAdId = "ca-app-pub-6685658831663319/4875778545";
    private static String rewardedVideAdId = "ca-app-pub-6685658831663319/2971919290";
    #else
    private static String appId = "unexpected_platform";
    private static String bannerAdId = "unexpected_platform";
    private static String interistitialAdId = "unexpected_platform";
    private static String rewardedVideAdId = "unexpected_platform";
    #endif


    public enum TypeOfAd
    {
        Banner,
        Interestitial, 
        RewardedVideo
    }

    public AdsManager()
    {
        Debug.Log("Initializing a new AdsManager.");
        if (instance == null)
        {
            instance = this;
            Setup();
            Debug.Log("AdsManager initialization successful.");
        }
        else
        {
            Debug.Log("AdsManager already exists. New initialization unsuccessful.");
        }
    }

    private void Setup()
    {
        // Initialize the Google Mobile Ads SDK.
        MobileAds.Initialize(appId);

        this.bannerAd = new BannerView(bannerAdId, AdSize.SmartBanner, AdPosition.Bottom); //Info to chang banner size: https://developers.google.com/admob/unity/banner#banner_sizes
        SetupBannerEventHandlers();

        this.interstitialAd = new InterstitialAd(interistitialAdId);
        SetupInterstitialEventHandlers();

        this.rewardedVideoAd = RewardBasedVideoAd.Instance;
        SetupRewardedVideoAdsEventHandlers();

        //Load firsts ads
        instance.LoadAd(TypeOfAd.Interestitial);
        instance.LoadAd(TypeOfAd.Banner);
    }

    private void SetupBannerEventHandlers()
    {
        this.bannerAd.OnAdLoaded += HandlerOnBannerAdLoaded;
        this.bannerAd.OnAdFailedToLoad += HandlrOnBannerAdFailedToLoad;
        this.bannerAd.OnAdOpening += HandlerOnBannerAdOpening;
        this.bannerAd.OnAdClosed += HandlerOnBannerAdClosed;
        this.bannerAd.OnAdLeavingApplication += HandlerOnBannerAdLeavingApplication;
    }

    private void SetupInterstitialEventHandlers()
    {
        this.interstitialAd.OnAdLoaded += HandlerOnInterstitialAdLoaded;
        this.interstitialAd.OnAdFailedToLoad += HandlerOnInterstitialAdFailedToLoad;
        this.interstitialAd.OnAdOpening += HandlerOnInterstitialAdOpening;
        this.interstitialAd.OnAdClosed += HandlerOnInterstitialAdClosed;
        this.interstitialAd.OnAdLeavingApplication += HandlerOnInterstitialAdLeavingApplication;
    }

    private void SetupRewardedVideoAdsEventHandlers()
    {
        this.rewardedVideoAd.OnAdLoaded += HandlerRewardVideoAdLoaded;
        this.rewardedVideoAd.OnAdFailedToLoad += HandlerRewardVideoAdFailedToLoad;
        this.rewardedVideoAd.OnAdOpening += HandlerRewardVideoAdOpening;
        this.rewardedVideoAd.OnAdStarted += HandlerRewardVideoAdStarted;
        this.rewardedVideoAd.OnAdRewarded += HandlerRewardVideoAdRewarded;
        this.rewardedVideoAd.OnAdClosed += HandlerRewardVideoAdClosed;
        this.rewardedVideoAd.OnAdLeavingApplication += HandlerRewardVideoAdLeftApplication;
    }

    public void LoadAd(TypeOfAd typeOfAd)
    {
        if (DataManager.instance.showAds)
            switch (typeOfAd)
            {
                case TypeOfAd.Banner:
                    Debug.Log("Loading Banner ad");
                    this.bannerAd.LoadAd(new AdRequest.Builder().Build());  //After loading it, it will be automatically displayed
                    break;

                case TypeOfAd.Interestitial:
                    Debug.Log("Loading Interestitial ad");
                    if (!this.interstitialAd.IsLoaded())
                        this.interstitialAd.LoadAd(new AdRequest.Builder().Build());

                    break;

                case TypeOfAd.RewardedVideo:
                    Debug.Log("Loading RewardedVideo ad");
                    if (!this.rewardedVideoAd.IsLoaded())
                        this.rewardedVideoAd.LoadAd(new AdRequest.Builder().Build(), rewardedVideAdId);
                    break;
            }
    }

    public bool ShowAd(TypeOfAd typeOfAd)
    {
        if (DataManager.instance.showAds)
            switch (typeOfAd)
            {
                case TypeOfAd.Banner:
                    Debug.Log("Showing Banner ad");
                    this.bannerAd.Show(); //No avaliable check to know if the ad has been loaded...
                    return true; //...so maybe the return is true but the ad is not being displayed because it was not loaded before.


                case TypeOfAd.Interestitial:
                    Debug.Log("Showing Interestitial ad");
                    if (this.interstitialAd.IsLoaded())
                    {
                        this.interstitialAd.Show();
                        return true;
                    }
                    else
                    {
                        Debug.LogWarning("Trying to show InterstitialAd but it is not loaded");
                        //TBD: Automaitcally load?
                    }
                    break;


                case TypeOfAd.RewardedVideo:
                    Debug.Log("Showing RewardedVideo ad");
                    if (this.rewardedVideoAd.IsLoaded())
                    {
                        this.rewardedVideoAd.Show();
                        return true;
                    } else {
                        Debug.LogWarning("Trying to show RewardedBasedVideoAd but it is not loaded");
                        //TBD: Automaitcally load?
                    }
                    break;
            }

        return false;
    }

    public void QuitAd(TypeOfAd typeOfAd)
    {
        switch (typeOfAd)
        {
            case TypeOfAd.Banner:
                Debug.Log("Quiting Banner ad");
                bannerAd.Hide();
                break;


            case TypeOfAd.Interestitial:
                Debug.Log("Quiting Interestitial ad");
                Debug.LogError("QuitAd Interestitial Not Implemented");
                break;


            case TypeOfAd.RewardedVideo:
                Debug.Log("Quiting RewardedVideo ad");
                Debug.LogError("QuitAd RewardedVideo Not Implemented");
                break;
        }
    }

    //BANNER EVENT HANDLERS
    public void HandlerOnBannerAdLoaded(object sender, EventArgs args) { } // Called when an ad request has successfully loaded.
    public void HandlrOnBannerAdFailedToLoad(object sender, AdFailedToLoadEventArgs args) { Debug.LogWarning("Banner failed to load: " + args.Message); LoadAd(TypeOfAd.Banner); } // Called when an ad request failed to load.
    public void HandlerOnBannerAdOpening(object sender, EventArgs args) { } // Called when an ad is clicked.
    public void HandlerOnBannerAdClosed(object sender, EventArgs args) { } // Called when the user returned from the app after an ad click.
    public void HandlerOnBannerAdLeavingApplication(object sender, EventArgs args) { } // Called when the ad click caused the user to leave the application.

    //INTERSTITIAL EVENT HANDLERS
    public void HandlerOnInterstitialAdLoaded(object sender, EventArgs args) { } // Called when an ad request has successfully loaded.
    public void HandlerOnInterstitialAdFailedToLoad(object sender, AdFailedToLoadEventArgs args) { Debug.LogWarning("Interstitial failed to load: " + args.Message); LoadAd(TypeOfAd.Interestitial); } // Called when an ad request failed to load.
    public void HandlerOnInterstitialAdOpening(object sender, EventArgs args) { } // Called when an ad is shown.
    public void HandlerOnInterstitialAdClosed(object sender, EventArgs args) { } // Called when the ad is closed.
    public void HandlerOnInterstitialAdLeavingApplication(object sender, EventArgs args) { } // Called when the ad click caused the user to leave the application.

    //REWARDED VIDEO AD EVENT HANDLERS
    public void HandlerRewardVideoAdLoaded(object sender, EventArgs args) { } // Called when an ad request has successfully loaded.
    public void HandlerRewardVideoAdFailedToLoad(object sender, AdFailedToLoadEventArgs args) { Debug.LogWarning("RewardedVideo failed to load: " + args.Message); LoadAd(TypeOfAd.RewardedVideo); } // Called when an ad request failed to load.
    public void HandlerRewardVideoAdOpening(object sender, EventArgs args) { } // Called when an ad is shown.
    public void HandlerRewardVideoAdStarted(object sender, EventArgs args) { } // Called when the ad starts to play.
    public void HandlerRewardVideoAdRewarded(object sender, Reward args) { Debug.Log("Rewarded video ad completed. Reward info: " + args.Amount + " of " + args.Type); } // Called when the user should be rewarded for watching a video.
    public void HandlerRewardVideoAdClosed(object sender, EventArgs args) { } // Called when the ad is closed.
    public void HandlerRewardVideoAdLeftApplication(object sender, EventArgs args) { } // Called when the ad click caused the user to leave the application.

}

Чтобы показать рекламу, я просто вызываю метод ShowAd, а чтобы скрыть ее, я вызываю метод QuitAd. Я думаю, что оба работают так, как ожидалось, потому что они работают при первом вызове, а также потому, что в сценах, где HideAd называется «областью баннера», нельзя щелкнуть, но когда вызывается метод ShowAd, вы можете щелкнуть невидимый баннер.

Спасибо за любую помощь!


person Guillem Poy    schedule 12.03.2019    source источник


Ответы (1)


Я решил проблему, уничтожив баннер в методе QuitAd:

public void QuitAd(TypeOfAd typeOfAd)
{
    switch (typeOfAd)
    {
        case TypeOfAd.Banner:
            Debug.Log("Quiting Banner ad");
            bannerAd.Destroy();
            break;


        case TypeOfAd.Interestitial:
            Debug.Log("Quiting Interestitial ad");
            Debug.LogError("QuitAd Interestitial Not Implemented");
            break;


        case TypeOfAd.RewardedVideo:
            Debug.Log("Quiting RewardedVideo ad");
            Debug.LogError("QuitAd RewardedVideo Not Implemented");
            break;
    }
}

Затем я изменил метод ShowAd, загружающий баннер перед его показом:

public bool ShowAd(TypeOfAd typeOfAd)
{
    if (DataManager.instance.showAds)
        switch (typeOfAd)
        {
            case TypeOfAd.Banner:
                Debug.Log("Showing Banner ad");
                LoadAd(TypeOfAd.Banner); //Every time the banner is asked to be shown it will try to load before being shown.
                this.bannerAd.Show(); //Will be show after loading
                return true;


            case TypeOfAd.Interestitial:
                Debug.Log("Showing Interestitial ad");
                if (this.interstitialAd.IsLoaded())
                {
                    this.interstitialAd.Show();
                    return true;
                }
                else
                {
                    Debug.LogWarning("Trying to show InterstitialAd but it is not loaded");
                    //TBD: Automaitcally load?
                }
                break;


            case TypeOfAd.RewardedVideo:
                Debug.Log("Showing RewardedVideo ad");
                if (this.rewardedVideoAd.IsLoaded())
                {
                    this.rewardedVideoAd.Show();
                    return true;
                } else {
                    Debug.LogWarning("Trying to show RewardedBasedVideoAd but it is not loaded");
                    //TBD: Automaitcally load?
                }
                break;
        }

    return false;
}

Однако я не знаю, является ли это правильным решением, потому что новый запрос на загрузку будет выполняться каждый раз, когда необходимо показать баннер (после сцены, где он не отображается).

Кроме того, это «решение» представляет собой всего лишь другой подход к той же цели, а не исправление исходного подхода.

Поэтому, если кто-нибудь знает, почему исходный код не работает, я был бы очень признателен за то, что поделился этим знанием.

person Guillem Poy    schedule 13.03.2019