複数体のスライムが急に追跡をやめる原因を、Layer と Raycast で解剖する

広告

Unity で敵 AI を作っていると、1体では正常なのに、複数体にすると全員止まるという現象に遭遇することがあります。
今回のケースはまさにそれで、結論から言うと原因は次の組み合わせでした。

  • EnemyMove の RaycastLayerMask が Default
  • CollisionDtetector(索敵トリガー)の Layer も Default
  • Queries Hit Triggers が有効(既定 ON のことが多い)

この3つが揃うと、敵同士の索敵トリガーが Raycast を遮ってしまうため、プレイヤーを見失います。


症状

  • スライム1体なら Queryちゃんを追う
  • スライムを複数置くと、全員ほぼ停止
  • CollisionDtetector の Layer を Default → Enemy にすると、一斉に追跡復帰

「Layer を変えたら直った」時点で、スクリプトロジックというより物理クエリ(Raycast)とレイヤーフィルタの問題を疑うのが正解です。


何が起きていたか

1. 索敵トリガーは Trigger コライダー

CollisionDtetector は SphereCollider (isTrigger = true)

半径が大きいほど、敵同士の判定球が重なりやすくなります。

2. Raycast は Trigger も拾っていた

Physics.queriesHitTriggers が有効だと、Raycast は Trigger にヒットします。
つまり、他スライムの索敵球も「壁」として扱われます。

3. RaycastLayerMask が Default だった

プレイヤーだけ見たいつもりでも、同じ Default にいる Trigger までヒット対象になります。
結果、次のようなことが起こります。

  • スライムAがプレイヤー方向にRayを撃つ
  • 途中でスライムBの CollisionDtetector(Default, Trigger)に当たる
  • 最初のヒットがプレイヤーでなくなる
  • 視線判定失敗 → 追跡しない

これが全体で同時多発し、「全員止まる」ように見えます。


なぜ Enemy Layer にすると直るのか

CollisionDtetector を Enemy に移したことで、RaycastLayerMask = Default の Ray から除外されます。
その結果、敵同士の索敵球が視線を遮らなくなり、プレイヤーにRayが届くようになります。


実践的な設計指針(中規模プロジェクト向け)

中級者以降は「とりあえず動く」より、判定の責務分離が効きます。

  • 敵本体・敵の検知トリガーは Enemy Layer
  • プレイヤーは Player Layer
  • 地形や障害物は Default or Environment
  • 視線判定Rayは「本当に見たい層」だけを LayerMask に入れる
  • 必要なら QueryTriggerInteraction.Ignore で Trigger を明示除外

特に「索敵トリガー」と「視線判定Ray」が同じ層を見ていると、今回のような自己干渉が起きやすいです。


デバッグで再現性を上げるチェックリスト

  • Layer Collision Matrix で想定外のON/OFFがないか
  • Physics.queriesHitTriggers の状態
  • RaycastLayerMask に何が入っているか
  • RaycastHit.collider.name / layer をログ出力
  • Debug.DrawRay で実際の視線を可視化

「誰に当たっているか」をログで出すだけで、原因特定速度はかなり上がります。


まとめ

今回の本質はシンプルです。
AIが止まったのではなく、視線判定が“味方の索敵トリガー”に吸われていた、ということ。

  • 1体では問題なし
  • 複数体で破綻
  • Layer分離で即改善

このパターンは、敵AIの初期実装から量産フェーズに移るタイミングで非常に起きやすいので、早めにレイヤー設計を固めるのがおすすめです。


訪問数 16 回, 今日の訪問数 16回

広告

Unity

Posted by hidepon