GameObject.Find()とアウトレット接続(インスペクター での変数の参照)の違い

2023年9月14日

Unityでオブジェクトの参照を取得する場合、2つの方法があります。の違いについて考えてみましょう。

オブジェクトの参照をUpdateメソッドで取得すると不可になるためよくありません

例えば、オブジェクトの取得をUpdate()メソッドで使用すると、その都度シーン内から探す処理が実行されるため、パフォーマンスが落ちます(CPUに負荷がかかります)そのため、Start()メソッドで変数に代入しておき、必要に応じてその値を使うようにします。

❌ダメな例

GameObject enemy;

void Update()
{
    enemy = GameObject.Find("Enemy");
}

2つのパターンの違い

オブジェクトはUpdateメソッドで何回も取得しても値が変わらないため、負荷がかかるため無意味です

GameObject.Find()

タイミング

プログラム実行時(正確にはメソッドの呼び出し時)に参照を取得します。

特徴

Hierachyまたは、Scene内のオブジェクトの名前を変更するとそのそのオブジェクトが取得できませんので、参照が外れエラーになります

次のコードを例に考えます。

GameObject enemy;

void Start()
{
    enemy = GameObject.Find("Enemy");
}

ゲームオブジェクトの名前がEnemyの場合は問題なく取得できますが、コード作成を進めていく途中で、名前を「Slime」に変更するとEnemyという名前のオブジェクトが存在しないため、Nullエラーになります。

インスペクター での変数の参照(アウトレット接続)

[SerializeField]
GameObject enemy;

タイミング

プログラム設計時に参照先を設定します
オブジェクトが読み込まれる時にメモリが取得されます(メソッドの実行を待ちません)

特徴

Hierachyまたは、Scene内のオブジェクトの名前を変更してもその参照は維持されます。

インスペクター での変数の参照(アウトレット接続)で参照の設定漏れを探してくれるツール

インスペクター にドラッグアンドドロップ(アウトレット接続)を忘れると、Nullエラーになりますが、複数のオブジェクトがあり、複数のスクリプトがアタッチされていると、どこが外れているのか?判断が面倒になります。

次に紹介するツールは、実行前に参照が外れていないかをチェックするツールになります。

使い方

準備

  • GitHubからzipのダウンロードを選択します。
  • 圧縮ファイルを展開します。
  • Unityプロジェクトを立ち上げておきます
  • NotNullAttribute.unitypackageファイルをダブルクリックしてUnityにインポートします。
  • 次のようにコードを変更します。

元のコード

[SerializeField]
GameObject enemy;

または、

Public GameObject enemy;

変更後のコード

チェックしたいメンバーにNotNullアトリビュートを追加します

[SerializeField]
[NotNull]
GameObject enemy;

または、

[SerializeField, NotNull]
GameObject enemy;

確認の方法

  • メニューバーのRedBlueToolsメニューからNot Null Finderを選択します
  • 参照忘れがあると、コンソールウィンドウにエラーが表示されます(参照忘れの場所も表示されます)

参考

Unity,小技

Posted by hidepon