Unityのアクションゲームで攻撃時に敵の方向をむかせる機能

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

今回は主人公キャラクターが武器を構えた時に一番近い敵の方向を向くようにします。

今まではユーザーが主人公キャラクターを操作し、敵の方向を向かせ、攻撃をしていました。
しかし、もっと単純に武器を構えたら一番近い敵の方向を向かせて、左右の方向キーを押したら別の近い敵にターゲットを変更します。

市販のゲームで言うと昔のバイオハザードみたいな感じになります。
昔のバイオハザードがどんな感じだったか今となってはあまり覚えていないんですが・・・・(^_^;)
あとはSIRENも近いかも!?

今回の機能を作成すると、

↑のような感じで攻撃をする為に構えた時、ターゲットの方向を向かせる事が出来ます。

左右のキーを押した場合は主人公の検知エリア内にいる敵の中から一番角度が近い敵の方向を向いています。

検知エリア内にいる敵でも主人公との間に壁があった場合はその敵はターゲットには設定出来ないようにします。

スポンサーリンク

敵の方向を向く機能の実現方法を考える

まずは機能を実現する為の方法を考えます。

主人公の子要素に敵をサーチするエリアを作成し、そのエリアに入った敵をゲームオブジェクトのリストに保存します。
格納された敵のゲームオブジェクトの中から主人公と一番近い敵を最初のターゲットに設定します。

次に一番近いターゲットを狙っている時に左右の方向キーを押したら別の敵をターゲットにします。

ユーザーが左の方向キーを押したら左側、右の方向キーを押したら右側にいる敵を調べ、
主人公から見て一番角度が小さい敵を次のターゲットにします。

敵をサーチするエリアから敵が出た場合はゲームオブジェクトのリストからその敵のゲームオブジェクトを削除します。

敵をサーチするエリアの作成

それではまず主人公の子要素に敵をサーチするエリアを作成していきましょう。

ターゲット選択1

主人公キャラクターの子要素に右クリック→Create Emptyで空のゲームオブジェクトを作成し名前をSearchEnemyとします。
SearchEnemyにインスペクタのAdd Component→Physics→Sphere Colliderを追加します。

ターゲット選択2

コライダは衝突させず検知するだけのエリアとして使うのでIs Triggerにチェックを入れておきます。

Sphere ColliderのRadiusはご自分の好みに合わせて変更してください。
ここで注意しなければいけないのはBox Collider等の角ばったコライダを設定してはいけない事です。

例えばBox Colliderをキャラクターに設置した場合、キャラクターが回転している間に敵がサーチエリアを出てしまうからです。
Sphere Colliderならば回転している間も範囲から外れる事がないので大丈夫です。

また敵をサーチするSearchEnemyスクリプトを新しく作り設定します。

ターゲット選択3

上がSphere Colliderの範囲です。
Sphere Colliderは上の画像のように丸いのでキャラクターが回転中も敵が範囲外に出る事はありません。

ターゲットを選択するスクリプトSearchEnemyの作成

それではターゲットを選択するスクリプトSearchEnemyを作成していきます。

スクリプトが長いので細かく見ていきます。

フィールド宣言とStartメソッド

enemyListsとnowTargetをSerializeFieldアトリビュートを付けて宣言したのはUnityの実行中に値を確認する為です。

enemyListsはリストを使い主人公の検知エリア内にいる敵を登録したり削除したりします。

StartメソッドではListのオブジェクトの作成と現在のターゲットであるnowTargetの初期化、キャラクター操作スクリプトの取得をしています。

UpdateメソッドとTargetOthersメソッド

UpdateメソッドはTargetOthersメソッドを呼び出しているだけです。

TargetOthersメソッドでは主人公が攻撃の為に構えている状態で左右のキーを押した時に検知エリア内にいる別の敵をターゲットに変える処理です。

最初に検知エリア内にいる敵がいなければターゲットを設定する事は出来ない為、returnでそれ以降の処理はしません。

次に主人公が攻撃をする為に構える状態でない、またはターゲットを変更する為回転中、左右のキーを押していない時もreturnでそれ以降の処理はしません。

それらの条件を抜けた場合は敵のリストに登録されている敵を調べます。

調べている敵がすでにターゲットである時、またはその敵にレイを飛ばして間に壁があった場合はcontinueでそれ以降の処理を飛ばし次の敵を調べます。

人型キャラクターの基底値は足元になっているので、Vector3.upを使って1mだけ上に移動した位置からレイを飛ばします。

これはDebug.DrawLineでレイを視覚的に確認出来るのでどこからどこにレイを飛ばしているか確認してください。

ターゲット選択4

Unityの実行中にレイを確認するにはGizmosを有効にすると確認出来ます。
(Gizmosの右の下矢印を押すと視覚化するものを選択出来ます)

主人公の位置にVector3.up(Vector3(0, 1, 0))を足した位置からサーチエリア内にいる敵の位置+Vector3.upの位置にレイが飛んでいます。

主人公の向いている方向と敵の方向から角度を求めます。

主人公と今調べている敵の角度と、主人公と今のところ一番角度が小さい敵の角度を求めています。

次に左右のどちらのキーを押したかで処理を分岐させます。

主人公が見ている方向から左側は-180~0、右側は0~180が角度として返ってくるので、その値を使って向いている方向から一番近い敵を探します。

左のキーを押している時でtargetAngleが-180から0の間の場合と、右のキーを押している時でtargetAngleが0から180の間の場合のみターゲットにします。

今見ている敵との角度と今のところ一番角度が近い敵を調べ、今見ている敵の角度の方が近かったらその敵をnearTargetに入れます。

Mathf.Absで絶対値が求められます。

敵検知などのメソッド

後は敵を検知するメソッド等をみていきます。

OnTriggerStayメソッドで検知エリアに入った敵を調べ、enemyListsに登録します。

OnTriggerExitメソッドでは敵が検知エリアから出て行った時にnowTargetに設定されていれば解除し、enemyListsから削除します。

SetNowTargetメソッドはキャラクター操作スクリプトから呼び出し、現在のターゲットを設定します。

これでターゲットを指定するスクリプトが完成しました。

キャラクター操作スクリプトの作成

次はキャラクター操作スクリプトを作成します。

この記事用にRotateEnemyCharaスクリプトを作成しました。

長いので一部説明していきます。

キャラクターの状態がノーマル状態の時にFire2ボタン(デフォルトではマウスの右クリック)を押したらSearchEnemyスクリプトのSetNowTargetメソッドを呼び出し、ターゲットの設定をします。

その後、攻撃をする為に構える状態へと変更します。

攻撃をする為に構えている状態の時は

SearchEnemyスクリプトのGetNowTargetでターゲットがいる場合は回転中フラグをオンにし、キャラクターのY軸の角度を変更します。

主人公のY軸の角度とターゲットのY軸の角度がロック解除をする角度以下になったら回転中のフラグをオフにします。

ターゲットにする敵を変更出来るか確認する

これで処理が出来たので確認してみましょう。

攻撃時に敵の方向を向かせるキャラクター操作スクリプトの設定

上のように設定しました。

ターゲット選択6

上のように左右の方向キーを押すとターゲットにする敵を変更します。

が、これだと人の下に回転盤でもあるかのようにクルッと回転してしまうので、ターゲットに向けて回転している間は
下半身のアニメーションを足踏みのものに変更しましょう。

体の一部のアニメーションを変更して違和感をなくす

体の一部のアニメーションを変更する方法は

Unityのレイヤー、アバターマスクを使って体の一部分を別のアニメーションにする
Unityで体の一部分だけ別のアニメーションに変更したい場合はAnimatorControllerのレイヤーとアバターマスクを使う事で実現出来ます。

を参照してください。

ターゲット選択7

上のようにLower Layerという名前でアニメーターのレイヤーを作成します。

ターゲット選択9

Assetsフォルダで右クリック→Create→Avatar Maskを選択し名前をLower Avatarとし、インスペクタで上のように設定します。

ターゲット選択8

Lower Layerの右の歯車を押して、上の画面を開きLower Avatarを設定します。
Weightは1に設定しておきます。

ターゲット選択10

Lower Layerの状態遷移を上のように作成します。
あ・・・名前を変更するのを忘れてNew Stateのままになっていますが・・・、Idle等のわかりやすい名前を付けてください。

New Stateのアニメーションクリップは何も設定しません。

Rotate Walkのアニメーションクリップは足踏みをするようなアニメーションを選択します(歩くアニメーションでOK)

アニメーションパラメータにRotateWalkをbool型で作成しておき、RotateWalkがtrueになったらRotateWalkに遷移するようにします。
RotateWalkがfalseになった時にNew Stateに遷移させます。

ターゲット選択11

上がNew State→Rotate Walkの遷移のインスペクタです。

最後にキャラクター操作スクリプトでアニメーションパラメータのRotateWalkのOn・Offの処理を追加します。

↑のようにRotateWalkアニメーションパラメータを操作します。

これで体の一部のアニメーション変更処理が終わったのでUnityの実行ボタンを押して確認してみましょう。

ターゲット選択12

上のように下半身は歩くアニメーションが再生されるようになりました。
もっと細かく作りたい場合は左向きに回転する時、右向きに回転する時のアニメーションを変更するといいかもしれません。

細かいアニメーション設定をしたい方は

UnityアニメーターのBlendTreeで細かい動作をさせる
Unityのブレンドツリーを使ってアニメーションの切り替えを細かく設定し、向きを変える時の角度によってアニメーションを変更するようにします

を参考にしてください。

これでUnityのアクションゲームで攻撃時に敵の方向をむかせる機能が完成しました。

左右の方向キーを押した時にターゲットを変更する処理が結構大変でした・・・(^_^;)
今回のターゲットの変更の仕方は向いている方向に一番近い敵ですが、方向ではなく一番近い距離にいる敵とする事も出来ます。

その場合は回転でターゲットを選択するのではなく距離で計算する事で実現できますので、やってみてください。

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