为什么我的非静态游戏对象在场景重新加载后会在脚本中丢失其引用?
Why does my non-static GameObject lose its reference in a script after scene reloaded?
我的 Canvas 上有一个空游戏对象,用于显示广告菜单,我已通过检查器将其附加到 public 变量中的单独脚本(不在菜单本身上) .
我正在使用 adMenu.SetActive(false)
在脚本中将其设置为非活动状态,这在我的游戏的第一次通关时有效。但是,当我通过场景中的按钮重新启动场景时,菜单在检查器中丢失了对同一游戏对象的引用,并且我收到此错误:
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
在场景重新加载后以类似方式初始化的其他 GameObject 从未发生过这种情况。
其他详细信息:
GameObject.Find()
可以在同一脚本中使用其名称检索游戏对象
DontDestroyOnLoad()
未在脚本或其附加的游戏对象上的任何位置使用
代码:
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();
}
}
在你的restart方法上,你应该re-activate带adMenu.SetActive(true)
的按钮,如果没有,当你再次调用场景时,adMenu
GameObject
被禁用,所以您无法访问 GameObject
.
也许您可以在 AdManager 中添加一个方法,例如:
public void OpenAdMenu()
{
adMenu.SetActive(true);
}
并在 AdManager.Start()
上调用它
发生的事情与您的菜单对象或 static
实例无关。
问题是
的回调
public void OnUnityAdsDidFinish(string placementId, ShowResult showResult)
因为您通过
注册了实例
Advertisement.AddListener(this);
但是this
实例在场景改变后会变成毁灭者
如the examples所示你应该做
private void OnDestroy()
{
Advertisement.RemoveListener(this);
}
我的 Canvas 上有一个空游戏对象,用于显示广告菜单,我已通过检查器将其附加到 public 变量中的单独脚本(不在菜单本身上) .
我正在使用 adMenu.SetActive(false)
在脚本中将其设置为非活动状态,这在我的游戏的第一次通关时有效。但是,当我通过场景中的按钮重新启动场景时,菜单在检查器中丢失了对同一游戏对象的引用,并且我收到此错误:
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
在场景重新加载后以类似方式初始化的其他 GameObject 从未发生过这种情况。
其他详细信息:
GameObject.Find()
可以在同一脚本中使用其名称检索游戏对象DontDestroyOnLoad()
未在脚本或其附加的游戏对象上的任何位置使用
代码:
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();
}
}
在你的restart方法上,你应该re-activate带adMenu.SetActive(true)
的按钮,如果没有,当你再次调用场景时,adMenu
GameObject
被禁用,所以您无法访问 GameObject
.
也许您可以在 AdManager 中添加一个方法,例如:
public void OpenAdMenu()
{
adMenu.SetActive(true);
}
并在 AdManager.Start()
发生的事情与您的菜单对象或 static
实例无关。
问题是
的回调public void OnUnityAdsDidFinish(string placementId, ShowResult showResult)
因为您通过
注册了实例Advertisement.AddListener(this);
但是this
实例在场景改变后会变成毁灭者
如the examples所示你应该做
private void OnDestroy()
{
Advertisement.RemoveListener(this);
}