You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity Android真机上Admob插屏广告OnAdFullScreenContentClosed未触发

问题描述

我的Unity应用中,点击按钮会展示插屏广告,预期关闭广告后自动切换场景。这个功能在模拟器上运行正常,但在Android真机上,OnAdFullScreenContentClosed事件完全没被调用——广告能正常显示和关闭,但关闭后场景无法切换。以下是我的实现代码:

using UnityEngine;
// 注意:确保已导入SceneManagement命名空间
using UnityEngine.SceneManagement;
using GoogleMobileAds.Api;

public class Mymanager : MonoBehaviour
{
    bool isloaded = false;
    private InterstitialAd _interstitialAd;
    string sceneN = "Scene0";

#if UNITY_ANDROID
    private string _adUnitId = "ca-app-pub-XXXXXXXXXX";
#elif UNITY_IPHONE
    private string _adUnitId = "ca-app-pub-XXXXXXXXXX";
#else
    private string _adUnitId = "unused";
#endif

    void Start()
    {
        MobileAds.Initialize(initStatus => { });
        LoadInterstitialAd();
    }

    public void onClickButton()
    {
        if(isloaded){
            ShowInterstitialAd();
        } else {
            SceneManager.LoadScene(sceneN);
        }
    }

    public void LoadInterstitialAd()
    {
        if (_interstitialAd != null)
        {
            _interstitialAd.Destroy();
            _interstitialAd = null;
        }

        var adRequest = new AdRequest();

        InterstitialAd.Load(_adUnitId, adRequest,
            (InterstitialAd ad, LoadAdError error) =>
            {
                if (error != null || ad == null)
                {
                    Debug.LogError("interstitial ad failed to load an ad " +
                            "with error : " + error);
                    isloaded = false;
                    return;
                }
                else
                {
                    isloaded = true;
                }

                Debug.Log("Interstitial ad loaded with response : "
                    + ad.GetResponseInfo());

                _interstitialAd = ad;
            });

        RegisterEventHandlers(_interstitialAd);
    }

    public void ShowInterstitialAd()
    {
        if (_interstitialAd != null && _interstitialAd.CanShowAd())
        {
            _interstitialAd.Show();
        }
        else
        {
            Debug.LogError("Interstitial ad is not ready yet.");
            SceneManager.LoadScene(sceneN);
        }
    }

    private void RegisterEventHandlers(InterstitialAd interstitialAd)
    {

        interstitialAd.OnAdPaid += (AdValue adValue) =>
        {
            Debug.Log(String.Format("Interstitial ad paid {0} {1}.",
                adValue.Value,
                adValue.CurrencyCode));
        };

        interstitialAd.OnAdImpressionRecorded += () =>
        {
            Debug.Log("Interstitial ad recorded an impression.");
        };

        interstitialAd.OnAdClicked += () =>
        {
            Debug.Log("Ad: Clicked");
        };

        interstitialAd.OnAdFullScreenContentOpened += () =>
        {
            Debug.Log("Ad: Opend");
        };

        interstitialAd.OnAdFullScreenContentClosed += () =>
        {
            Debug.Log("Ad: Closed");
            SceneManager.LoadScene(sceneN);

        };

        interstitialAd.OnAdFullScreenContentFailed += (AdError error) =>
        {
            Debug.LogError("Ad: Failed" +
                        "with error : " + error);
            SceneManager.LoadScene(sceneN);
        };
    }
}
问题根源

你的代码核心问题是事件注册时机错误:RegisterEventHandlers(_interstitialAd)在InterstitialAd.Load异步调用后立即执行,但此时_interstitialAd还未被赋值(Load是异步操作,只有回调函数触发时才会初始化广告实例)。这导致你实际上没有给加载完成的插屏广告绑定任何事件处理器,所以真机上广告关闭后OnAdFullScreenContentClosed自然不会触发。

模拟器能正常运行属于偶然情况——模拟器的异步回调执行时机可能更快,刚好在RegisterEventHandlers调用前完成了_interstitialAd的赋值,但这种行为在真机上不可靠。

修复方案

1. 调整事件注册时机

把RegisterEventHandlers的调用移到InterstitialAd.Load的回调函数内部,确保只在广告加载成功、实例有效时才绑定事件:

public void LoadInterstitialAd()
{
    if (_interstitialAd != null)
    {
        _interstitialAd.Destroy();
        _interstitialAd = null;
    }

    var adRequest = new AdRequest();

    InterstitialAd.Load(_adUnitId, adRequest,
        (InterstitialAd ad, LoadAdError error) =>
        {
            if (error != null || ad == null)
            {
                Debug.LogError("插屏广告加载失败,错误信息:" + error);
                isloaded = false;
                return;
            }
            else
            {
                isloaded = true;
            }

            Debug.Log("插屏广告加载成功,响应信息:" + ad.GetResponseInfo());

            _interstitialAd = ad;
            // 移到此处,给有效广告实例注册事件
            RegisterEventHandlers(_interstitialAd);
        });

    // 移除原来此处的RegisterEventHandlers调用
}

2. 优化广告生命周期管理

在广告关闭或展示失败后,销毁广告实例并重置状态,避免重复使用失效实例:

interstitialAd.OnAdFullScreenContentClosed += () =>
{
    Debug.Log("广告已关闭");
    // 销毁广告实例
    interstitialAd.Destroy();
    _interstitialAd = null;
    isloaded = false;
    SceneManager.LoadScene(sceneN);
};

interstitialAd.OnAdFullScreenContentFailed += (AdError error) =>
{
    Debug.LogError("广告全屏展示失败,错误信息:" + error);
    // 销毁广告实例
    interstitialAd.Destroy();
    _interstitialAd = null;
    isloaded = false;
    SceneManager.LoadScene(sceneN);
};

3. 确认命名空间导入

确保代码顶部已导入场景管理命名空间,否则SceneManager会报错:

using UnityEngine.SceneManagement;
验证逻辑

修复后,广告加载成功后才会绑定事件处理器,真机上关闭广告时OnAdFullScreenContentClosed会正常触发,进而执行场景切换逻辑。

内容的提问来源于stack exchange,提问作者wonmoment

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 00:17:04