UnityのAwake
とStart
の使い分けガイド
Unityでコードを書く際に、レースコンディションやヌル参照エラーを避けるために、Awake
と Start
を正しく使い分けることが重要です。ここでは、そのベストプラクティスを解説します。
1. Awake
の使い方
▶ Awake
で自身のコンポーネントを取得
【理由】
-
Awake
は ゲームオブジェクトが生成された直後に呼ばれる - この段階では 自身のコンポーネントは必ず存在している
- しかし、他の
GameObject
のAwake
はまだ完全に実行されていない可能性がある
【コード例】
private Rigidbody rb;
void Awake() {
rb = GetComponent<Rigidbody>(); // 自身のコンポーネントはここで取得
}
Awake
で実行することで、自分の GameObject 内
に存在するコンポーネントを確実に取得できます。
2. Start
の使い方
▶ Start
で他の GameObject
を取得
【理由】
-
Start
は すべてのAwake
実行後に呼ばれる - そのため、他の
GameObject
のコンポーネントも初期化済みである可能性が高い -
Awake
の段階でGameObject.Find()
を使うとnull
になる可能性があるが、Start
ならより安全
【コード例】
private GameObject target;
void Start() {
target = GameObject.Find("TargetObject"); // 他のGameObjectを安全に取得
}
これにより、Awake
よりも確実に target
を見つけることができます。
3. レースコンディション(Race Condition)とは?
プログラムの 実行順が保証されていない ために起こるバグのことです。
⚠️ 悪い例:
private GameManager gm;
void Awake() {
gm = FindObjectOfType<GameManager>(); // GameManagerのAwakeがまだ実行されていなかったらnullになる!
}
この場合、GameManager
の Awake
がまだ実行されていないと gm
は null
になります。
✅ 安全な方法(Start
で取得する)
void Start() {
gm = FindObjectOfType<GameManager>(); // `Awake` の後に実行されるので、より安全
}
こうすれば、GameManager
の Awake
が完了した後に取得できるので、より安全です。
4. Awake
と Start
の適切な使い分けまとめ
メソッド | いつ呼ばれる? | 何をやるべき? | 例 |
---|---|---|---|
Awake |
オブジェクト生成時(コンポーネントがアタッチされた時) | 自身のコンポーネントを取得 | GetComponent<Rigidbody>() |
Start |
すべての Awake の後 |
他のオブジェクトの参照を取得 | FindObjectOfType<GameManager>() |
✅ より安全な設計のために
- 自分のコンポーネントは
Awake
で取得 - 他の
GameObject
のコンポーネントはStart
で取得 - 外部データのロードなど時間がかかる処理は
Start
やCoroutine
で処理
このルールを守ることで、NullReferenceException
を防ぎ、バグの少ない予測しやすいコードを書くことができます!