Unity场景重载后激励广告无法加载、按钮失效问题求助
Unity激励广告场景重载后失效的解决办法
核心问题分析
场景重载时,Unity Ads SDK重复初始化、事件监听未正确解绑/重绑、广告状态未同步,导致按钮失效、脚本无法正常工作。
具体解决步骤
使用单例模式确保SDK只初始化一次
Unity Ads不支持重复初始化,场景切换时若初始化脚本被重复创建会引发异常。将广告管理脚本设为全局单例,保留在所有场景中:public class AdsManager : MonoBehaviour { public static AdsManager Instance; private bool _isSdkInitialized; [SerializeField] private string _gameId; void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); } void Start() { if (!_isSdkInitialized) { Advertisement.Initialize(_gameId); _isSdkInitialized = true; // 注册广告加载状态监听 Advertisement.RewardedAdLoaded += OnRewardedAdLoaded; Advertisement.RewardedAdFailedToLoad += OnRewardedAdLoadFailed; } } void OnDestroy() { // 销毁时移除监听,避免内存泄漏 Advertisement.RewardedAdLoaded -= OnRewardedAdLoaded; Advertisement.RewardedAdFailedToLoad -= OnRewardedAdLoadFailed; } private void OnRewardedAdLoaded() { // 全局通知广告就绪,更新按钮状态 var adButton = GameObject.FindObjectOfType<Button>(); if (adButton != null) adButton.interactable = true; } private void OnRewardedAdLoadFailed(LoadError error, string message) { // 处理加载失败逻辑 Debug.Log($"广告加载失败: {error} - {message}"); } public void ShowRewardedAd() { if (Advertisement.IsReady("rewardedVideo")) { var options = new ShowOptions { resultCallback = HandleShowResult }; Advertisement.Show("rewardedVideo", options); } } private void HandleShowResult(ShowResult result) { switch (result) { case ShowResult.Finished: // 给用户发放奖励 break; case ShowResult.Skipped: // 用户跳过广告 break; case ShowResult.Failed: Debug.Log("广告播放失败"); break; } // 播放后重置按钮状态,等待下一次加载 var adButton = GameObject.FindObjectOfType<Button>(); if (adButton != null) adButton.interactable = false; } }场景重载后重绑按钮事件与状态
场景切换后,UI元素会重建,需在场景加载完成后重新绑定点击事件并同步广告状态:public class AdButtonHandler : MonoBehaviour { private Button _adButton; void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; } void Start() { _adButton = GetComponent<Button>(); _adButton.onClick.AddListener(() => AdsManager.Instance.ShowRewardedAd()); // 初始状态设为不可点击,直到广告加载完成 _adButton.interactable = Advertisement.IsReady("rewardedVideo"); } void OnSceneLoaded(Scene scene, LoadSceneMode mode) { // 重新获取按钮组件并绑定事件 _adButton = GetComponent<Button>(); _adButton.onClick.RemoveAllListeners(); _adButton.onClick.AddListener(() => AdsManager.Instance.ShowRewardedAd()); // 同步当前广告就绪状态 _adButton.interactable = Advertisement.IsReady("rewardedVideo"); } }避免重复注册事件监听
所有广告相关的事件监听必须在OnDisable或OnDestroy中移除,防止场景重载后重复注册导致逻辑冲突或内存泄漏。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

