こんにちは、Unityエンジニアのオオバです。
Unityはコンポーネントを開発してゲームを作っていくゲームエンジンです。プログラム上でコンポーネントのやり取りがよく発生します。
その通りコンポーネントの取得には GetComponent
を使用します。
ところで 「GetComponentは重いから使わない方が良い」 と聞いたことがありませんか?とはいえコンポーネントを取得するために必要なGetComponentです。
そこで本記事ではGetComponentが本当に重いのか、コンポーネントはどうやって取得したら良いのか解説していきます。コンポーネントとの扱い、付き合い方に困っている方はぜひ読んでみてください。
コンポーネント自体はこちらの記事で詳しく解説しているので参考にどうぞ。
👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!
GetComponentって何?
「GetComponentってよく聞くけど何?」 という方に向けてGetComponentついて解説します。
GetComponentはGameObjectにせとされているコンポーネントを取得する関数です。
例えば以下のコードはGameObjectにセットされたRigidbodyコンポーネントを取得しています。
Rigidbody rb = gameObject.GetComponent<Rigidbody>();
このようにGetComponentはGameObjectにセットされたコンポーネントを取得できる関数ということでよく使われます。
GetComponentはGameObjectと同階層のコンポーネントしか取得できませんが、「GetComponentInChildren」「GetComponentInParent」を使用することで子階層、親階層のコンポーネントも取得できるようになります。
しかしコンポーネントを動的に取得できて便利な一方、CPU負荷もかかってしまうのです。そこで本記事ではGetComponentとの付き合い方についてCPU負荷の観点から考察していきます。
GetComponentは重いのか?
結論から言うと重いです。Transformコンポーネントを例に検証してみます。
- GetComponent<Transform>
- .transform
- 事前キャッシュ
上記の通りTransformコンポーネントは3種類の取得方法があります。それぞれどのくらいCPU負荷がかかっているか計測してみましょう。
取得方法 | 処理時間 |
---|---|
GetComponent | 約0.64ms |
.transform | 約0.54ms |
事前キャッシュ | 約0.09ms |
「GetComponent取得」と「.transformで取得」を比べると15.63%早く処理できています。
そして「GetComponent取得」と「事前キャッシュ」を比べると85.94%処理が早くなりました(最速)。
GetComponentが重いというより、もっと早くアクセスできる方法があるということを覚えておきましょう。
GetComponentを使わずにコンポーネントを取得する方法
コンポーネント取得は事前キャッシュが最速ということが分かりました。つまりGetComponentはあまり使わないほうが良いということです。
実際に開発現場でGetComponentは使用しません。では事前にコンポーネントをどうやって取得するのでしょうか?
コンポーネントを事前に取得(キャッシュ)する方法は2つあります。
SerializeFieldを使用
キャッシュしたいコンポーネントの変数に [SerializeField]
をセットするとシーン、またはPrefabにコンポーネントをキャッシュできるようになります。
具体的には次のようなコードです。
using UnityEngine;
public class CacheComponent : MonoBehaviour
{
[SerializeField] private BoxCollider _collider;
}
上記ソースコードをGameObjectにセットしてみてください。
するとInspectorウィンドウにコンポーネントのフィールドが追加されます。ドラッグアンドドロップでコンポーネントのキャッシュができるのです。

UnityのPrefab(プレハブ)とは?使い方まで徹底解説
Unity開発する上で基礎中の基礎「Prefab(プレハブ)」本記事を通してPrefabの正しい使い方を学ぶことができます。
public変数を使用
SerializeFieldと同様の機能をpublic変数にすることで実現できます。下記のコードはSerializeFieldののコードと機能的には全く同じです。
using UnityEngine;
public class CacheComponent : MonoBehaviour
{
public BoxCollider _collider;
}
しかしpublic変数をコンポーネントのキャッシュに使用するのはオススメしません。なぜならpublic変数自体がプログラムを弱くするコードだからです。
public変数はクラスの外からでも値を上書きできるため、思わぬところでトラブルが起きてしまう可能性があります。
SerializeFieldとpublic変数どちらも利用可能なケースなら SerializeField を選択しましょう。
GetComponentの使いどころ
最後にGetComponentの使い所について解説していきます。
結論 「動的にコンポーネントをつけ外しするケースで使用する」 です。
どうしても事前にコンポーネントをセットできないケースが発生します。ランタイム中に「AddComponent」してコンポーネントをセットし、GetComponentで取得する。こういうケースでのみGetComponentを使用しましょう。
事前にGameObjectにコンポーネントをセットできるケースであれば、前述したコンポーネントを事前キャッシュを使用する方がパフォーマンス観点からも良い状態を保てます。
実際オオバもUnityを12年使ってきていますが、GetComponentを実際のプロダクトのコードで使ったことは数えるくらいしかありません。それくらい事前キャッシュしています。
ということで GetComponentは使わざるを得ないときのみ使用 していきましょう。
GetComponentは重いのか?まとめ
本記事ではGetComponentとの付き合い方について解説してきました。
簡単にまとめます。
①コンポーネント取得の中でGetComponentは最も負荷が高い
②コンポーネントを取得の基本は事前キャッシュ
③GetComponentは使わざるを得ないときに使用
GetComponentはとても便利なのでついつい使ってしまいがちですが、それなりに負荷が掛かってしまうということを覚えておきましょう。事前キャッシュすることで85%高速に処理できました。
ゲームはシステムパフォーマンスによって体験が大きく変わってきます。パフォーマンスチューニングするタイミングで本記事のことも思い出してみてください(忘れないようにブックマーク!)
コンポーネントの取得は基本的に事前キャッシュしてできる限りGetComponentを使わないようにしておくと最低限のコストで済みます。
ぜひ参考にしてみてください。

筆者のXをフォローしよう
- Unity6000.0.32f1