mohumohu studio みずきの技術&読書ブログ&無料ゲーム

mohumohu studio

           

みずきの技術&読書ブログ&無料ゲーム

プロフィール画像

Unity C#|GetComponentがnullになる理由と対処法【初心者向け完全解説】

UnityでC#を書いていると、ほぼ確実に一度は遭遇するのが
「GetComponent が null になる問題」です。


var rb = GetComponent<Rigidbody>();
rb.AddForce(Vector3.up);

一見すると正しそうなコードなのに、
実行すると NullReferenceException が発生してしまう。
「ちゃんとGetComponentしているのに、なぜ?」
と混乱した経験がある方も多いのではないでしょうか。

実は、GetComponentがnullを返すのは
珍しいことでも、特別なバグでもありません。
Unityの仕組みを正しく理解していれば、
「なるほど、そういうことか」と納得できるケースがほとんどです。

この記事では、Unity初心者の方に向けて、

  • GetComponentがnullになる仕組み
  • よくある原因と具体例
  • nullを防ぐための安全な書き方
  • 設計レベルでの対処法

を、実際のコード例を交えながら分かりやすく解説します。

前回の記事
「NullReferenceExceptionとは何か?」
の内容を踏まえつつ、
今回はその中でも特に質問の多い
GetComponentに特化して解説していきます。

この記事を読み終える頃には、
「GetComponentがnullで落ちるのが怖い」状態から、
「原因を切り分けて冷静に対処できる」状態になっているはずです。

それでは、まず
GetComponentとは何か?
から見ていきましょう。


目次

  1. GetComponentとは何か?
    1. GetComponentの基本的な使い方
    2. GetComponentは「探している」だけ
    3. 戻り値は「Component または null」
    4. GetComponentが使われる代表的な場面
    5. 重要ポイントまとめ
  2. なぜGetComponentはnullになるのか?
    1. 「失敗している」のではなく「見つからない」
    2. NullReferenceExceptionが発生する本当の原因
    3. Unityは「エディタ設定」と強く結びついている
    4. nullになる原因はほぼパターン化できる
    5. ここからは「具体例」で理解する
  3. よくある原因① 同じGameObjectに付いていない
    1. GetComponentは「自分自身」しか見ない
    2. 別のGameObjectに付いていると必ずnull
    3. よくある勘違い
    4. 正しい対処法① 子オブジェクトから取得する
    5. 正しい対処法② 明示的に参照を持つ
    6. 正しい対処法③ Transform経由で取得する
    7. この原因のチェックリスト
    8. ここまでのまとめ
  4. よくある原因② コンポーネントを付け忘れている(Inspector)
    1. 「コードは合っているのにnull」な理由
    2. Prefabとシーンの差分に注意
    3. スクリプトを付け替えた時も要注意
    4. RequireComponentで事故を防ぐ
    5. Inspectorで必ず確認したいポイント
    6. ここまでのまとめ
  5. よくある原因③ Awake / Start の初期化順問題
    1. Awake と Start の違い
    2. Awakeでnullになる典型例
    3. Startでは成功するケース
    4. GetComponent自体はAwakeでも問題ない
    5. 実行順が関係する場合の対処法
    6. 初期化順で悩まないための考え方
    7. ここまでのまとめ
  6. よくある原因④ GetComponentInChildren / GetComponentInParent の誤解
    1. GetComponentInChildren の基本動作
    2. 非アクティブなオブジェクトは対象外
    3. includeInactive を使う
    4. GetComponentInParent でも同様
    5. 複数ある場合は「最初の1つ」だけ
    6. 安全な設計の考え方
    7. ここまでのまとめ
  7. よくある原因⑤ 実行中にDestroyされている
    1. Destroyされたオブジェクトは「null扱い」
    2. よくあるバグ例
    3. Destroy後に処理しない設計にする
    4. OnDestroy を活用する
    5. 「見た目が残っている」は信用しない
    6. ここまでのまとめ
  8. nullを防ぐための安全な書き方
    1. 基本① 必ず一度変数に受ける
    2. 基本② TryGetComponentを使う(Unity 2019.2以降)
    3. 基本③ 参照はキャッシュする
    4. 基本④ SerializeFieldで明示的に参照する
    5. 基本⑤ RequireComponentを使う
    6. 「nullにならない前提」を捨てる
    7. ここまでのまとめ
  9. GetComponentを減らす設計の考え方
    1. GetComponentは「その場しのぎ」になりやすい
    2. 設計① 参照は「最初にまとめて取得」
    3. 設計② Inspector注入を使う
    4. 設計③ 責務を分離する
    5. 設計④ 初期化専用メソッドを用意する
    6. 「GetComponentが多い=悪」ではない
    7. ここまでのまとめ
  10. よくある質問(FAQ)
    1. Q1. GetComponentは毎回呼んでも大丈夫ですか?
    2. Q2. TryGetComponentとGetComponentの違いは何ですか?
    3. Q3. GetComponentがnullでもエラーが出ないことがあるのはなぜ?
    4. Q4. Destroyしたオブジェクトがnull判定になるのはバグですか?
    5. Q5. GetComponentが多いコードはダメな設計ですか?
  11. まとめ

GetComponentとは何か?

GetComponent は、UnityでC#を書く上で最も基本的かつ重要なメソッドの一つです。

一言で言うと、

同じGameObjectに付いているコンポーネントを取得するためのメソッド

です。


GetComponentの基本的な使い方

最もよく見る形がこちらです。


Rigidbody rb = GetComponent<Rigidbody>();

この1行は、次の意味を持っています。

  • このスクリプトが付いている GameObject
  • そのGameObjectに付いている Rigidbodyコンポーネント
  • それを取得して rb に代入する

つまり、
「自分自身(同じGameObject)から探す」
という点が非常に重要です。


GetComponentは「探している」だけ

GetComponentは、
コンポーネントを生成しているわけではありません。

やっていることはシンプルで、

  • 指定された型のコンポーネントを探す
  • 見つかれば → それを返す
  • 見つからなければ → nullを返す

という処理です。


var rb = GetComponent<Rigidbody>();

if (rb == null)
{
    // Rigidbodyが見つからなかった
}

👉
エラーを出しているのではなく、
「存在しないので null を返している」

というだけなのです。


戻り値は「Component または null」

GetComponentの戻り値は、常に

  • 対象のコンポーネント
  • もしくは null

のどちらかになります。

そのため、次のようなコードは
非常に危険です。

GetComponent<Rigidbody>().AddForce(Vector3.up);

もし Rigidbody が付いていなければ、

  1. GetComponent<Rigidbody>() → null
  2. null.AddForce(…) → ❌ NullReferenceException

という流れでエラーが発生します。


GetComponentが使われる代表的な場面

GetComponentは、以下のような場面で頻繁に使われます。

  • Rigidbody や Collider の取得
  • Animator や AudioSource の操作
  • 他の自作スクリプトへのアクセス

例:

Animator anim = GetComponent<Animator>();
Enemy enemy = GetComponent<Enemy>();

Unityのスクリプトは
「GameObjectに機能を追加する」設計になっているため、
GetComponentはほぼ必須の存在です。


重要ポイントまとめ

ここまでの内容をまとめます。

  • GetComponentは「同じGameObject」から探す
  • 見つからなければ null を返す
  • 生成はしない
  • nullは異常ではない

👉
GetComponentがnullになること自体は正常な動作
という点を、まず押さえておきましょう。


なぜGetComponentはnullになるのか?

GetComponentがnullを返す理由は、実はとてもシンプルです。

指定した型のコンポーネントが、
そのGameObjectに存在しないから

これだけです。

バグでも、Unityの不具合でもありません。
「見つからなかった」 という正常な結果として、
nullが返ってきています。


「失敗している」のではなく「見つからない」

GetComponentという名前から、
「失敗している」「取得に失敗した」
と感じる方も多いですが、実際には違います。

GetComponentは、

  • 成功 → コンポーネントを返す
  • 失敗 → nullを返す

という仕様です。

例:

Rigidbody rb = GetComponent<Rigidbody>();

if (rb == null)
{
    Debug.Log("Rigidbodyは付いていません");
}

このコードは、
エラーを出さずに正常終了します。

👉
GetComponentは例外を投げません。
例外が出るのは、その後に
nullを使ってしまったときです。


NullReferenceExceptionが発生する本当の原因

多くの人が混同しているポイントですが、

  • 原因 → GetComponentがnullを返したこと
  • 実際に落ちる理由 → nullに対して処理をしたこと

です。

GetComponent<Rigidbody>().AddForce(Vector3.up);

この1行には、

  1. Rigidbodyを探す
  2. 見つからなければ null
  3. null に AddForce を呼ぶ

という流れが含まれています。

👉
GetComponent自体は悪くない
という点を理解しておきましょう。


Unityは「エディタ設定」と強く結びついている

Unityでは、

  • GameObject
  • コンポーネント
  • Inspectorの設定

が密接に関係しています。

つまり、

  • スクリプト上は正しく見える
  • でも Inspector では付いていない

という状態が簡単に起こります。

これが、
「コードは合っているのにnullになる」
と感じる大きな理由です。


nullになる原因はほぼパターン化できる

GetComponentがnullになるケースは、
実際には以下のように ほぼ決まったパターン があります。

  • 同じGameObjectに付いていない
  • Inspectorで付け忘れている
  • 初期化タイミングが早すぎる
  • 子・親オブジェクトを誤解している
  • 実行中にDestroyされている

👉
これらを1つずつ理解すれば、
GetComponentで悩むことはほとんどなくなります。


ここからは「具体例」で理解する

次の章からは、
実際によくあるミスを 1つずつ 見ていきます。

まずは最も多い原因、

👉 「同じGameObjectに付いていない」
から解説します。


よくある原因① 同じGameObjectに付いていない

GetComponentがnullになる原因として、
最も多く、最も基本的なケースがこれです。

取得しようとしているコンポーネントが、
同じGameObjectに付いていない


GetComponentは「自分自身」しか見ない

改めて強調しておきたいポイントですが、
GetComponentは

このスクリプトが付いているGameObject

からしかコンポーネントを探しません。

例:

public class Player : MonoBehaviour
{
    void Start()
    {
        Rigidbody rb = GetComponent<Rigidbody>();
    }
}

このコードは、

  • Player スクリプト
  • Rigidbody

同じGameObject に付いている場合のみ成功します。


別のGameObjectに付いていると必ずnull

例えば、次のような構成を考えてみましょう。

  • Player(GameObject)
    • Player.cs
  • PlayerModel(子オブジェクト)
    • Rigidbody

この場合、

GetComponent<Rigidbody>();

を呼んでも、
PlayerModel に付いている Rigidbody は見つかりません。

結果として、null が返ります。


よくある勘違い

初心者の方がよくやってしまうのが、

「子オブジェクトに付いているから取れるはず」

という思い込みです。

しかし、
このコードだけでは子オブジェクトは見ません。

GetComponent<Rigidbody>(); // 見ない

正しい対処法① 子オブジェクトから取得する

子オブジェクトに付いている場合は、
以下のようにします。

Rigidbody rb = GetComponentInChildren<Rigidbody>();

これで、

  • 自分自身
  • 子オブジェクト(すべて)

を対象に検索してくれます。


正しい対処法② 明示的に参照を持つ

もう1つの安全な方法は、
Inspectorから参照を設定するやり方です。

[SerializeField]
private Rigidbody rb;

InspectorでRigidbodyをドラッグすれば、
GetComponentを使わずに確実に取得できます。

👉
特に重要なコンポーネントは、
この方法が一番安全です。


正しい対処法③ Transform経由で取得する

特定の子オブジェクトが分かっている場合は、

Rigidbody rb = transform.Find("PlayerModel")
                        .GetComponent<Rigidbody>();

のように、
対象を限定して取得することもできます。


この原因のチェックリスト

GetComponentがnullになったら、
まずここを確認しましょう。

  • スクリプトと対象コンポーネントは同じGameObjectか?
  • 子オブジェクトではないか?
  • Prefab構造は変わっていないか?

ここまでのまとめ

  • GetComponentは同じGameObjectのみ対象
  • 別オブジェクトなら必ずnull
  • 子オブジェクトは明示的に指定する

よくある原因② コンポーネントを付け忘れている(Inspector)

GetComponentがnullになる原因として、
原因①と並んで非常に多いのがこのケースです。

そもそも、取得しようとしているコンポーネントが
GameObjectに付いていない


「コードは合っているのにnull」な理由

次のコードを見てみましょう。

Rigidbody rb = GetComponent<Rigidbody>();

文法的にも、書き方としても問題はありません。
それでも null になる場合、
Inspectorを確認すると…

  • Rigidbody が付いていない
  • Prefabには付いているが、シーン上のオブジェクトには付いていない
  • 途中で削除してしまった

といったことがよくあります。


Prefabとシーンの差分に注意

Unityでは、

  • Prefab
  • シーン上のインスタンス

別物 です。

例えば、

  • PrefabではRigidbodyが付いている
  • しかしシーン上では削除されている

という状態でも、
見た目では気づきにくいことがあります。

👉
GetComponentがnullになったら、
必ずシーン上のオブジェクトのInspectorを確認しましょう。


スクリプトを付け替えた時も要注意

次のような流れも、よくあるミスです。

  1. 以前は Rigidbody を使っていた
  2. 途中で不要になり、Rigidbody を削除
  3. スクリプト内では GetComponent<Rigidbody>() が残っている

この場合、
当然 null が返ります。


RequireComponentで事故を防ぐ

このミスを防ぐために、
Unityには便利な属性があります。

[RequireComponent(typeof(Rigidbody))]
public class Player : MonoBehaviour
{
}

これを付けておくと、

  • スクリプトをアタッチした瞬間に
  • Rigidbody が自動で追加される

ため、
付け忘れを物理的に防止できます。

👉
必須コンポーネントには積極的に使いましょう。


Inspectorで必ず確認したいポイント

GetComponentがnullになったら、
以下をチェックしてください。

  • 対象のコンポーネントは付いているか?
  • 無効(チェックOFF)になっていないか?
  • Prefabとシーンで差分がないか?

ここまでのまとめ

  • GetComponentは付いていなければ必ずnull
  • Inspector確認は最優先
  • RequireComponentで事故を防げる

よくある原因③ Awake / Start の初期化順問題

GetComponentがnullになる原因として、
意外と見落とされがちなのが
初期化タイミングの問題です。

コード自体は正しいのに、
「タイミングが早すぎて取得できない」
というケースがUnityではよく起こります。


Awake と Start の違い

まずは基本を整理しましょう。

  • Awake
    • オブジェクトが生成された直後に呼ばれる
    • すべてのスクリプトが揃っているとは限らない
  • Start
    • すべてのAwakeが呼ばれた後に呼ばれる
    • 初期化が一通り終わった後

この違いが、
GetComponentがnullになる原因になります。


Awakeでnullになる典型例

次のようなコードを見てみましょう。

private Enemy enemy;

void Awake()
{
    enemy = FindObjectOfType<Enemy>();
    enemy.Init(); // ❌ null の可能性
}

この場合、

  • Enemyオブジェクトがまだ生成されていない
  • もしくは Enemy の Awake が終わっていない

といった理由で、
enemy が null になることがあります。


Startでは成功するケース

同じ処理を Start に移すと、

void Start()
{
    enemy = FindObjectOfType<Enemy>();
    enemy.Init(); // ✅ 安全になりやすい
}

Startは、

  • すべてのAwakeが完了した後

に呼ばれるため、
参照取得が成功しやすくなります。


GetComponent自体はAwakeでも問題ない

誤解されがちですが、

GetComponent<Rigidbody>();

のような
同一GameObject内の取得は、
Awakeでも基本的に問題ありません。

問題になるのは、

  • 他オブジェクト
  • Find系
  • 実行順に依存する処理

です。


実行順が関係する場合の対処法

どうしてもAwakeで取得したい場合は、

  • Script Execution Order を調整する
  • 初期化用メソッドを分離する

といった方法があります。

public void Init()
{
    rb = GetComponent<Rigidbody>();
}

必要なタイミングで
明示的に呼ぶ設計にするのも有効です。


初期化順で悩まないための考え方

  • 自分自身の初期化 → Awake
  • 他オブジェクト参照 → Start以降
  • 依存関係がある処理 → 明示的Init

このルールを決めておくと、
null問題は激減します。


ここまでのまとめ

  • Awakeは早すぎることがある
  • Startは参照取得が安定
  • 他オブジェクトはStart以降が安全

よくある原因④ GetComponentInChildren / GetComponentInParent の誤解

「子オブジェクトに付いているから
GetComponentInChildren を使えば大丈夫」

そう思っているのに null になる場合、
このメソッドの仕様を誤解している
可能性があります。


GetComponentInChildren の基本動作

var rb = GetComponentInChildren<Rigidbody>();

このメソッドは、

  • 自分自身
  • 子オブジェクト(階層すべて)

を対象に、
指定した型のコンポーネントを探します。

しかし、
必ず見つかるわけではありません。


非アクティブなオブジェクトは対象外

重要な落とし穴がこちらです。

デフォルトでは、非アクティブな子オブジェクトは検索されない

例えば、

  • 子オブジェクトが SetActive(false)
  • Prefab内で非表示

この場合、

GetComponentInChildren<Rigidbody>();

null を返します。


includeInactive を使う

非アクティブな子も含めたい場合は、
以下のように指定します。

var rb = GetComponentInChildren<Rigidbody>(true);

この true が、
includeInactive を意味します。

👉
これを知らないと、
「あるはずなのに取れない」
状態になります。


GetComponentInParent でも同様

親オブジェクトを探す場合も、
基本は同じです。

var rb = GetComponentInParent<Rigidbody>();

こちらも、

  • 非アクティブな親
  • 無効化されたオブジェクト

は、
デフォルトでは対象外です。


複数ある場合は「最初の1つ」だけ

GetComponentInChildren / Parent は、

  • 複数見つかった場合
  • 最初に見つかった1つ

だけを返します。

👉
どれが取得されるかは、
ヒエラルキー構造に依存します。

意図しないコンポーネントを
取得しているケースもあるので注意が必要です。


安全な設計の考え方

頻繁にこれらを使う場合は、

  • 明示的にTransformを指定する
  • Inspectorから参照を設定する

ほうが、
バグが入りにくくなります。

[SerializeField]
private Rigidbody childRb;

ここまでのまとめ

  • 非アクティブな子は対象外(デフォルト)
  • includeInactive を使う
  • 複数ある場合は1つだけ返る

よくある原因⑤ 実行中にDestroyされている

「最初は取得できていたのに、
途中からGetComponentがnullになる」

このような場合、
実行中にオブジェクトがDestroyされている
可能性があります。

これはUnity特有の挙動なので、
初心者の方が特に混乱しやすいポイントです。


Destroyされたオブジェクトは「null扱い」

Unityでは、

Destroy(gameObject);

を実行すると、

  • 見た目上は存在している
  • 参照も残っているように見える

にもかかわらず、
nullとして扱われる
という特殊な挙動をします。

if (enemy == null)
{
    // Destroyされている可能性あり
}

👉
C#の純粋なnullとは少し違う、
Unity独自の仕様です。


よくあるバグ例

Enemy enemy;

void Start()
{
    enemy = GetComponent<Enemy>();
}

void Update()
{
    enemy.Move(); // ❌ 途中でnullになる
}

別の処理で enemy が Destroy されると、
Update 内で突然
NullReferenceException が発生します。


Destroy後に処理しない設計にする

Destroyされる可能性がある場合は、
必ずガードを入れましょう。

if (enemy == null) return;

もしくは、

  • フラグで生存管理する
  • 参照を解除する

といった設計が有効です。


OnDestroy を活用する

void OnDestroy()
{
    enemy = null;
}

Destroyされたタイミングで
明示的に参照を切ることで、
意図しないアクセスを防げます。


「見た目が残っている」は信用しない

Unityでは、

  • フレーム終端まで描画が残る
  • 参照があるように見える

ことがあります。

👉
見た目ではなく、参照状態を信じる
ようにしましょう。


ここまでのまとめ

  • Destroyされたオブジェクトはnull扱い
  • 途中からnullになるケースは要注意
  • ガード処理が重要

nullを防ぐための安全な書き方

ここまでで、
GetComponentがnullになる原因は
ほぼパターン化できることが分かってきました。

この章では、
そもそもnullで落ちない書き方・設計
を紹介します。


基本① 必ず一度変数に受ける

まず大前提として、
次の書き方は避けましょう。

GetComponent<Rigidbody>().AddForce(Vector3.up); // ❌

代わりに、
必ず変数に受けてから使うようにします。

Rigidbody rb = GetComponent<Rigidbody>();
if (rb != null)
{
    rb.AddForce(Vector3.up);
}

👉
これだけで、
NullReferenceExceptionの多くは防げます。


基本② TryGetComponentを使う(Unity 2019.2以降)

Unityには、
null対策として非常に便利なメソッドがあります。

if (TryGetComponent(out Rigidbody rb))
{
    rb.AddForce(Vector3.up);
}

この書き方のメリットは、

  • nullチェック込み
  • 意図が分かりやすい
  • コードが簡潔

という点です。

👉
「存在するなら使う」
という処理には最適です。


基本③ 参照はキャッシュする

Updateなどで
毎フレームGetComponentを呼ぶのは、
可読性・パフォーマンスの両面でよくありません。

private Rigidbody rb;

void Awake()
{
    rb = GetComponent<Rigidbody>();
}

一度取得したら、
使い回す設計にしましょう。


基本④ SerializeFieldで明示的に参照する

重要なコンポーネントほど、
Inspectorで明示的に設定する方が安全です。

[SerializeField]
private Rigidbody rb;

これなら、

  • GetComponent不要
  • Inspectorで未設定ならすぐ気づく
  • 構造変更に強い

というメリットがあります。


基本⑤ RequireComponentを使う

必須コンポーネントには、
必ずこれを付けましょう。

[RequireComponent(typeof(Rigidbody))]
public class Player : MonoBehaviour
{
}

これにより、

  • 付け忘れが起きない
  • チーム開発でも安全

になります。


「nullにならない前提」を捨てる

大切な考え方として、

GetComponentはnullになるもの

という前提でコードを書くことが重要です。

  • あるはず
  • 取れるはず

という思い込みが、
NullReferenceExceptionを生みます。


ここまでのまとめ

  • 直接メソッドチェーンしない
  • TryGetComponentを活用
  • 参照はキャッシュする
  • Inspector設定を信頼する

GetComponentを減らす設計の考え方

GetComponentは便利ですが、
多用しすぎるとバグの温床になります。

ここでは、
「GetComponentに頼らない設計」
という視点で考えてみましょう。


GetComponentは「その場しのぎ」になりやすい

よくあるコードがこちらです。

void Update()
{
    GetComponent<Rigidbody>().AddForce(Vector3.up);
}

この書き方は、

  • 毎フレーム探索が走る
  • nullチェックがない
  • 構造変更に弱い

という問題を抱えています。

👉
動いているからOK
になりがちな危険なコードです。


設計① 参照は「最初にまとめて取得」

基本はこの形を目指しましょう。

private Rigidbody rb;

void Awake()
{
    rb = GetComponent<Rigidbody>();
}

こうすることで、

  • 取得失敗が早期に分かる
  • Updateがシンプルになる
  • nullチェック箇所が限定される

というメリットがあります。


設計② Inspector注入を使う

Unityでは、
Inspectorは立派なDI(依存性注入)です。

[SerializeField]
private Rigidbody rb;

この方法の利点:

  • 実行前に設定ミスに気づける
  • GetComponent不要
  • Prefab構造変更に強い

👉
「このスクリプトは何に依存しているか」
が一目で分かります。


設計③ 責務を分離する

GetComponentが多いクラスは、
責務が多すぎるサインです。

例:

  • 移動
  • 攻撃
  • アニメーション
  • サウンド

を1つのスクリプトでやっていませんか?

👉
それぞれを別クラスに分けることで、
GetComponentの数も自然に減ります。


設計④ 初期化専用メソッドを用意する

依存関係がある場合は、
初期化を明示的に行うのも有効です。

public void Init(Rigidbody rb)
{
    this.rb = rb;
}
  • どこで参照が渡されるか分かる
  • 実行順トラブルを避けやすい

「GetComponentが多い=悪」ではない

誤解しがちですが、

  • 少数
  • 初期化時のみ
  • 意図が明確

であれば、
GetComponentは問題ありません。

👉
無意識に増えていないか
を意識することが大切です。


ここまでのまとめ

  • GetComponentは初期化時にまとめる
  • Inspector参照を活用する
  • クラスの責務を見直す
  • 設計でnullを減らす

よくある質問(FAQ)

Q1. GetComponentは毎回呼んでも大丈夫ですか?

技術的には可能ですが、
推奨はされません。

  • 可読性が下がる
  • nullチェックを忘れやすい
  • Updateで多用すると無駄が増える

👉
初期化時に1回取得してキャッシュする
設計がおすすめです。


Q2. TryGetComponentとGetComponentの違いは何ですか?

TryGetComponent(out Rigidbody rb);
  • 成功 / 失敗がboolで分かる
  • nullチェック込み
  • 意図が明確

👉
「存在すれば使う」処理には
TryGetComponentが最適です。


Q3. GetComponentがnullでもエラーが出ないことがあるのはなぜ?

GetComponent自体は、
nullを返すだけでエラーを出しません。

エラーが出るのは、

null.AddForce(...)

のように、
nullに対して処理を行った瞬間です。


Q4. Destroyしたオブジェクトがnull判定になるのはバグですか?

バグではありません。
Unity特有の仕様です。

if (enemy == null)

は、
Destroyされたオブジェクトも
trueになります。


Q5. GetComponentが多いコードはダメな設計ですか?

必ずしもダメではありません。

  • 初期化時のみ
  • 数が少ない
  • 意図が明確

であれば問題ありません。

👉
ただし、
無意識に増えている場合は設計見直しのサイン
と考えましょう。


まとめ

GetComponentがnullになる理由は、
ほとんどの場合 Unityの仕様を誤解している ことが原因です。

重要なポイントを振り返りましょう。

  • GetComponentは同じGameObjectのみ対象
  • 見つからなければ null を返すのが正常
  • Inspector設定ミスは最優先で確認
  • Awake / Start の初期化順に注意
  • Destroyされたオブジェクトはnull扱い

そして何より大切なのは、

GetComponentはnullになる前提で書く

という考え方です。

nullを正しく扱えば、
NullReferenceExceptionは
怖いエラーではなく、原因が分かるエラーになります。

2026-01-15

0件のコメント

コメントはまだありません。最初の一人になりましょう!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です