大量のObjectでGetComponentする際のコストを減らす【Unity】【Arbor】

はじめに

UnityにおけるGetComponentの処理が重いことは周知の事実です。
そのため、繰り返しGetComponentする場合、結果をフィールドにキャッシュして使い回すことが多いかと思います。

もちろんこれでも悪くないのですが、この参照を大量のPrefabが使いたい場合はどうすればいいでしょう。

こういう場合ですね。Bullet.csをBulletオブジェクトにアタッチし、100発の弾をオブジェクトプールで生成したとします。

すると、Startが100回呼ばれ、Playerコンポーネントも100回参照されます。
これは、処理速度的にあまりに無駄が多すぎます。

今回は、この問題を「Arbor」というアセットを使って解決していきます。

Arborでコンポーネントの参照を保持

Arborとは

Arborとは、ケットシーウェアさんが配布している、シンプルかつ強力なグラフエディタです。詳細は公式サイトに譲ります。

Arbor 公式サイト

有料ですが試用版もあるので、とりあえず記事に沿って組みたい方はそちらを導入するのもいいと思います。

※記事の段階ではArbor3を使用しています。

ParameterContainer で参照を保持

ParameterContainerという機能を用います。
GameObjectにアタッチすることで、様々な型のパラメーターに外部からアクセスできるようになります。
シングルトンで疑似グローバル変数を管理したことがある方なら感覚が掴みやすいかと思います。


ParameterContainerの作成

大まかな特徴が分かったところで、さっそくParameterContainerを作っていきましょう。

  1. Hierarchy上で右クリック
  2. Arbor → ParameterContainerを選択
  3. 生成されたオブジェクトのInspectorを表示
  1. ParameterContainerの+アイコンをクリック
  2. Componentを選択

1つのコンポーネントにつき、3つの設定項目があります。
上から順に説明します。

Component識別用の名前です。Scriptから参照する際に使います。
プルダウンメニューValueでアタッチするコンポーネントの型を制限します。設定しなくても問題はありません。
Valueコンポーネントの参照です。外部からアクセスしたいコンポーネントを手動でアタッチします。

例として、PlayerオブジェクトのRigidbodyを設定したい場合、以下のようになります。

外部からParameterContainerにアクセスする

作成はそれほど手間がかかりませんが、外部のScriptから参照する際はそれなりに手間がかかります。

まず、 ComponentParameterReference 型のフィールドを作成します。
これは、ParameterContainerの参照を保持する変数です。

フィールドを作成すると、Inspector上で以下のように表示されるので、ContainerとParameterを手動でアタッチしてください。

Parameterに関しては、 [ClassExtends (typeof (任意の型))] で任意の型に制限できます(今回の例ではRigidbody)。

ParameterContainerへの参照が設定できたら、Script上で、

ParameterContainerの参照.parameter.objectReferenceValue as コンポーネントの型

でコンポーネントまでたどり着けます。

コーディングを短縮する

ここまで読んだ方は、「毎回こんな入力するのは面倒くさい」と思ったことでしょう。僕は思いました。

プログラマーなら、何度も同じ入力をする状況に出くわしたら、マクロ化する癖をつけましょう。VS Codeのスニペット機能を使います。

  1. VS Codeで「ファイル → 基本設定 → ユーザースニペット」を選択
  2. 入力欄にcsharpと打ち込み、csharp.jsonを選択
  3. 上記のコードスニペットをコピペして保存

使う際は、フィールド変数を記述する場所で「getc」と入力し、変換候補が出てきたらEnterを押してください。

typeコンポーネントの型
propertyNameコンポーネントにアクセスする変数名
refNameParameterContainerの参照を格納する変数名

各項目はtabを押すことで切り替えられます。

逆に、ParameterContainerにコンポーネントをセットしたい場合は、

ParameterContainerの参照変数.parameter.value = GetComponent<型>();

でOKです。

こんな具合に、Bulletが影響を与えるRigidbodyを指定したい場合などに便利です。AIの難易度ごとにコンポーネントを分けておけば、Strategyパターンとしても使えます。

スポンサードサーチ

まとめ

以上、駆け足になりましたがまとめてみました。

Arborの公式サイトに非常に分かりやすいドキュメントがあるので、ParameterContainer詳しい手順や仕様はそちらをお読みください。

ParameterContainer – Arborドキュメント

記事をシェアする