在Unity中,在我的GameManager
脚本中,我有一个代表。在我的Door
脚本中,我订阅了这个代理。我已尝试在OnDisable
脚本中的OnDestroy
和Door
方法中取消订阅。在这两种情况下,当我在编辑器中停止运行游戏时出现错误:
关闭场景时,某些对象未被清除。 (你是否从OnDestroy产生了新的GameObjects?)
使用Debug.Log
,我发现这是因为GameManager
将始终在Door
脚本之前销毁。即使我在null
脚本的OnDisable
或OnDestroy
内进行了Door
检查,看看GameManager
是否为null
,得到同样的错误
if (GameManager.Instance)
{
GameManager.Instance.OnAllEnemiesKilled -= OpenDoor;
}
有人告诉我,我不需要取消订阅,因为当Door
对象被销毁时,委托将自动变为空,但事实并非如此。在运行期间,在Door
被销毁之后,GameManager
内部的更新循环仍在打印代表有一个订户:Door
。
答案 0 :(得分:1)
我怀疑你在被销毁之后致电GameManager.Instance
时会产生一个新的单身人士吗?如果是这样,请改为做这样的事情:
public class GameManager : MonoBehaviour
{
public static GameManager Instance
{
get
{
if (isDestroyed) return null;
// Your spawn logic...
}
}
static bool isDestroyed;
void OnDestroy()
{
isDestroyed = true;
}
}
答案 1 :(得分:0)
正如Lece指出的那样,当我调用GameManager.Instance时,我会产生一个新的单例。然而,我没有创建静态bool来解决问题,而是在我的Instance getter中用if (_instance == null)
替换了if ((object)_instance == null)
,它解决了问题。这是因为,虽然对象在本机代码中被销毁,但它仍然存在于托管代码中。所以我现在在托管世界中引用它。此外,Unity make是这样的,当一个对象在本机代码中被销毁时,它在托管代码中的值仍将返回null。