【Unity】スライムが複数いると追跡をやめる原因と対処法|Raycastとレイヤー設定を理解しよう
こんな現象に心当たりはありませんか?
Unityでアクションゲームを作っているとき、敵のスライムを複数体置いたところ、次のような動きになりませんでしたか。
- スライムがプレイヤー(クエリちゃん)を追いかけている途中で、急に立ち止まる
- スライムが1体だけのときは、ちゃんと追いかけてくる
- 他のスライム(味方)が近くにいるときに限って、追跡が止まる
スクリプトにミスは見当たらないのに、複数体にしたとたんに起きる――このようなバグは、実はスクリプトではなく、レイヤーの設定が原因です。この記事では、原因をたどり、初学者の方でも理解して直せるように解説します。
取り上げるのは、敵がプレイヤーを索敵して追いかける、次のような構成です。
- 索敵エリア:スライムの子オブジェクト
CollisionDetector(半径4のトリガーSphere Collider) - 追跡処理:
EnemyMove.OnDetectObject(索敵エリアに入った相手が Player タグなら、NavMeshAgentで追いかける)
ポイント1 原因は「視線チェックのRaycastが、他のスライムの索敵エリアに当たっている」
スライムは、プレイヤーを見つけると、間に障害物がないかを Physics.RaycastNonAlloc で確かめてから追いかけます。問題の箇所は次のコードです。
var hitCount = Physics.RaycastNonAlloc(
transform.position, direction, _raycastHits, distance, raycastLayerMask);
if (hitCount == 0)
{
// 間に何もない → 追いかける
_agent.isStopped = false;
_agent.destination = collider.transform.position;
}
else
{
// 何かに当たった → 見失ったとみなして停止
_agent.isStopped = true;
}
このコードは「レイが1つでも何かに当たれば、障害物ありと判断する」作りです。ポイントは、何に当たるかを決めるのが raycastLayerMask である点です。
このプロジェクトでは、マスクは Default レイヤーのみになっていました。一方で、索敵エリアを担当する子オブジェクト CollisionDetector も Default レイヤーのままでした。
さらに、Raycastはトリガー(Is Trigger が ON の Collider)にも当たるという初期設定です(Physics.queriesHitTriggers がデフォルトで ON)。つまり、レイが他のスライムの索敵球を横切ると、「間に障害物がある」と判定されてしまいます。
ポイント2 なぜ「複数体のときだけ」起きるのか
流れを順に追うと、理由が見えてきます。
- スライムAがプレイヤーを見つけ、プレイヤーに向けてレイを飛ばす
- そのレイが、近くにいるスライムBの索敵球(半径4・Defaultレイヤー・トリガー)を横切る
- マスクに Default が含まれ、トリガーも無視されないので、レイが当たる
hitCountが 0 でなくなり、「見失った」扱いでスライムAが停止する
なお、スライムA自身の索敵球には当たりません。レイの始点が索敵球の内側にあるためです。そのためスライムが1体だけのときは問題が表に出ず、複数体置いて初めて症状が見えるのです。スライム同士が近づくほど、起きやすくなります。

ポイント3 対処:索敵エリア専用のレイヤーを作る
解決策は、索敵エリアを「レイが当たらないレイヤー」に移すことです。スクリプトは変えず、エディタの設定だけで直ります。索敵エリア専用のレイヤーを作る方法を、手順で紹介します。
手順A レイヤーを追加する
- メニューから Edit > Project Settings > Tags and Layers を開く
- Layers を開き、空いているスロットに
EnemyMoveTargetDetectorと入力する

手順B 索敵エリアにレイヤーを割り当てる
- スライムのプレハブを開く
- 子オブジェクト
CollisionDetectorを選択し、Inspector上部の Layer をEnemyMoveTargetDetectorに変更する - このモデルをバリアントやコピーで増やしている場合(大きいスライム、小さいスライムなど)は、それらも同じ設定になっているか確認する

手順C Layer Collision Matrix を整える
専用レイヤーを作ったら、Edit > Project Settings > Physics の Layer Collision Matrix で、どのレイヤーと当たり判定をするかを決めます。
EnemyMoveTargetDetectorの行・列を、Player とだけ ON にする- このレイヤーと他のレイヤーの組み合わせは、すべて OFF にする
マトリクスは「どのレイヤー同士で当たり判定を行うか」の一覧表です。センサー(索敵エリア)は、探したい相手の Player とだけ当たればよい、と役割から考えると理解しやすくなります。このプロジェクトでは、攻撃判定も同じ考え方です。
| レイヤー | 役割 | ON にする相手 |
|---|---|---|
EnemyMoveTargetDetector | 敵の索敵センサー | Player のみ |
EnemyAttack | 敵の攻撃判定 | Player のみ |
PlayerAttack | プレイヤーの攻撃判定 | Enemy のみ |

これで直る理由
Raycast Layer Maskは Default のままで、索敵エリアはマスクの対象外になるため、レイが当たらなくなる- 地形や壁など実体のある障害物(Defaultレイヤー)は、これまでどおり視線を遮る
- 索敵エリアは Player とだけ当たるので、プレイヤーを見つける動作はそのまま動く
ポイント4 コードでさらに安全にする:QueryTriggerInteraction.Ignore
レイヤー設定で直る方法は、「索敵エリアのレイヤーが、マスクに含まれていないこと」を前提にしています。この前提はコードのどこにも書かれていないため、後からレイヤーを変更したときに同じバグが再発する可能性があります。
そこで、Raycastの最後の引数に QueryTriggerInteraction.Ignore を渡して「視線チェックではトリガーを無視する」と宣言しましょう。
// 視線チェックでは索敵エリアなどのトリガーを無視し、実体のある障害物だけを対象にする
var hitCount = Physics.RaycastNonAlloc(
transform.position, direction, _raycastHits, distance,
raycastLayerMask, QueryTriggerInteraction.Ignore);
引数は、順に「始点、方向、結果を入れる配列、距離、レイヤーマスク、トリガーの扱い」です。
| 値 | 動き |
|---|---|
Ignore | トリガーを無視する(今回はこれ) |
Collide | トリガーにも当たる |
UseGlobal | 省略時の既定値。プロジェクト設定の Queries Hit Triggers に従う(デフォルトで ON) |
これで「レイヤー設定」と「コード」の二重の守りになり、レイヤー設定を変更しても追跡が止まりにくい構造になります。地形や壁など、トリガーではない Collider は、これまでどおり視線を遮ります。
ポイント5 とりあえず直したいときは Enemy レイヤーでもOK
新しいレイヤーを作るのがやや大がかりに感じる場合は、CollisionDetector の Layer を、スライム本体と同じ Enemy にするだけでも直ります。
- 新しいレイヤーも、Layer Collision Matrix の追加設定もいらない
- Enemy と Player の組み合わせは ON なので、プレイヤーを見つける動作もこれまでどおり
- Raycastのマスクは Default のままで、索敵エリアがマスクの対象外になる
索敵エリアはセンサーですので、役割で分けた専用レイヤー(ポイント3)のほうが、設計としてはすっきりします。まずは Enemy で動かして理解し、慣れたら専用レイヤーに進む、という順序もおすすめです。
よくある勘違い:Physics Materialやマトリクスのせい?
原因を探すときに疑いやすい、次の2点は今回のバグとは関係ありません。
- Physics Material:摩擦や反発を決める設定です。トリガー判定やレイキャストには影響しません
- Layer Collision Matrix:Collider同士の衝突とトリガーの発生だけを決めます。Raycastはマトリクスを見ず、コードで渡すレイヤーマスクだけで当たる相手を決めます
「衝突の設定」と「レイの設定」は別物と覚えておくと、トラブルシュートが速くなります。
動作確認のポイント
- シーンにスライムを、3体以上近くに置く
- プレイヤーをスライムの索敵範囲に入れ、追いかけてくることを確認する
- 他のスライムが間に入っても、追跡が止まらないことを確認する
- 壁や箱(Defaultレイヤーのコライダー)の裏に隠れたときは、これまでどおり追跡が止まることも確認する
まとめ
- 現象:スライムを複数体置くと、追跡中に立ち止まる
- 原因:視線チェックのRaycastが、他のスライムの索敵エリア(Defaultレイヤー・トリガー)に当たっていた
- 対処:索敵エリアを専用レイヤーに分け、マトリクスで Player とだけ ON にする(簡易版は Enemy レイヤー)
- さらに安全に:
QueryTriggerInteraction.Ignoreで、視線チェックからトリガーを外す
レイヤーは「誰と誰が当たるか」を整理する道具です。スライムを増やすときは、最初から索敵エリアに専用レイヤーを割り当てる習慣をつけておくと、同じトラブルを防げます。
関連記事
- Unityで敵をプレイヤーの周りにランダム出現させる|NavMesh対応のSpawnerをコルーチンで作ろう
- Unityゲームにおける状態管理とキャラクター制御スクリプトの解説(敵の攻撃からプレイヤーの攻撃まで)










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