Unity 2019.2 から追加されたTryGetComponentを知る
xRLT#3のこちらの発表でTryGetComponentの存在を知ったので,調べてみました.
色々調べてみたら面白かった.
TryGetComponentとは
GetComponentとの違いを見比べるとわかりやすい. Rigidbodyコンポを取得して,nullチェックし,もしあればオブジェクトを赤くするスクリプトで比較.
GetComponent
void Update() { var rigidbody = GetComponent<Rigidbody>(); if (rigidbody != null) { this.GetComponent<Renderer>().material.color = Color.red; } }
TryGetComponent
void Update() { if (TryGetComponent<Rigidbody>(out var rigidbody)) { this.GetComponent<Renderer>().material.color = Color.red; } }
一行スッキリしたし,nullチェックが必要なくなった.
Unityのドキュメント読もう. Unity - Scripting API: GameObject.TryGetComponent
out variablesとは
C#7.0で導入. 事前に変数宣言せずに,メソッド呼び出しの中で変数を宣言できる.
TryGetComponentとout、out var のお話 - Qiita
C#7.0,8.0の知識整理したい.
GC Alloc
引き続き最初のサンプルコードで説明します.
【Unity】GetComponent と TryGetComponent の違い - コガネブログ
こちらの記事を読むと面白いのですが, GetComponentの場合,RigidbodyがないとUnity Editor上ではGC Allocが発生しますが TryGetComponetの場合,GC Allocが発生しません.
GetComponentの場合
TryGetComponentの場合
cf. GC Allocについてとか
.NETにおけるマネージヒープとガベージコレクション - Qiita
偽null?真null?
Unity Tip: Use TryGetComponent instead of GetComponent to avoid memory allocation in the Editor
こちらの記事を読むと
It should be noted that this memory allocation will only occur in the Editor. But why is this memory allocation happening? This is because when a MonoBehaviour has fields, Unity dose not set those fields to “real null”, but to a “fake null” object. If the requested component does not exist, Unity will generate a custom warning string inside the newly allocated fake null object.
せっかくなので最近話題のDeepLでぶちこみましょうか.
注意しなければならないのは、このメモリ割り当てはEditorでしか発生しないということです。しかし、なぜこのメモリ割り当てが発生するのでしょうか?それは、MonoBehaviourにフィールドがある場合、Unityはフィールドを「real null」ではなく、「fake null」オブジェクトに設定するからです。要求されたコンポーネントが存在しない場合、Unityは新たに割り当てられたFake nullオブジェクトの中にカスタムの警告文字列を生成します。
??????
nullがnullじゃない???
Unityのnullはnullじゃないかもしれない - Qiita
上の記事によると「Unityのnullはnullじゃないかもしれない」らしい.Unity難しすぎる.
参考:Custom == operator, should we keep it? - Unity Technologies Blog