FPSで追いかけてて発砲してくる敵キャラを作ってみました。
無料のアセットだけを使って実装しました。
アセットはToon Soldiers Demoというのを使っています。
https://assetstore.unity.com/packages/3d/characters/toon-soldiers-demo-69684
このアセットを使って似たようなFPSゲーの敵キャラを使った動画があったのですが、
有料のアセット(UFPS?)に含まれるスクリプトが必要だったりして、再現できない感じだったので自分で作りました。
作り方はシンプルで、以下の通りです。
- 追跡用コライダ内に入ったら追いかける
- 射程用コライダ内に入ったら撃つ
- ダメージ判定用コライダ内に入ったらダメージを与える
というふうにしています。
コライダを3つ用意してそれぞれで処理を分けて実装しました。
それぞれのコードは以下の通りです。
追いかける
// プレイヤーの位置を追跡します。 public void onDetectObject(Collider collider) { if (!_status.IsMovable) { _agent.isStopped = true; return; } if (collider.CompareTag("Player")) { _agent.isStopped = false; _agent.destination = collider.transform.position; } }
このコードはonTriggerStayの中で呼び出しています。(追跡用コライダのisTriggerはチェックを入れています。)
プレイヤーが追跡用コライダの中に入ったら上記のコードで追いかけるようにしています。
Window→AI→Navigationでベイクして追いかけるルートを計算しておきましょう。

発砲する
射程用コライダはプレイヤーが射程圏内にいるかどうか判別するためのコライダです。
public void OnAttackRangeEnter(Collider collider) { if (collider.CompareTag("Player")) { var positionDiff = collider.transform.position - transform.position; var distance = positionDiff.magnitude; var direction = positionDiff.normalized; var hitCount = Physics.RaycastNonAlloc(transform.position, direction, _raycastHits, distance, raycastLayerMask); // プレイヤーとの間に障害物がないかチェックする。 if (hitCount == 0) { if (!_status.IsAttackable) return; // ステータスと衝突したオブジェクトで攻撃可否を判断 _status.GoToAttackStateIfPossible(); //プレイヤーの方向を向く(y軸) Vector3 target = collider.transform.position; target.y = this.transform.position.y; this.transform.LookAt(target); } } }
このコードもonTriggerStayの中で呼び出しています。
追跡用コライダのisTriggerはチェックを入れています。
追いかける時とは違い、レイキャストを飛ばして、障害物がない時だけ、発砲しています。
敵が壁などの障害物があるのに発砲してきたら、強すぎ&怖すぎですからね。
ダメージを与える
ダメージ判定用コライダは、発砲開始時にオンして終わったらオフにしておきます。
コライダのオン・オフを切り替えるにはアニメーションで設定します。
ソルジャーのアセットに、assult_combat_shootが含まれていますので、CTRL + D で複製して_customをつけて名前を変更し、編集可能な状態にします。

OnAttackStart,OnAttackFinishをそれぞれアニメの開始、終了時にセットしました。
public void OnAttackStart() { attackCollider.enabled = true; } public void OnHitAttack(Collider collider) { var player = collider.GetComponent<PlayerStatus>(); if (null == player) return; player.Damage(1); } public void OnAttackFinished() { attackCollider.enabled = false; StartCoroutine(CooldownCoroutine()); }
ダメージ判定用コライダのonTriggerEnterの中でOnHitAttackを呼び出します。
OnTriggerEnterはコライダに入った時の一回のみしか呼ばれませんので、連続してダメージを与えてしまうことはありません。