FPSゲームの作り方9 Unityで敵が自動で攻撃する人工知能を完成させる

Unity FPSゲームの作り方


Unity入門の森オリジナル本格ゲーム制作講座はこちら
8種類の本格ゲームの全ソースコード公開・画像&動画による解説付き

この記事はFPSゲームの作り方講座の第9回目です。

前回はCinemachineによる移動と敵の攻撃準備のための移動処理AIを作成しました。

前回の記事:

FPSゲームの作り方8 Unityで空を飛ぶ敵の自動行動AI・プレイヤー追尾処理を作る
この記事はFPSゲームの作り方講座の第8回目です。空を飛ぶ敵のAIを作成していきます。 前回はNavMeshを使って敵の移動処理、そしてNavMeshObstacleを使って敵が障害物を避ける処理等を作成しました。 前回の記事:...

今回は敵が自動で動いて攻撃してくる人工知能の開発を完成させていきましょう。

近距離攻撃、遠距離攻撃両方を移動処理を結合させながら行動してくるAIを作ります。

盛りだくさんの内容ですが一緒にがんばって作っていきましょう!


【Line登録者限定のプレゼントもあるよ!】

EnemyBase.csに死亡フラグの追記を行う

まずは、少し「EnemyBase.cs」に追記していきます。 

追加するのは、「isDead」というフラグです。死亡した瞬間に「すでに死亡しています」という状態を表すために使用します。

「OnEnemyColliderEnter」関数の最初に「if( isDead == true ) 」のif文を追加します。

処理はまず「Destroy( col.gameObject )」ですでに死亡している場合は、矢をそのまま破棄します。そしてその後の処理を行わない様に「return」します。

「OnDead()」関数でその「isDead」を「true」にします。これで「EnemyBase」を継承している、他の敵スクリプトで死亡時に「isDead」が「true」になります。

これにより死亡が決定した後は再び攻撃処理が動かないようになります。

EnemyCrocodileの攻撃処理を作成する

ではワニの敵「Enemy1」の攻撃処理を作成しましょう。主に近寄ってきて近距離攻撃をします。

アニメーションイベントの設定

攻撃アニメーションを実行していく前に少し必要なことがあるのでやっていきましょう。

攻撃アニメーションである「Assets/AppMain/Animator/Croc/Attack(2)」をダブルクリックしてください。すると「Animation」ウインドウが開きます。(Animatorウインドウではなく粒々がたくさんあるウインドウです)

まずは一番上の時間が書いてある部分をクリックして、カーソルを最後(一番右)に置いておいてください。

そして名前の右横にある一番右のボタン(太めの縦棒に+マークのAdd Event)を押します。するとカーソルのある部分にアニメーションイベントが作成されます。

作成されたら、その縦棒を選択してInspectorをみてください。「AnimationEvent」という項目になるので、この「Function」に「Anim_AttackEnd」と入力して下さい。

これで、「Attack(2)」アニメーションの最後のタイミングになった時に「Anim_AttackEnd」というアニメーションイベントが実行されるようになります。しかしこれだけでは「アニメーションイベントを実行するためのスクリプトがないよ」みたいなエラーになってしまうので、このイベントを受け取らないといけません。

受け取るには、このアニメーションが実行されているGameObjectと同じGameObjectに「Anim_AttackEnd」という関数をもったスクリプトを付与する必要があります。

同じ、と言うところが重要で今回アニメーションを実行している(Animatorがあるもの)のは「Monster_X_Green」です。なのでここに受け取る処理を作成します。

では新しくスクリプトを作成し「EnemyAnimationEventReceiver」と言う名前にしましょう。考え方は「ColliderCallReceiver」と同じです。

まず「using UnityEngine.Events;」を忘れずに追加しましょう。

そして「public UnityEvent AttackEndEvent」を用意します。これでInspectorでイベントを設定できるようにします。

次に先ほどアニメーションイベントとして追加したものと同じ名前の関数「Anim_AttackEnd」を作成します。名前が違うと実行されないので注意してください。

処理は「AttackEndEvent?.Invoke();」でイベントを実行しているだけです。

ではこの「EnemyAnimationEventReceiver」を「Monster_X_Green」に付与してください。

FPSゲームの必須機能である敵の攻撃処理を作る

準備ができたので、「EnemyCrocodile.cs」に処理を追加していきます。 

EnemyCrocodile.csに敵を攻撃するC#スクリプトを追加する

変数は「isAttacking」という攻撃中のフラグを用意します。

次に「SetNext()」関数、つまり次の目的地を決める関数の最初「toAttack == true」で「return」していますが、そこにさらに「isDead == true」でも「return」するようにします。

さらに「else if( navMeshAgent.isStopped == true )」の部分。処理は「navMeshAgent.isStopped = false」以外はifの部分と同じです。これは「攻撃をする」という行動が加わることで、移動が停止のまま近くにプレイヤーもいない状態になってしまうのを防ぐための処理です。

「OnNeighborhoodTriggerExit()」関数の追加です。この関数は敵の周辺検知コライダーからプレイヤーが出て行った時の処理です。追加部分は「isAttacking = false」で攻撃中フラグを「false」にします。

続いて「ToAttack()」関数に追加します。追加部分は「if( isDead == true ) return」で死亡時には実行しない処理を追加したところと、「if( dis < 4f )」の中の処理です。

後半の追加部分だけ抜き出します。

最初に「anim.SetTrigger( “Attack” )」でアニメーションの「Attack」トリガーを実行します。これで攻撃アニメーションを始めます。

残りはプレイヤーの方向を向く処理です。「targetTransform」に「targetPlayer.transform.position」つまりターゲットの位置を保管します。そしてそのYの値を「gameObject.transform.position.y」に合わせます。これは敵自身の高さでのプレイヤーの方向を求めています。

次に「dir」に「( targetTransform – gameObject.transform.position )」でプレイヤーの位置から自身の位置をひいて、それを「normalized」して正規化(大きさ1にする)した方向を求めます。

Vector3.normalized : Vector3を正規化、大きさを1にする。

そしてその値を「transform.forward」にいれて正面を求めた方向に合わせます。最後に「isAttacking」を「true」にして攻撃中の状態にします。

transform.forward : 正面方向(LocalのZ軸+方向)

これで、近づいたら攻撃をするようになりました。

続いて関数を新しく2つ追加します。

まずは、「StartCoroutine( AttackWait() )」のみの「OnAttackEnd()」関数を作成します。これは、後ほど「EnemyAnimationEventReceiver」に登録するための関数です。

こちらはコルーチンで最初に「yield return new WaitForSeconds( 2f )」で2秒待機します。その後「isAttacking」と「toAttack」を「false」にします。

ここの処理は一回攻撃をして、次の攻撃までの待機時間のための処理です。

InspectorでEnemyAnimationEventReceiverにイベントを登録

ではイベントを登録します。

「Monster_X_Green」の「EnemyAnimationEventReceiver」で「+」ボタンでイベントを追加して、「Enemy1」をドラック&ドロップします。そして関数は「EnemyCrocodile.OnAttackEnd」を選択します。

一旦再生して確かめよう

では一旦再生してみましょう。

敵に近づくと、寄ってきて攻撃してきます。そして離れない限りそこで攻撃を続けます。離れるとまた周回位置に戻ります。

まだ攻撃がプレイヤーに当たるようになっていませんので、次はそこを作成していきましょう。

FPSゲームにおける敵の攻撃のヒット・当たり判定を作ろう

ここからは敵の攻撃の当たり判定を実装します。

 

AttackPoint、AttackSphereの作成

まずは「Enemy1」の子に空オブジェクトを作成し「AttackPoint」という名前にします。

次に「AttackPoint」の子に「Sphere」を作成し「AttackSphere1」と言う名前にします。「AttackSphere1」のTransformはPosition、Rotationを「0」にしておきます。

そして、「AttackPoint」「AttackSphere1」の「Transform」を下記のように設定します。

続きを読む

このコンテンツはパスワードで保護されています。 コンテンツを読みたい方はUnity入門の森ショップ(https://unityforest.stores.jp/)で講座閲覧権を取得してね。

次回に向けて

今回はここまでにしましょう。

ここまでで敵の攻撃当たり判定、攻撃アニメーション、近距離攻撃、遠距離攻撃を実装しました。

また、移動やプレイヤーの自動追尾機能との切り替えを行えるようにし、実践的な敵AIに仕上がりました。

次回は現在配置している敵を増やして自動生成していきます。

次回の記事 : 

FPSゲームの作り方10 Unityで指定したスポーン位置に敵を自動生成する
本講座では、UnityとC#を用いて3DFPSゲームを作成しています。今回は第10回です。 前回までで敵の攻撃処理を作成しました。アニメーション・当たり判定・遠距離攻撃も作成したので、敵の一連の行動AIはできあがりです。 前回の記事...

 



Unity入門の森オリジナル本格ゲーム制作講座はこちら
8種類の本格ゲームの全ソースコード公開・画像&動画による解説付き

コメント

タイトルとURLをコピーしました