Unityのアクションゲームで与えたダメージを与えた場所にUIで表示する

主人公が敵に攻撃を与えた時に

Unityで敵キャラクターのHPを頭上に表示するUIを作成
Unityで敵キャラクターのHPを表すUIを頭上に表示してキャラクターと一緒に移動するようにします。

で敵のHPのメーターを減らすという事をしました。

今回は敵のHPのメーターを減らすのではなく敵に与えたダメージを表示するようにしてみます。

また、敵が攻撃を受けた体の部位にダメージのUIを表示するようにし、UIを上の方に動かしながら段々見えなくなるようにし、ダメージUIの表示が邪魔にならないようにします。

スポンサーリンク

攻撃を受ける簡易的な敵キャラクターの作成

まずは簡易的な敵キャラクターを作成していきます。

ダメージUI1

上のようにヒエラルキーで右クリック→Create Emptyで空のゲームオブジェクトを作成し、名前をKakasiとします。

Kakasiの子要素にヒエラルキーで右クリック→3D Objectで頭、体、右手、左手、右足、左足をSphere、Capsuleで作成します。
それぞれ名前をHead、Body、RightHand、LeftHand、RightFoot、LeftFootとします。

簡易的な敵キャラクターはご自由に作成してください。普通の人型3Dオブジェクトを使用し、コライダを分けて作成してもOKです。

ダメージUI2

KakasiにはAdd Component→Physics→Capsule ColliderとPhysics→Rigidbodyを取りつけます。
Capsule ColliderはKakasiキャラクターが移動する時の接地を確認する為のコライダです。

人型キャラクターには今回のようにCapsule Collider(何らかのコライダ)とRigidbodyを取りつけるか、Character Controllerを取りつける必要があります。

このどちらかが取り付けられていないと、武器の接触イベントが発生しない為です。
また、新しくDamageスクリプトを作成し取りつけておきます。

ダメージUI3

上がKakasiの子要素のBodyのインスペクタです。

Enemyという新しいタグを作成し、Bodyのタグを変更します。
またコライダはIsTriggerにチェックを入れ攻撃が当たったかどうかの判定のみに使用します。

Kakasiの他の子要素も同じようにタグをEnemyに設定し、コライダのIsTriggerのチェックを入れておきます。

ダメージUI4

上が出来上がった敵キャラクター「かかし君」です。
人型キャラクター全体を覆うCapsule Colliderと体の部位ごとにコライダが設定されています。

ここで作成した「かかし君」はその場に立っているだけにしておきます。

ダメージを表示するUIの作成

次にダメージを与えた時に表示するダメージUIを作成していきます。

ダメージUI5

ヒエラルキーで右クリック→UI→Canvasでキャンバスを作成し、名前をDamageUIとします。
子要素に右クリック→UI→Textとしダメージ用のテキストを作ります。

ダメージUI6

RectTransformのScaleを調整してUIの大きさを変更します。
WidthやHeightをいじらない方がいいです。

DamageUIのインスペクタのCanvasのRender ModeをWorld Spaceに変更し、
Add Componentから新しいスクリプトRotateDamageUIとMoveDamageUIを作成し取りつけます。

Render ModeをWorld Spaceに変更するとUIが他のゲームオブジェクトと同じように扱う事が出来ます。

RotateDamageUIスクリプトはカメラの方にUIを向けるスクリプト、MoveDamageUIはUIを移動するスクリプトです。
これらは後で作成します。

ダメージUI7

DamageUIの子要素のTextには初期テキストとして100を設定し、Add ComponentからFadeOutTextスクリプトを作り設定します。
このスクリプトは後で作成します。

ダメージUI8

上が出来上がったダメージ用UIです。

「かかし君」の辺りに表示されていますが、これはかかし君のサイズとUIのサイズを合わせる為です。
ダメージUIを表示する位置はスクリプトで行うので位置を厳密に設定する必要はありません。

DamageUIが出来上がったらAssetsエリアにドラッグ&ドロップをしてプレハブ化しておきます。

回転させるRotateDamageUI、動かすMoveDamageUI、テキストを消していくFadeOutTextの作成

次に先ほど登場したRotateDamageUI、MoveDamageUI、FadeOutText等のダメージUI関連のスクリプトを作成していきます。
まずはRotateDamageUIを作成します。

RotateDamageUIスクリプトはDamageUIゲームオブジェクトをカメラの方向と同じ角度にして常に真正面から見えるようにします。
Camera.mainとすると今使用しているメインのカメラを表します。

他のカメラを使う場合はCamera型の変数にカメラを設定すればそのカメラの角度に合わせる事が出来ます。

次はMoveDamageUIです。

現在の位置に1秒間にVector3(0, 0.4, 0)分だけ足した位置に移動します。

DamageUIが出ている間は上向きにDamageUIが移動していくようになります。
昔のファイナルファンタジー風?(覚えていないけれど・・・)ですかね

次はFadeOutTextスクリプトを作成します。

DamageUIのテキストを少しづつ透明にする処理です。
Colorは

Color(R, G, B, A)

でRはRed、GはGreen、BはBlue、AはAlphaをfloatで指定します。
つまり白はColor(1, 1, 1, 1)で黒はColor(0, 0, 0, 1)、青はColor(0, 0, 1, 1)となります。

つまりFadeOutTextスクリプトでは赤色のテキストのAlpha値を小さくしていき、1秒後に透明になるようにしています。

DamageUIを登場させるDamageスクリプトの作成

次は「かかし君」に設定したDamageスクリプトを作成します。

publicでdamageUIを宣言し、インスペクタでDamageUIプレハブを設定出来るようにしておきます。

Damage関数内ではDamageUIのインスタンスを作成しますが、この時に表示する位置は武器が接触したコライダの中心からカメラ方向に20cm寄せた位置になります。

これは武器が接触した体に設定しているコライダの所に表示する為です。
少しカメラよりに移動させているのは、ダメージUIがちゃんと見えるようにする為です。

表示したDamageUIは1秒後に破棄するようにします。

次に主人公の武器が「かかし君」に当たったかどうかの処理ですが、この辺りの処理は

Unityで主人公キャラが敵を攻撃出来るようにする機能
Unityで主人公キャラが剣を振って敵キャラを攻撃出来るようにする機能を作成します

を参考に作成してください。
アニメーションイベント、コライダのOn・Offの機能を作成しておいてください。

武器が敵に当たった時の処理スクリプトMyAttackの作成

主人公が装備している武器にコライダを設定しIsTriggerにチェックを入れます。
武器にMyAttackという新しいスクリプトを取りつけます。

武器のコライダが他のコライダと接触した時にOnTriggerEnterイベントが発生するので、
接触した相手がEnemyタグを設定したコライダであった時にそのコライダのルート(Kakasi)に設定してあるDamageスクリプトのDamage関数を呼び出します。

その際に接触したコライダの情報も渡します。

ダメージUIが正しく動作するか確認してみる

これで機能が出来たので主人公で「かかし君」を攻撃しダメージが表示されるかどうか確認してみましょう。

ダメージUI9

上のようにうまくいきました。

敵キャラクター「かかし君」を動かすとずれる

「かかし君」を少し動かしてみましょう。

上のようなスクリプトをKakasiに設定します。
X軸を行ったり来たりするようになります。

ダメージUI10

「かかし君」が動き出した事で上のようにDamageUIと「かかし君」との位置がずれてしまいます。

こういう仕様でいいという人はいいんですが、DamageUIも「かかし君」とともに動かしたい方もいると思います。
その為にDamageスクリプトを修正します。

DamageUIを「かかし君」の子要素にする

DamageUIを作成した時に親要素をDamageスクリプトが設定されているゲームオブジェクトにします。
この場合はDamageUIの親要素がKakasiに設定されるようになります。

DamageUIは「かかし君」の子要素なので、「かかし君」が移動するとDamageUIも一緒に動くようになります。

それではUnityの実行ボタンを押して確認してみましょう。

ダメージUI11

上のようにDamageUIがKakasiと共に動くようになりました。

これでUnityのアクションゲームで与えたダメージを与えた場所にUIで表示する機能が完了しました。

本機能とは関係なく当たり判定で気になる事

今回の機能を作成していて武器と敵の接触判定は気をつけなければいけないなと思いました。
剣を振るアニメーションが速いと敵との接触判定(OnTriggerEnter)がスルーされる事が多いです。

アニメーション再生スピードを落とせば問題はないんですが・・・、
見た目的に武器が敵に当たっているのに当たり判定がされない!?という状況になってしまう可能性もあります。

当たり範囲のコライダを大きくしたりアニメーションのスピードを下げたりして回避するのがいいのかな?
ここら辺もうまく出来るようにしなきゃいかんですね(-.-)