
ナビメッシュエージェントに目的地を設定するときに、プレイヤーの位置をそのまま伝えるのではなく、プレイヤーへの方向を中心とした範囲の中から目的地の方向をランダムで決定して大まかに目的地を設定してみます。
- Vector3 targetDir = (player.position - transform.position) * 1.5f; // エージェントからプレイヤーの少し後ろへ
- Vector3 minTargetDir = Quaternion.Euler(new Vector3(0, -targetRange, 0)) * targetDir; // 水平に回転
- Vector3 maxTargetDir = Quaternion.Euler(new Vector3(0, targetRange, 0)) * targetDir; // 反対側に回転
-
- // 範囲の両端にテスト用の球を生成
- Instantiate(sphere1, minTargetDir + transform.position, transform.rotation);
- Instantiate(sphere2, maxTargetDir + transform.position, transform.rotation);
-
- targetDir = Vector3.Slerp(minTargetDir, maxTargetDir, Random.Range(0f, 1f)); // 範囲の中からランダムで方向を選ぶ
- Vector3 dest = targetDir + transform.position; // 目的地
-
- Instantiate(sphere3, dest, transform.rotation); // 目的地にテスト用の球を生成
-
- NavMeshHit hit;
- // 目的地に最も近いナビメッシュ上の点を探す
- if (NavMesh.SamplePosition(dest, out hit, 20f, NavMesh.AllAreas))
- {
- Instantiate(sphere4, hit.position, transform.rotation); // 目的地の最寄りのナビメッシュ上の点にテスト用の球を生成
- agent.destination = hit.position;
- }
まずエージェントからプレイヤーへの方向を求めて、それを指定の角度だけY軸に沿って回転させて両サイドに広げることで、目的地の方向の範囲の両端の方向を決めます。今回はテスト用に範囲の両端の位置に青と黄色の球を配置しました。
そして、その2つの方向の間からランダムで目的地の方向を選びます。その方向にナビメッシュエージェントの位置を加えると目的地の位置がわかります。ここに緑の球を置きました。
そこがナビメッシュ上でないと困るので、前の記事の方法で最寄りのナビメッシュ上の位置を求めて、エージェントに伝えます。ここにオレンジの球を置きました。
これで、大まかにプレイヤーの方へエージェントを向かわせることができました。エージェントが複数いても問題ありません。

目的地の距離の最小値を設定しないでプレイヤーが立ち止まっていると、いずれエージェントはプレイヤーの近くに集まってしまいます。
- Vector3 targetDir = Vector3.Normalize(player.position - transform.position);
- targetDir = targetDir * Mathf.Max(Vector3.Distance(player.position, transform.position) * 1.5f, 50f);