この投稿で得られること
- Unityで状態値が正しく初期化されないバグの原因
-
Awake()
とStart()
の正しい使い分け方 - 実行順がバグの引き金になる事例とその対処法
現象:敵のHPがいきなり0からスタート!?
ある日、Unityで敵ユニットを配置してゲームを再生したところ…
え? HPが0で始まってる!?
しかも、起きるときと起きないときがある
→ プレハブは正常、設定値も正しい、なのになぜ…?
実際のコード
void Start()
{
stats = Instantiate(statsTemplate);
currentHP = stats.maxHP;
UpdateHPBars(currentHP, stats.maxHP, 0, false);
}
このコードの中で stats.maxHP は正しい値(例:100)を持っていますが、
再生した瞬間に currentHP が0のままでHPバーが表示されることがありました。
原因:Start() よりも先に他スクリプトが currentHP を参照していた
Unityの実行順は以下の通りです:
Awake() → OnEnable() → Start()
この順序により、他のスクリプトの Start() や Update() が走る前に currentHP をセットしないと、0のまま参照されてしまうことがあるのです。
void Awake()
{
stats = Instantiate(statsTemplate);
currentHP = stats.maxHP;
}
void Start()
{
UpdateHPBars(currentHP, stats.maxHP, 0, false);
}
Awake() はオブジェクト生成時に最も早く呼ばれるタイミングなので、
状態値の初期化はここで行うのがベストです。
学びポイント
Unityの実行順は Awake() → OnEnable() → Start() の順
Start() では既に他のスクリプトがアクセスしている可能性あり
状態(HPなど)を持つスクリプトは Awake() で初期化しておくと安全
補足:Script Execution Order でも制御可能
どうしても順番を制御したい場合は、
Edit > Project Settings > Script Execution Order
から EnemyController の実行優先度を上げることもできます。
ただし、原則はAwakeによる初期化の方がシンプルで安全です。
アイキャッチ付きでブログでも発信中
実際のUnity画面を再現したアイキャッチ画像も作りました。
ブログでもUnityや開発ネタを発信中です!
開発ノウハウやアプリ制作過程、Unity連携系のハマりポイントなど
より深掘りした内容をブログでまとめています。
▶ https://syunpp.com
公開中のアプリ一覧はこちら!
▶ https://syunpp.com/公開中のアプリ一覧/
コメント・ストック・LGTM大歓迎!
「自分も似た経験ある」「こんな対策してるよ」などあればぜひコメントで教えてください!
ストックやLGTMも励みになります!
まとめ
状態値の初期化は Awake() が基本!
Start() に依存してると予期せぬバグの温床になることも
Unityの実行タイミングは奥が深いけど、一度覚えるとトラブルも回避しやすくなる!