Unityで複数の敵をデバッグする方法
― 同じスクリプトを持つ複数インスタンスの中で「どの敵が処理されたか」を正しく判別する
Unity では、複数の敵キャラクターが同じ Enemy スクリプトを持つ状況はよくあります。
しかしこの構成には特有のデバッグの難しさがあります。
- どの敵の Update が呼ばれたのか分からない
- どの敵の HP が減ったのか特定できない
- 想定外の敵がイベントを受けているように見える
- Visual Studio のブレイクポイントで止めても、どのインスタンスか判断できない
こうした「複数インスタンスのデバッグ問題」に対して、どの敵インスタンスが処理の対象になっているか正確に判別する方法をまとめます。
(Unity 側がブレイク中に操作できなくなる話は、この記事では補足扱いとします。)
1. なぜ同じスクリプトを複数の敵に付けると判別が難しいのか?
理由は単純で、同じ C# コードが複数のインスタンスで同時に動いているためです。
public class Enemy : MonoBehaviour
{
public int hp = 10;
void Update()
{
// 全員がそれぞれの hp を持つ
}
}
この Enemy が 10 体いれば、Update() も TakeDamage() も 10 個のインスタンスで呼ばれます。
しかしコード上ではすべて 同じ場所のブレイクポイントで止まるため、「今どの敵の処理?」が分からなくなりがちです。
2. ブレイクした敵インスタンスを判別するための基本テクニック
複数インスタンスの識別には、以下の方法が実務で最も有効です。
方法① Visual Studio の Locals(ローカル) / Watch(ウォッチ1) で this.name を確認(最重要)
ブレイクポイントで処理が停止したら、Visual Studio の Locals(ローカル) ウィンドウ を開きます。


this を展開すると name が表示されます。
例:
this.name = Enemy_3
→ 今まさに処理されている敵がすぐに分かります。
敵生成時に名前を付けておくと完璧
enemy.name = $"Enemy_{id}";
方法② 固有IDを持たせる(最も一般的)
public int enemyId;
public void Init(int id)
{
enemyId = id;
}
ブレイクしたら Locals で enemyId を見るだけで、どのインスタンスかが明確に分かります。
方法③ ログにインスタンス情報を出す(大量の敵に有効)
Debug.Log($"Damage! EnemyID={enemyId}, HP={hp}", this);
Unity 側が動いている状態なら、ログをクリックすると該当敵が Hierarchy で選択されます。
※ ブレイクポイント使用中は Unity が停止するため、 ログ方式はブレイクしないデバッグに最適。
方法④ 条件付きブレイクポイントで「特定の敵だけ止める」
Visual Studio のブレイクポイントを右クリックして Conditions を設定。
例:ID=4 の敵だけで停止したい
enemyId == 4
例:特定の HP の時だけ止めたい
hp <= 0
無駄に何度もブレイクしなくて済むため、複数敵デバッグでは非常に便利です。
3. ブレイク中に Unity エディターが操作できない問題は “仕様”
Visual Studio でブレイクすると、Unity エディターのプロセス全体が OS によって停止するため、
- ヒエラルキー選択不可
- Inspector 変更不可
- ウィンドウ操作不可
となります。
これは正常動作です。
そのため、ブレイク中に Unity エディター側で敵を特定することは不可能であり、上記の Visual Studio 側での判別方法が必須 となります。
※ これは記事の主テーマではないため詳細は割愛しています。
4. Unity 側の Inspector 操作を使いたい場合はDebug.Break() を使う
Unity 側のPause機能なら、ゲームは止まりますがエディターは操作できます。
if (hp < 0)
{
Debug.Break(); // Unity 停止(エディターは操作可能)
}
Inspector で該当オブジェクトを触りたいときはVisual Studio ブレイクではなく Unity Pause を使うとよいです。
5. 実務でのベスト・デバッグフロー
複数敵デバッグを行う場合、以下のセットが最も効率的です。
● ① 敵生成時に index(敵ID)と名前を付与
enemy.enemyId = i;
enemy.name = $"Enemy_{i}";
● ② 基本は Visual Studio の Locals / Watch で判別
- this.name
- enemyId
- hp
これだけでほとんどデバッグできます。
● ③ 条件付きブレイクで対象を絞る
無駄に止まらず効率的。
● ④ Inspector で見たいときは Debug.Break() を一時的に挿入
ブレイクポイントと Pause の”,役割を切り替えることでストレスなくデバッグできます。
6. まとめ
複数の敵が同じスクリプトを使っている場合のデバッグは、「どのインスタンスが処理されたかを見分ける」ことが最重要ポイントです。
そのための基本は:
| 方法 | 用途 |
|---|---|
| this.name(Locals) | 最も簡単・確実 |
| 固有IDを付与 | 判別をさらに明確にする |
| ログ + インスタンスID | ブレイクを使わない検証に最適 |
| 条件付きブレイク | 特定インスタンスのみ止めたい時 |
そして、Unity エディターが操作できないのは仕様であり、ブレイク時の判別は VS 内で完結させるのが正しいやり方 です。


ディスカッション
コメント一覧
まだ、コメントがありません