我找到了一种在代码中解决这个问题的方法,但我想了解为什么会发生这种情况,因为我想学好C#。我搜索了很多,可以简化问题,这里是简化的代码:
/*MyCustomComponent.cs, this is attached to a game object in the scene*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MyCustomComponent : MonoBehaviour {
void Start () {
Test testInstance = new Test();
Debug.Log (testInstance);
Debug.Log (testInstance == null);
Debug.Log (testInstance.Equals(null)); //Also tried the same with Equals()
Debug.Log (testInstance.value);
}
}
/*Test.cs*/
using UnityEngine;
using System.Collections;
public class Test : Object {
public int value = 7;
public Test(){
}
}
控制台输出:
null
true
7
为什么会这样?如何将Object设为null但返回属性值?
因为Unity.Object
以非常特殊的方式工作,所以基本上它包含有关托管对象的数据,同时指向本机对象(粗略地说)。
让我们举个例子:你创建一个继承自MonoBehaviour
的新对象。现在您有两个对象,一个在本机端,另一个在托管端。由于instanceID
继承自MonoBehaviour
这一事实,您可以访问管理对象的Unity.Object
特权。基本上,后者用于显示Inspector中对象的所有相关数据。
现在,你想通过调用相同的命名方法来Destroy
这个游戏对象。本机对象实际上已被销毁,但托管对象不是,因为所有托管对象只能被垃圾收集器销毁。正是在这一点上,Unity.Object
变成了null
:这是Unity引擎使用的一个技巧,以避免你试图访问不再存在的本机对象。最终,当调用GC时,这个Unity.Object
也将被销毁。
这就是为什么你永远不应该创建一个直接从Unity.Object
继承的Unity对象,而只能从MonoBehaviour
或ScriptableObject
创建。