【你真的會Unity開發嗎?】第一期之UnityEngine.Object類與System.Object類差異所帶來的坑

Tobeslash發表於2020-10-18

第一期:UnityEngine.Object與System.Object

丟擲問題

我們先來看一行程式碼

// 嘗試獲取該元件如果獲取為空則新增該元件
MeshFilter meshFilter = this.gameObject.GetComponent<MeshFilter>() ?? this.gameObject.AddComponent<MeshFilter>();

你覺得這行程式碼能在Unity中執行正確獲得期望的結果嗎?如果你覺得這行程式碼有問題,並知道問題的Key點,那麼這篇文章你可以略過過程看一下結論是否與你的猜想一致,如果你覺得沒問題,那麼繼續看下去吧.

執行結果

該行程式碼最後通過Debug.Log()方法輸出的值為null,沒想到吧?不信的同學可以自己去嘗試一下,也可以加深自己的理解與印象。

產生原因

經過一段時間的摸索,博主發現在Unity中MeshFilter的基類是UnityEngine.Object類,而非System.Object類,而因為UnityEngine.Object類重寫了==與!=的行為,這就導致了以下的結果,請看下列程式碼示範

bool sign = GetComponent<MeshFilter>() == null; //UnityEngine.Object
Debug.Log(sign);// True

bool Csharp_sign = (object)GetComponent<MeshFilter>() == null; //System.Object
Debug.Log(Csharp_sign); //False

//So ?? not work correct.

感興趣的同學也可以在自己的編輯器裡測試一下。

結論

UnityEngine.Object類

由於Object類過載了型別隱式轉換運算子"==“與”!=",所以在使用該相關邏輯的地方需要尤為注意,否則很可能會產生非預期的結果。這個在與null比較時要特別注意,既使是有效的引用結果有可能在與null做等判斷時也是返回true的.

換句話講,也就是Unity中編寫相關指令碼時是不支援??空合併運算子與?.空條件運算子的,這會導致非預期的結果產生,更為詳細的介紹與說明可以參考Unity官網文件對UnityEngine.Object類的詳細說明.

那麼本期文章到此為止,如果你覺得對你有所幫助請給作者一個小小的贊吧~

相關文章