📘
【Unity】敵AIのターゲットを動的に切り替える方法
はじめに
敵が常にプレイヤーだけを狙う実装だと、
味方ユニットや障害物を配置しても無視されてしまい、
ゲーム性が単調になりやすいです。
今回は、
「通常はプレイヤーを狙う」
「近くに味方ユニットがいればそちらを狙う」
「撃破後は元の目標に戻る」
というターゲット切り替え処理を実装します。
やりたいこと
- 基本ターゲットを持つ
- 一定範囲内の別ターゲットを検知する
- 条件に合えばターゲットを切り替える
- 切り替え先が倒されたら元のターゲットへ戻す
例えば以下のような状況を想定します。
- 敵は通常時はプレイヤーを追跡
- 味方ユニットが近くにいる場合はそちらを攻撃
- 味方ユニット撃破後は再びプレイヤーを追跡
このような仕組みを作ることで、
敵の行動に変化を付けることができます。
実装方針
-
defaultTarget
を保持する -
currentTarget
を現在の攻撃対象にする - 一定範囲内の候補を探す
- 候補があれば
currentTarget
を差し替える - 候補が無効になったら
defaultTarget
に戻す
実装例
今回は以下の流れでターゲットを切り替えています。
- 現在のターゲットが有効か確認
- 無効ならデフォルトターゲットへ戻す
- 周囲のターゲット候補を検索
- より優先度の高い対象が見つかれば切り替える
周囲のターゲット候補は
OverlapSphereNonAllocを利用して周囲の対象を取得し、
最も距離の近いオブジェクトを選択しています。
[SerializeField] private GameObject defaultTarget;
[SerializeField] private GameObject currentTarget;
private void Update()
{
// 現在のターゲットが有効か判定
if (!IsValidCurrentTarget())
{
currentTarget = defaultTarget;
// 関連コンポーネントへのターゲット反映(必要に応じて実装)
ApplyTarget(defaultTarget);
}
GameObject nearest = FindNearestTarget();
GameObject desired = nearest ?? defaultTarget;
if (desired != currentTarget)
{
currentTarget = desired;
// 関連コンポーネントへのターゲット反映(必要に応じて実装)
ApplyTarget(desired);
}
}
// 周辺ターゲット取得処理
private GameObject FindNearestTarget()
{
// ターゲット候補オブジェクト取得処理
int count = Physics.OverlapSphereNonAlloc(
transform.position, // 検知の中心座標
targetSwitchRadius, // 検知対象半径
scanResults, // 検知結果
targetableLayerMask, // 検知対象のレイヤーマスク
QueryTriggerInteraction.Collide);
GameObject best = null;
float bestSqrDistance = float.MaxValue;
for (int i = 0; i < count; i++)
{
Collider hit = scanResults[i];
if (hit == null) continue;
// Targetable:検知対象になるゲームオブジェクト(敵or味方等)にアタッチ
Targetable target = hit.GetComponent<Targetable>();
if (target == null || !target.IsTargetable) continue;
if (target.transform == null) continue;
float sqrDistance = (target.transform.position - transform.position).sqrMagnitude;
if (sqrDistance < bestSqrDistance)
{
bestSqrDistance = sqrDistance;
best = target.gameObject;
}
}
return best;
}
なお、サンプルでは分かりやすさを優先して
Update()内で探索していますが、
実際の実装する際は一定間隔で検索する方が負荷を抑えられます。
実装時の注意点
- 毎フレーム探索すると重くなりやすい
- Coroutineや一定間隔更新も検討する
- 優先順位を決めておく
- 倒された対象を参照し続けない
- 対象がなくなった時の更新処理が必要
まとめ
敵のターゲットを固定せず状況に応じて切り替えられるようにすると、
ゲームらしい駆け引きを作りやすくなります。
今回のようにデフォルトターゲットを保持しておけば、
一時的なターゲット変更と復帰処理も比較的シンプルに実装できます。