🙌
UnityでHPが0から始まる謎のバグ ー原因は初期化タイミングだった
この投稿でわかること
- Unityで状態値(HPなど)が初期化されないバグの原因
-
Awake()
とStart()
の正しい使い分け - Unityのスクリプト実行順による非直感的な不具合の回避方法
現象:敵のHPがいきなり0からスタート!?
Unityで敵ユニットを複数配置して再生したところ、
「初期HPが0で開始されている」というバグに直面しました。
しかも再現は不定期。
再生ボタンを押すたびにHPが0か100か変わることも…。
実際のコード
void Start()
{
stats = Instantiate(statsTemplate);
currentHP = stats.maxHP;
UpdateHPBars(currentHP, stats.maxHP, 0, false);
}
見た目は問題なさそう。
statsTemplate は ScriptableObject で、maxHP = 100 も正常。
にもかかわらず、画面上のHPバーが0表示になることがあったんです。
原因:Start() より早く他スクリプトが currentHP にアクセスしていた
Unityの実行順は以下のようになっています。
Awake() → OnEnable() → Start()
Start() の中で currentHP を初期化しても、
他スクリプトがその前に currentHP を参照している可能性があるんですね。
解決策:Awake() に初期化処理を移動
void Awake()
{
stats = Instantiate(statsTemplate);
currentHP = stats.maxHP;
}
void Start()
{
UpdateHPBars(currentHP, stats.maxHP, 0, false);
}
こうすることで、他のスクリプトが Start() や Update() でアクセスする前に、確実に currentHP を初期化できます。
学びポイント
Unityの初期化順は Awake() → Start()
状態値(HP・MP・行動状態など)は Awake() で確実に初期化すべし
Start() では他スクリプトが既に動いてる可能性がある
補足:実行順が重要なときは Script Execution Order も活用
どうしても初期化順序を明示的に制御したい場合は、
Unityメニューから:
Edit > Project Settings > Script Execution Order
で EnemyController の実行順を上位にしておくのも手です。
このバグ含めて色々まとめてます!
Unityでのハマりポイントや開発ノウハウは、ブログでも発信しています。
👉 https://syunpp.com
公開中のアプリ一覧はこちら!
Unityで開発・公開済みのアプリ一覧です。
👉 https://syunpp.com/公開中のアプリ一覧/
コメント・ストック大歓迎!
似たような経験をされた方、他に良い設計案をお持ちの方、
コメントやストックをいただけると嬉しいです!
Discussion