🙌

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