Unityでスクリプトを書くとき、Start()
とAwake()
のどちらに処理を書くべきか、悩んだことはありませんか?
どちらもゲームオブジェクトの初期化に使えるけれど、「なんとなくStartに全部書いてる」という方も多いかもしれません。
でも実はこの2つ、ちゃんと使い分けることでコードの意図が明確になり、バグも減るんです。
コード省略シリーズの記事でも散々お伝えしてきた「コードの意図」がまた出ました。本当に重要です。
今回は、初心者のうちに知っておきたい Start()
と Awake()
の違いと、実際の使い分けのコツを紹介します。
AwakeとStartを使い分ける
そもそもStartとAwakeの違いって?
まずは公式の仕様に沿ったざっくりとした違いを確認しましょう。
- Awake() は、スクリプトが有効になったタイミングで1度だけ呼ばれます。
この時点で、まだ他のスクリプトの初期化は終わっていない可能性があります。 - Start() は、すべての
Awake()
が完了したあと、最初のUpdate()
の前に呼ばれます。
つまり、他のコンポーネントの初期化が終わった「あと」で処理を実行したいときに使うべきです。
実例でわかる使い分けのポイント
public class Player : MonoBehaviour
{
private Rigidbody rb;
void Awake()
{
rb = GetComponent<Rigidbody>();
// 自分自身の初期化に向いている
}
void Start()
{
GameManager.Instance.RegisterPlayer(this);
// 他のオブジェクトとの連携はStartが安全
}
}
上記の例では、自分自身が持っている Rigidbody を取得する処理は Awake()
に書かれています。
このように「自分の中だけで完結する初期化」は Awake()
が最適です。
一方、Start()
では GameManager
に自分を登録する処理が行われています。GameManager
側の初期化がまだ終わっていなければエラーになってしまうため、依存先が存在するようになる「Startのタイミング」が安全というわけです。
StartとAwakeの両方に書くのはNG?
「両方使っていいの?」「どっちかにまとめるべき?」という質問もよく見かけますが、併用はまったく問題ありません。
むしろ、それぞれの意味を理解して適切に分けることで、コードの見通しがぐっと良くなります。
特に複雑なシーンでスクリプトが増えてくると、「どこで何をしているのか」が一目で分かるようになるメリットは大きいです。
注意点:非アクティブオブジェクトや手動生成との関係
Awake()
は、オブジェクトがアクティブかどうかに関係なく必ず1回呼ばれます。
しかし Start()
は非アクティブなオブジェクトには呼ばれません。
また、Instantiate()
でプレハブを生成したときにも、生成直後に Awake()
→ 次のフレームで Start()
という順序になることを覚えておくと安心です。
まとめ:使い分けのルール(覚え方)
- Awake() → 自分自身の準備
- Start() → 他人と関わる準備
たったこれだけ覚えておくだけでも、トラブルの原因を減らすことができます。
「何となくStartに全部書いてた…」という方は、今日から使い分けを意識してみてください!