この記事はFPSゲームの作り方講座の第8回目です。空を飛ぶ敵のAIを作成していきます。
前回はNavMeshを使って敵の移動処理、そしてNavMeshObstacleを使って敵が障害物を避ける処理等を作成しました。
前回の記事:
今回は空を飛んでいる敵の移動処理を作成していきます。地面がないことにより障害物もそれほど多くないため、スクリプトで移動させても良いです。
が、よりわかりやすく移動できるように今回は別の方法、具体的にはCinemachineを使って移動処理を作成していきます。
また、敵飛行ユニットは移動後に、周回を一旦中断して攻撃のための移動や停止などを行えるようにしていきます。複数の行動を実現できる敵AIを作成していきましょう。
では始めます。
Cinemachineを使って飛行ユニットの敵を周回移動させる
今回は「Cinemachine」というパッケージを使用して、敵をあらかじめ決められたルートをひたすら周回するようにしていきます。
「Cinemachine」は「PackageManager」から簡単に導入でき、名前の通り本来は動画や映画的のカメラワークを作成するようなものですが、それを利用していきます。
「Cinemachine」の導入
まず、Unity上部のメニュー「Window/PackageManager」を開きます。
パッケージマネージャーで「Cinemachine」を探して「Install」を押せば完了です。
EnemyBatの移動処理を作成しよう
では、作成していきましょう。移動処理を作成するのは「EnemyBat」です。
まず、Unity上部メニューの「Cinemachine」を開いて「Create Dolly Track with Cart」を選択します。似たような文字がたくさんあるので間違えないように気をつけてください。
(追記:2021以降のバージョンでは「Cinemachine」は上部メニューの「GameObject」の中にあります)
すると「DollyTrack1」「DollyCart1」が生成されます。この2つで1セットとなります。
次に「DollyTrack1」「DollyCart1」を、「EnemyBat」の子に移動します。
そして「DollyTrack1」のTransformでPositionとRotationをすべて「0」にしておいてください。
さらに「DollyCart1」の子に「Bat_Red」を移動します。この「Bat_Red」のTransformもPosition、Rotationを「0」にしておきましょう。まずはここまでのInspector下記をもとに確認してください。
Pathの設定をして飛行ルートを作る
次にPath(移動経路、パス)を設定していきます。
「DollyTrack1」を選択してInspectorの「CinemachineSmoothPath」を見てください。ここに「Waypoints」というリストがあります。これが移動経路のポイントです。
「+」ボタンを押して試しに2つほど増やし計4つにして、値を下記のように設定してみましょう。そして「DollyTrack1」を選択した状態でSceneウインドウを見てみましょう。
線路のような緑色の線と番号があるのが分かります。この番号が先ほど「Waypoints」で設定した位置で、それを0から順に自動的に繋いで線路が描かれています。
この線路上を「DollyCart」が動くのがこの「Dolly Track with Cart」の機能です。では試しに動かしてみましょう。
再生しても移動設定をしていないのでゲーム画面ではまだ動きません。「DollyCart1」を選択して、Inspectorの「CinemachineDollyCart」を見てください。
この一番下の「Position」という値を変更してみましょう。すると敵(Dollycart)が線路にそって移動しているのがわかると思います。
つまりこの「Position」の値をスクリプトで変更していくことで敵を移動させることができます。
またその上の「Speed」と言う値に数値を入れると、速度を設定しているということになり再生時には勝手に動き出します。
この「Speed」に値を設定して実際に動くことを確かめてみましょう。この後C#スクリプトで値を設定するので確かめた後は「0」にしておきましょう。
ここまでの結果を踏まえてPathを作成していきます。細かく決め打ちする必要もないので下記を参考にご自由に配置してみてください。ただし、1周してまた最初から動き始められるように、最初の位置はXYZ全て「0」、最後の位置もXYZ全てを「0」にしておいてください。
(画像では最初は「0」と最後は「7」です。)
ちなみに「Waypoints」という項目の1つ上の「Path Length」というのは経路全体の距離を表しています。後で使用するので覚えておきましょう。
スクリプトの記載
ではスクリプトで移動処理を作成していきましょう。
EnemyBatの攻撃処理作成
次は空を飛んでいるコウモリの方を作成しましょう。
コウモリは「Cinemachine」で移動しているので、先ほどとは少し違ってきます。またワニとは違いプレイヤーに向かってくるのではなく、攻撃範囲に入ったら遠距離攻撃をするようにしていきましょう。
コライダーの作成
まずは「NeighborhoodSphere」を作成しますが、ここで注意です。
作成するのは「EnemyBat/DollyCart1/Bar_Red/RIG/Bat1Control」の子に作成するようにしてください。
6章で敵のコライダーを作成するときにもここにコライダーを付けました。その際はまだアニメーションの設定をしていなかったので詳細は解説しませんでしたが、この段階で解説します。
まずは一旦再生してみて、再生中に「EnemyBat」の子にあるゲームオブジェクトのInspectorのTransformを見てみてください。
「EnemyBat」を見ると特に変化はしていません。変化していないというのは移動も回転もしていないということです。
経路上を移動しているのは「EnemyBat」ではなく「DollyCart1」です。数値が変化しています。
これはCinemachineによる移動の動きです。つまり、Chinemachineがアタッチされているオブジェクトの親は動かないということです。このため、移動しているDollyCart1の子オブジェクトとして「Bat_Red」を配置しています。
そして、それとは別にBat_Red>Rigの子にある「Bat1Control」も再生中に数値が変化している(動いている)のが分かると思います。この「Bat1Control」の動きは羽ばたいているアニメーションによる動きで少し上の方で上下しています。
そのため、ここに敵のコライダーをつけ、さらに周囲検知のための「NeighborhoodSphere」はこの「Bat1Control」の子に作成することで、アニメーションしているコウモリの目に見える部分のゲームオブジェクトとコライダーの動きを合わせることができます。
コライダーの「IsTrigger」を「true」に「MeshRenderer」を無効化して見た目を消すのも忘れないようにしましょう。大きさはScale「0.5」くらいで。(親のBat_RedのScaleが大きいためここでは逆に小さくする必要があります。)
そして「NeighborhoodSphere」に「ColliderCallReceiver」を付与、Rayが当たらないようにレイヤーを「Ignore Raycast」に設定しておきましょう。
プレイヤーを検知して移動を停止する処理を作成
では、ワニの時は近づいてきましたが、今度は範囲内に入ったら移動を停止するように処理を作成していきます。
変更は「EnemyBat.cs」です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
public class EnemyBat : EnemyBase { ・・・ // 戦闘体制フラグ. bool toAttack = false; // ターゲット. GameObject targetPlayer = null; ・・・ // --------------------------------------------------------------------------------- /// <summary> /// 周辺コライダーステイコールバック. /// </summary> /// <param name="col"> 侵入したコライダー. </param> // --------------------------------------------------------------------------------- public void OnNeighborhoodTriggerStay( Collider col ) { if( col.gameObject.tag == "Player" ) { Debug.Log( "Neighborhood Trigger In Player" ); targetPlayer = col.gameObject; ToAttack(); } } // --------------------------------------------------------------------------------- /// <summary> /// 周辺コライダーから出て行った時のコールバック. /// </summary> /// <param name="col"> 出て行ったコライダー. </param> // --------------------------------------------------------------------------------- public void OnNeighborhoodTriggerExit( Collider col ) { if( col.gameObject.tag == "Player" ) { Debug.Log( "Neighborhood Trigger Exit Player" ); targetPlayer = null; dollyCart.m_Speed = moveSpeed; } } // --------------------------------------------------------------------------------- /// <summary> /// 攻撃体制. /// </summary> // --------------------------------------------------------------------------------- void ToAttack() { toAttack = true; dollyCart.m_Speed = 0; } } |
同じような処理も多いので、軽く解説します。
変数は同じで「toAttack」と「targetPlayer」です。
そして、周辺検知コライダーのトリガーイベントに登録する「OnNeighborhoodTriggerStay」「OnNeighborhoodTriggerExit」を作成します。
「OnNeighborhoodTriggerStay」は全く同じでコライダーのタグが「Player」の時に、「targetPlayer」に保管して「ToAttack()」関数を実行します。
次に「OnNeighborhoodTriggerExit」は、似たような処理ですがコライダーのタグが「Player」の時に、「targetPlayer」を「null」にして、「dollyCart.m_Speed = moveSpeed」で「Cinemachine」のスピードを設定します。
これは「0」にしたものを元に戻すための処理です。その「0」にするのが「ToAttack」関数です。
1 2 3 4 5 |
void ToAttack() { toAttack = true; dollyCart.m_Speed = 0; } |
「ToAttack」を「true」にして、「dollyCart.m_Speed = 0」でスピードを「0」にしています。「Cinemachine」はこれだけで移動を停止できます。
ではInspectorで関数を登録します。
「OnNeighborhoodTriggerStay」を「TriggerStayEvent」に、「OnNeighborhoodTriggerExit」を「TriggerExitEvent」に登録します。
一覧のうち一番上にある引数を持つ関数の方ですので間違えないようにしましょう。
では、再生してみてみましょう。コウモリに近づいて、近くによると移動をやめてその場で停止するようになりました。この停止時にプレイヤーに遠距離攻撃をするように作成していきます。
長くなったので今回はここまでにします。
次回は実際に攻撃してプレイヤーにダメージを与えられるようにしていきましょう。
次回の記事:
コメント