为什么在场景重新加载后,我的非静态GameObject在脚本中失去了引用



我的画布上有一个空的GameObject,用于显示广告菜单,我通过检查器将其附加到公共变量中的一个单独脚本(而不是菜单本身(。

我在脚本中使用adMenu.SetActive(false)将其设置为非活动状态,这适用于我的游戏的第一次播放。然而,当我通过场景中的按钮重新启动场景时,菜单在检查器中失去了对同一GameObject的引用,我收到了这个错误:

MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.

在场景重新加载后,其他以类似方式初始化的GameObjects从未发生过这种情况。

其他详细信息:

  • GameObject.Find()可以使用同一脚本中的名称检索游戏对象
  • DontDestroyOnLoad()未在脚本或其所附的GameObject上的任何位置使用

代码:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Advertisements;
using MEC;
public class AdManager : MonoBehaviour, IUnityAdsListener
{
internal static AdManager instance;
private static bool isInitialized = false;
public GameObject adMenu;
private string placement = "rewardedVideo";
void Start()
{
instance = this;
if (!isInitialized)
{
isInitialized = true;
Advertisement.AddListener(this);
Advertisement.Initialize(Constants.appleGameId, true);
}
}
IEnumerator<float> ShowAd()
{
if (!Advertisement.IsReady())
{
yield return Timing.WaitForOneFrame;
}
Advertisement.Show(placement);
}
public void CloseAdMenu()
{
Debug.Log("Is adMenu null: " + (adMenu == null));  // Returns false on first playthrough only
adMenu.SetActive(false);
}

public void OnUnityAdsDidFinish(string placementId, ShowResult showResult)
{
if (showResult == ShowResult.Finished)
{
CloseAdMenu();
}
}
public void OnUnityAdsReady(string placementId)
{
// throw new System.NotImplementedException();
}
public void OnUnityAdsDidError(string message)
{
// throw new System.NotImplementedException();
}
public void OnUnityAdsDidStart(string placementId)
{
// throw new System.NotImplementedException();
}
}

发生的事情与菜单对象或static实例无关。

问题是的回调

public void OnUnityAdsDidFinish(string placementId, ShowResult showResult)

因为您通过注册了实例

Advertisement.AddListener(this);

但是CCD_ 5实例在场景改变之后将是Destroyer。

如示例所示,您应该执行

private void OnDestroy() 
{
Advertisement.RemoveListener(this);
}

在重新启动方法中,您应该使用adMenu.SetActive(true)重新激活按钮,否则,当您再次调用场景时,adMenuGameObject被禁用,因此您无法访问GameObject

也许你可以在你的AdManager中添加一个方法,比如:

public void OpenAdMenu()
{
adMenu.SetActive(true);
}

并在AdManager.Start()上调用

最新更新