Unityで主人公キャラが近づいてきたら追いかける敵キャラを作る

記事内に広告が含まれています。

今回は主人公キャラが敵キャラに近づいたら敵キャラが主人公に近づいてくるようにしたいと思います。

前回、敵キャラクターが見回りをするというスクリプトを組みました。

Unityで敵キャラが見回りをするように動き回るプログラム
Unityのゲームで作った敵キャラクターが見回りをするように、ランダムに設定した位置に移動させる機能を作成します。

まずはスクリプトをどうやって組むか考えてみます。

敵キャラクターに『主人公キャラクターが近づいてきた』、というのがわからなければいけません。

これにはコライダ(接触判定に使う)を使います。敵が持つコライダと主人公キャラのコライダが接触していたら近づいているとします。

コライダの範囲が主人公キャラを検知できる範囲になりますね。

次に敵キャラが主人公キャラクターを追いかける。

というのは敵キャラが移動する目的地を主人公キャラクターの位置に変更すればいいような気がします。

ただ目的地(主人公キャラ)は動くので常に監視し変更しなければいけません。

また敵キャラの検知範囲から主人公が外れた場合は敵キャラはまた見回りに戻る為、新しい目的地を設定するようにします。

スポンサーリンク

敵キャラが主人公キャラを検知する範囲を作成する

まずは敵キャラにコライダを設定します。

敵キャラのボーンの階層の下にSearch Areaという空のオブジェクトを作ります。(右クリック→Create Empty)

敵キャラのボーンの子要素にサーチエリアを作る

Add Component→Physics→Box Colliderを選択しIs Triggerにチェックを入れてください。
(ここではBox Colliderを選択していますが、Sphere Colliderの方がいいです)。

コライダの範囲を修正します。

BoxColliderのIsTriggerにチェックを入れる

Is Triggerにチェックを入れるとスクリプト上で接触の検知は出来ますが、物体としては当たらないようになります。

例えば木などにコライダを設定すると、その部分に侵入は出来ませんが、Is Triggerにチェックを入れると侵入可能となり、木をすり抜けていきます。

主人公キャラクターを検知する範囲

上のような検知範囲を設定してみました。

広く設定されているように見えますが、実際は足音が確実に聞こえる距離までいかないと相手は気づきません。

ゲームオブジェクトにタグを設定する

次に検知範囲に入って来たものが主人公キャラクターであるという判別が必要です。

その為に主人公キャラクターにタグを設定します。

タグはそのオブジェクトがどういう種類に属するかを判別する為のもので、自分で作成する事も出来ます。

主人公キャラにPlayerという元々あるタグを設定してみます。なければAdd Tagで追加してください。

主人公キャラクターにPlayerタグを設定する

タグを追加したので、SearchAreaオブジェクトにSearchCharacterスクリプトを追加し「masasi」君を検知出来るようにします。

サーチエリア(コライダ)に主人公が進入したか調べるスクリプト

SearchCharacterスクリプトはその名の通り検知するスクリプトです。

OnTriggerStayメソッドはスクリプトが設定されているオブジェクトのコライダが他のコライダと接触中に実行されるメソッドです。

そこで接触したコライダが何だったかをタグを使って判定します。

Startメソッドで自身の親に取り付けているMoveEnemyスクリプトを取得します。

OnTriggerStayメソッドでは引数colに接触した他のコライダが設定されるようになります。

接触した他のコライダのタグがPlayerの時に敵キャラが主人公を追いかけるようにすればいいという事になります。

接触したのがPlayerタグが設定されたゲームオブジェクトのコライダだった時で、敵キャラであるゾンビの状態が追いかける状態でなければ追いかける状態にします。

とします。

MoveEnemyスクリプトのGetStateメソッドとSetStateメソッドは後で作るのでここでは置いておいて、
SetStateでは第1引数にEnemyState.Chaseという列挙型を渡し、第2引数にcol.transformで接触したオブジェクトのTransformを渡しています。

特定の値だけ入れる事が出来る列挙型という変数

敵キャラが今どの状態にあるのか?という状態変数stateを宣言し、その状態を表すのに列挙型を使いますが、列挙型は普通の変数とは少し扱いが変わります。

宣言した項目以外の選択をしないようにする事が出来ます。

と宣言し、これを変数などに入れて使います。

C#だと整数型を指定する事が出来るみたいなんですが、JavaScriptだとどうやればいいかわかりませんでした・・。
型を割り当てない時はint型の数値が割り当てられwalkには0、waitには1と順番に数値が割り当てられます。

↑のようにすると

walk
wait
chase

という文字が表示されます。

State内の状態にそれぞれ値を設定する事も出来ます。

↑も同じように

walk
wait
chase

という文字が表示されます。

あらかじめ宣言された値以外をstateに入れるとエラーになるので、特定の値しか入れたくない場合は列挙型が活躍します。

敵キャラクターに状態を表す列挙型と状態変更メソッドの定義

敵キャラクター操作スクリプトのMoveEnemyに状態を表す列挙型と敵キャラクターの状態を取得するGetStateメソッドと状態変更をするSetStateメソッドを定義します。

第1引数で受け取った文字列で分岐させています。それぞれの分岐処理で状態の変化等をしています。

stateに入れている「EnemyState.名前」は列挙型のEnemyStateで宣言されていなければエラーになります。

フィールド宣言とStartメソッド内の追加と変更

フィールド宣言にEnemyStateフィールドとStartメソッド内でSetStateメソッドを呼び出し状態を初期化する処理を入れます。

敵の状態を表すEnemyState型のstateと追いかける状態になった時に追いかけるキャラクターのTransformを入れておくplayerTransformを宣言します。

状態によって処理を分岐させる

次にMoveEnemyスクリプトのUpdateメソッド内の処理を状態によって変更します。

目的地まで歩く処理とキャラクターを追いかける処理は目的地を指定すれば同じ処理を記述する事になるので、追いかける状態である時だけ目的地を再設定し、実際に移動させる処理は同じ処理をしています。

目的地に着いたら、待ち状態に変更します。

待ち状態である時は一定時間その場で待ち、指定時間を超えたら巡回状態(EnemyState.Walk)に変更します。

完成したMoveEnemyスクリプト

ここまで作成したMoveEnemyスクリプトは

となります。

主人公を検知するスクリプトSearchCharacterに追記

MoveEnemy内のスクリプトの記述が終わったので、SearchCharacterに戻ります。

現時点では敵がキャラクターを追いかける状態になったらそのまま一生追い続けます。(^_^;)

そこでSearchAreaに設定したコライダからキャラクターが出ていったら敵キャラクターを待ち状態に変更するようにします。

OnTriggerExitメソッドを追記します。

OnTriggerExitはオブジェクトが接触状態から抜けた時に呼ばれるメソッドなので、その時のオブジェクトのタグがPlayerであったら、敵キャラの状態を待機状態に変更しています。

これで追いかける処理と検知範囲外に出たら見失って一定時間待機し、再度見回りに戻るというスクリプトが出来ました。

簡単なAIではありますが、結構使えると思います。

もっと簡単に敵キャラの移動処理を作るなら

敵キャラをUnityのナビゲーション機能を使って移動させる
Unityのナビゲーション機能を使って敵キャラクターを移動させます。ナビゲーション機能はあらかじめBakeされたフィールドを移動出来る機能です。

を使うと移動処理が簡単になります。

また、ナビゲーション機能を追加した後に

Unityで主人公が敵から隠れた時は追いかけないようにする
Unityのゲームで主人公キャラが壁等で見えない状態で敵の検知エリアに入っても敵は主人公を追いかけないようにします。

の機能を追加するとよりリアルな敵の動きが表現出来ます。

スクリプトがバラバラで解り辛かったので、修正を入れました。

オーバーロード機能は使う必要がなくなったので削除しました。(^_^;)

次回は敵キャラを最初から配置しておくのではなく自動で増やせるようにしたいと思います。

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