Unityでコライダ1つだけでダメージ箇所を特定する

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

今回はUnityのゲームで敵キャラクターがダメージを受けた場所によってアニメーションを変更してみたいと思います。

あれ?これなら以前の記事でやったじゃん!(ー_ー)!!

というわたくしのブログを念入りに見てくれている方もいるかもしれません。

以前の記事

Unityの敵キャラの当たり判定を細かくしてよりバイオっぽくする
Unityの敵キャラの当たり判定を細かくして、部位毎に攻撃出来るようにしていきます。
敵にダメージを与えた時、部位によってアニメーションを変える
Unityのゲームで敵に攻撃を与えた時、与えた場所によって敵のダメージアニメーションを変更します

の記事ですね。

体の部位によってコライダを複数設置し細かく判定出来るようにしました。

しかし今回やるのはコライダを複数設置するのではなくキャラクターの移動に使うCharacterControllerやCapsule Collider1つでどこにダメージを受けたか判定していきます。

細かい当たり判定を必要とせず大ざっぱな当たり判定だけでいいけどダメージを受けた場所だけは把握したい時もありますよね?

そんな時の為にコライダ1つだけでダメージを受けた場所を把握出来るようにしておきます。

スポンサーリンク

ダメージを与える敵キャラクターの準備

まずはダメージを与える敵キャラクターを準備します。

敵キャラクターのインスペクタ

敵キャラクターのモデルにCharacterControllerを取りつけコライダのサイズを調整します。

敵キャラクターをキーボードで動かせるようにキャラクターにはスクリプトを取りつけています。

キャラクター移動のスクリプトに関しては今回はダメージを与える場所を変える為に使用するだけなのでキャラクターを動かせれば問題ありません。

キャラクターの移動に関しては

Unityでキャラクターの移動をプログラミングしてみる
Unityで3Dキャラクターモデルを配置し、キャラクターをCharacterControllerの機能を使って移動させるようなプログラミングをしてみます。

ここら辺りを見てください。

敵キャラクターを設置した画像

↑が敵キャラクターを床の上に設置した様子です。

コライダのサイズを大きくして確認する時にわかりやすくしておくのもいいかもしれません。

また敵キャラクターのLayerにはEnemyを設定しておいてください。

敵キャラクターのAnimatorを作成する

敵キャラクターのAnimatorに設定するAnimator Controllerを作成していきます。

Animator Controllerの作り方や設定に関しては

Unityのアニメーションの切り替えシステムとスクリプト
Unityのアニメーションの切り替えシステムであるAnimatorControllerの設定とスクリプトからアニメーションを制御していきます。

を参照してください。

新しくAnimator Controllerを作成しアニメーションパラメータに

ダメージ用Triggerを作成

↑のようにFloat型のSpeedとTrigger型のDamageForwardRight(前の右側)、DamageForwardLeft(前の左側)、DamageBackRight(後ろの右側)、DamageBackLeft(後ろの左側)のパラメータを作成します。

ダメージ用Animatorの遷移を作成する

それぞれの状態を作成し、その場所に攻撃を受けた時にアニメーションが遷移するようにし条件を設定します。

今回はサンプルなのでAny State(どの状態からでも)からMake Transitionをしてそれぞれの条件がトリガーされたら遷移するようにしておきます。

それぞれのダメージ状態からはExitに遷移をさせHas Exit Timeにチェックを入れておきます。

Has Exit Timeにチェックが入っていればダメージアニメーションが終了したらExitにながれEntryへと遷移します。

敵を攻撃するスクリプトを作成する

次に敵を攻撃するスクリプトを作成していきます。

このスクリプトが敵のコライダのどの部分を攻撃したかを判定します。

ヒエラルキー上で右クリック→Create Emptyを選択します。

空のゲームオブジェクトを追加

↑のようにGameObjectという空のゲームオブジェクトを作成し、そこに敵をクリックした時に攻撃(コライダの情報を取得)するスクリプトを作成し取りつけます。

Main Camera等に設定しても構いません。

マウスの左ボタンを押したらカメラからマウスを押した場所にレイを飛ばしEnemyレイヤーが設定されたコライダと接触したかどうかを調べています。

で接触したコライダのゲームオブジェクトからAnimatorコンポーネントを取得し変数に入れています。

実際のゲームの場合は敵キャラクターのAnimatorの操作は敵キャラクターに設定したスクリプトで行うのがいいと思います。

コライダの情報はhitに入っており、hit.pointで接触した位置をワールド座標のVector3の値で得られます。

今回の場合はコライダの中心から見たローカル座標のVector3の値がほしいのでInverseTransformPointを使ってワールド座標からローカル座標に変換しています。

hit.transformでヒットしたコライダのTransformを得られ、そこからhit.point座標分を相対的に移動した位置がInverseTransformPointで得られます。

またコライダの中心座標はhit.collider.bounds.centerで得られるのでそれもローカル座標に変換しています。

コライダの中心位置はInverseTransformPointを使わずにCharacterControllerのCenterをそのまま使っても同じですが、InverseTransformPointの練習の為に計算しました。

コライダの当たった位置は接触した位置(hit.point)とコライダの中心(hit.collider.bounds.center)との位置関係から調べるという事になります。

isForward変数はコライダの中心より前が接触したらtrue、後ろならfalse。
isRight変数はコライダの中心より右ならtrue、左ならfalseを入れます。

ローカル座標に変換した接触位置とコライダの中心位置を使ってコライダのどの部位に接触したかをコンソールに出力しています。

今回の場合は前後、上下、左右で判定するのでコライダの接触した位置は6か所で判定出来るようになっています。

最後にisForwardとisRightを使って前後、左右で敵キャラクターのAnimatorを操作しています。

上下も入れてもよかったんですが、正直なところ分けるだけのアニメーションの用意が出来なくて・・・・(^_^;)

今回設定したアニメーションもダメージアニメーションとは関係ないやつですしね・・・。

敵キャラクターをクリックして確認する

それでは敵キャラクターを動かしたり、クリックする位置を変えたりしてアニメーションやコンソールに表示される文字が変わるかどうか確認しましょう。

ダメージ位置でアニメーションを変えるサンプル

ちょっとわかり辛いですが敵キャラクターのクリックした位置によってコライダの前後、上下、左右のどの位置かを表示し、アニメーションが変わっているのが確認出来ます。

これで1つのコライダでダメージを受けた場所を特定する事が出来るようになりました。

本来であれば敵キャラクター側から見て前方左の上を攻撃されたとすれば頭を右に傾けるようなアニメーション。

前方左の下を攻撃されたら前につんのめるようなアニメーション。

後方左の上を攻撃されたら右前に倒れるようなアニメーション。

というように設定すると受けた場所によってアニメーションを変える事が出来ると思います。

今回はCharacterControllerのコライダを使って判定していますが、Coliiderを継承しているCapsule ColliderやSphereCollider等もboundsを持っているので、

同じようにコライダの中心からの接触位置を判定出来ます。

あ・・・YouTubeにチャンネル作ったのに動画をアップロードしなかった・・・(-_-)

レイを使わない場合の判定

ここまではレイを使って接触した位置がコライダの中心からローカルのどの位置にあるかで判断していますが、

主人公が剣を振った時にコライダのどの位置と接触したかを判断したい事もあります。

剣にAttackSwordスクリプトを設定します。

↑の例ではEnemyスクリプトのTakeDamageメソッドにダメージ数と剣の位置と接触したコライダの一番近い位置を渡しています。

TakeDamageメソッド内でダメージエフェクトをインスタンス化し、接触した位置に表示する事が出来るようになります。

↑で剣の位置(transform.position)と一番近い接触したコライダ(この場合敵の当たり判定のコライダ)のBounds(コライダを囲む四角形)の一番近いポイントが得られます。

こうすることで銃を撃った時にレイを使った接触位置だけでなく、剣で攻撃した時の接触位置も取得する事が出来ます。

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