谜之UnityEngine.Object

 问题代码示例

public Transform Parent = null;
void Start ()
{
    //Transform Parent = null;
    Transform SelfTransform = GetComponent<Transform>();
    Transform a = Parent ?? SelfTransform;
    Transform b = Parent != null ? Parent : SelfTransform;
    Debug.Log(a == b); //返回False
}
//public Transform Parent = null;
void Start ()
{
    Transform Parent = null;
    Transform SelfTransform = GetComponent<Transform>();
    Transform a = Parent ?? SelfTransform;
    Transform b = Parent != null ? Parent : SelfTransform;
    Debug.Log(a == b); //返回True
}

初步解释

That specific operator only takes the usual ‘null’ into account, whereas Unity also offers a pseudo-null object to present more information to the programmers in the editor (that’s what happens in the second example, it’ll set such a mysterious object to that non-assigned, serialized field).

Usual comparisons like ==, != and some boolean comparisons will check whether the variable references ‘null’ or that pseudo-null.

public Transform Parent;
void Start()
{
    // overriden operator compares to null and fake-null, result is true
    Debug.Log(Parent == null);
    // casting to a System.Object reveals that there's actually something assigned to it, result is false
    Debug.Log((System.Object)Parent == null);
}

可以看到虽然在Inspector里Parent是none,但是其实它是指向了某个pseudo-null的实例对象,也就是说编辑器里看到的空并不是真正的null

结论:

Never check if a UnityEngine.Object is null directly, always use the bool operator
Never cast a UnityEngine.Object to a System.Object
Never write a generic method designed to take UnityEngine.Object and System.Object
Never use ?? on a UnityEngine.Object

引用:

http://qiankanglai.me/2016/10/21/fake-null/
https://blogs.unity3d.com/2014/05/16/custom-operator-should-we-keep-it/

posted @ 2020-08-07 18:18  何文西  阅读(327)  评论(0编辑  收藏  举报