Unityでダメージポイント表示のアニメーションを作成する | Unityを使った3Dゲームの作り方(かめくめ)

Unityでダメージポイント表示のアニメーションを作成する

今回はUnityで敵にダメージを与えた時に敵の近くにダメージテキストをただ表示するのではなく、ダメージテキストを一文字ずつアニメーションさせて表示する機能を作成したいと思います。

今回の機能はユニティちゃんのRPGを作ってみようの記事の中で作成したスクリプトで一文字毎のアニメーションをさせるのではなくあらかじめ一文字毎のテキストのアニメーションを作成しておき、それを再生するという流れになります。

ユニティちゃんのRPGで戦闘中のダメージや回復ポイントをキャラクターの周辺にTextMeshProを使って表示し、ポイントがアニメーションをするような機能を作成していきます。

難しいスクリプトを組まなくても済むのでこちらの記事の方が楽です。

今回の機能を作成すると以下のようになります。

今回はいつも使用しているUI→Textバージョンと、3D Object→TextMeshProを使用したバージョンの二つを作成してみます。

上のサンプルはUI→Textバージョンです。

スポンサーリンク

UI→Textバージョンのダメージテキストアニメーションの作成

それではまずUI→Textバージョンの作成をしていきます。

UIの作成

Textの親となるCanvasを作成します。

ヒエラルキー上で右クリックからUI→Canvasを選択し、名前をDamageTextParentとします。

このDamageTextParentがダメージテキストの親となり、その子要素ダメージポイントの各桁のテキストを並べて表示するという形にします。

DamageTextParentゲームオブジェクトを選択し、インスペクタでRectTransformのWidthとHeightを100、ScaleのXYZを0.01とします。

CanvasのRender ModeをWorld Spaceにし普通のゲームオブジェクトと同じように3D空間に表示出来るようにします。

ダメージテキストの親のゲームオブジェクトのインスペクタ

ここまで出来たらDamageTextParentをAssetsフォルダ上にドラッグ&ドロップしてプレハブにします。

次にヒエラルキー上のDamageTextParentを選択した状態で右クリックからUI→Textを選択します。

Textを選択しインスペクタのWidthを30、Heightを50にします。

Font Sizeを40、ParagraphのAliginmentを真ん中、Colorを赤色にします。

ダメージテキストの一文字毎のテキストのインスペクタ

ここまで出来たらTextだけをAssetsフォルダにドラッグ&ドロップしてプレハブにします。

DamageTextParentとTextは単体でプレハブにする必要があるので注意してください。

Textのアニメーションを作成する

次にTextのアニメーションを作成していきます。

ヒエラルキー上のTextを選択した状態でAnimationタブを開きます。Animationタブが開いていない場合はUnityメニューのWindow→Animation→Animationを選択します。

ヒエラルキー上でアニメーションをさせるゲームオブジェクトが選択されていると、AnimationタブにCreateボタンが表示されるので押します。

新しいウインドウが開くのでDamageという名前を付けます。

この時点でAssetsフォルダにDamageアニメーションとTextのAnimatorControllerが作成され、TextにはAnimatorコンポーネントが設定されています。

Animationタブの赤い丸を押し(値等を変更するとキーフレームが打たれる)、0:05フレームに移動し、インスペクタのRectTransformのPosYを40を入力するかシーンビューでマニピュレータを使ってY軸方向に動かします。

するとキーフレームが0:00と0:05に作られます。

Text用のDamageアニメーションの作成

以下のように変更した箇所が赤くなっていればキーフレームが打たれます。

Text用のDamageアニメーションでPosYの値を変更する

次にDamageの所を押し、Create New Clipを選択します。

TextのIdleアニメーションクリップを作成する

名前をIdleとします。

Damageに戻り、0:00フレームを選択してCtrl+Cキーを押してコピーし、Idleの0:00フレームを選択してCtrl+Vキーを押して貼り付けます。

Damageアニメーションクリップを選択してインスペクタのLoopのチェックを外してアニメーションがループしないようにしておきます。

ダメージテキストアニメーションクリップのLoopのチェックを外す

これでアニメーションクリップが出来ました。

アニメーターコントローラーの設定

Assetsフォルダに作成されたTextアニメーターコントローラーを選択し、今度はAnimatorタブを開きます。

AnimatorControllerに関しては

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

等を参照してください。

既に作成されたIdleアニメーションとDamageアニメーションが設定された状態が作成されていればそれをそのまま使っても構いません。

アニメーションパラメーターにTrigger型のDamageを作成します。

Text用のアニメーターコントローラー

Idle状態、Damage状態、End状態を作成し、IdleにはIdleアニメーションクリップ、DamageにはDamageアニメーションクリップを設定します。

Idle→Damageの遷移条件はHas Exit Timeのチェックを外し、Damageをトリガーした時にします。

Damage→IdleはHas Exit Timeにチェックを入れ、その他の条件はなしとします。

次の文字のアニメーションへと移行させるビヘイビアスクリプトの作成

アニメーターコントローラーは一文字毎に設定されており、その文字のアニメーションが終わったら次のアニメーションへと移行させる必要があります。

なのでDamage状態を移動したら次の文字のアニメーションが開始されるようにビヘイビアスクリプトを作成し取り付けます。

Damage状態を選択し、インスペクタのAdd Behaviourボタンを押して名前をEndDamageAnimationという名前にします。

OnStateExitはその状態を抜ける時に呼び出されるのでそこで自身のAnimatorから親の要素を含めてDamageAnimatorスクリプトを取得し、そのAnimateNextCharメソッドを呼んで次の文字のアニメーションへ移行させます。

DamageAnimatorスクリプトは後で作成します。

これでアニメーターコントローラーの設定が終わりました。

ヒエラルキー上のDamageTextParentとその子要素のTextはもう使わないので削除します。

ダメージテキストをインスタンス化するスクリプトの作成

ダメージ用のテキストの親DamageTextParentプレハブとダメージポイントの一桁を表すTextのプレハブが出来たので、次はそれらをインスタンス化する処理を作成します。

今回はサンプルとしてヒエラルキー上にコライダを持つゲームオブジェクトをいくつか置いておいて、それをマウスクリックしたらそこにダメージテキストの親DamageTextParentをインスタンス化するようにします。

ヒエラルキー上のMain Cameraに新しくInstantiateDamagePointスクリプトを作成し取り付けます。

このスクリプト自体はDamageTextParentプレハブをクリックしたゲームオブジェクトの位置にインスタンス化するだけで、通常はダメージを与えた敵の位置等にDamageTextParentをインスタンス化する必要があります。

damageTextParentPrefabにDamageTextParentプレハブをインスペクタで設定します。

Input.GetButtonDown(“Fire1”)でマウスの左ボタンが押されたかどうかが判定されますので、その時にCamera.main.ScreenPointRayメソッドを使って引数で与えたマウスの位置Input.mousePositionにレイを飛ばしその情報をrayに入れます。

Physics.Raycastを使ってrayの位置と方向からレイを1000m先まで飛ばしコライダを持つオブジェクトと接触したらそれがhitにデータが入ります。

damageTextParentPrefabをオブジェクトと接触した位置と、カメラの角度にしてインスタンス化します。

インスタンス化したゲームオブジェクトからCreateDamageTextスクリプトを取得しCreateTextメソッドに自身のゲームオブジェクトと、Random.Rangeで1~3000の間のint型の数値を渡して呼び出します。

どれだけのTextを作成するかの処理をするスクリプトの作成

DamageTextParentプレハブをインスタンス化する処理は出来ましたが、DamageTextParentはテキストの親の要素で子要素のTextはまだ作成していません。

DamageTextParentプレハブにこのTextを生成するスクリプトを取り付けます。

新しくCreateDamageTextスクリプトを作成しDamageTextParentプレハブに取り付けます。

damageTextPrefabにはTextプレハブをインスペクタで設定します。

damageTextListは作成したTextを入れておくリストです。

charNumは今どの文字のアニメーションをしているかの番号です。

deleteTimeは全ての文字のアニメーション終了後に何秒経ったら親のゲームオブジェクト事消すかの秒数の設定です。

CreateTextメソッドはInstantiateDamagePointスクリプトでDamageTextPrefabをインスタンス化した後に呼び出しています。

damageTextPrefabのRectTransformを取得しそこからTextの幅を取得します。

その後、引数で受け取ったダメージ数の文字の数(桁数)分のdamageTextPrefabをインスタンス化します。

インスタンス化したdamageTextPrefabの位置は少しずつずらさないと同じ位置に作られてしまうので先ほど取得したwidthの幅だけ横にずらした位置にインスタンス化します。

i * widthとすることで何個目のTextの1個目は0、2個目は30、3個目は60と少しずつずれていきます。

インスタンス化したdamageTextPrefabの子要素のTextにその桁の数値を入れます。

その桁の数値はダメージをdamagePoint.ToString()で文字列にしているのでその中の何番目の文字かを[i]で取得しそれを入れます。

damageTextPrefabをダメージの桁数分インスタンス化したら最初のTextのAnimatorコンポーネントを取得しアニメーションパラメータのDamageをトリガーします。

AnimateNextCharメソッドはEndDamageAnimationビヘイビアスクリプトから呼び出していて、ダメージの桁数の文字を超えていなければ次の文字を指してアニメーションをさせ、全ての文字のアニメーションが終わっていたら親のゲームオブジェクトを削除します。

これでUI→Textのダメージテキストアニメーション機能が出来ました。

TextMeshProのダメージテキストアニメーション

TextMeshProはテキストをメッシュにして表示する機能です。

新しめのUnityであればTextMeshProは標準で搭載されているので、使うのに必要な他のファイル等をインポートするだけです。

UnityメニューのWindow→TextMeshPro→Import TPM Essential Resourcesを選択しインポートします。

TextMeshProを使ったダメージテキストアニメーションはUI→Textバージョンとほとんど同じなので同じ部分は説明を省いていきます。

ダメージテキストの親のゲームオブジェクトプレハブを作成

ダメージテキストの親のゲームオブジェクトのプレハブを作成します。

ヒエラルキー上で右クリックからCreate Emptyを選択し、名前をDamageTextMeshProParentとします。

DamageTextMeshProParentを選択し、インスペクタのAdd ComponentからLayout→Rect Transformを取り付けます。

Rect TransformのWidthを1、Heightを1とします。

DamageTextMeshProParentのインスペクタ

DamageTextMeshProParentをAssetsフォルダにドラッグ&ドロップしてプレハブにします。

TextMeshProの作成

TextMeshProを使って通常の3D空間に置けるテキストを作ります。

ヒエラルキー上で右クリックから3D Object→Text – TextMeshProを選択し、名前をDamageTextMeshProTextとします。

RectTransformのWidthとHeightを0.5、Main SettingsのFont AssetにLiberationSansSDFを設定します。

MaterialsのElement0にLiberationSansSDFの子要素のマテリアルが設定されていなければ設定します。

Font Sizeに5を設定します。Alignmentは真ん中にします。

DamageTextMeshProTextのインスペクタ

ダメージテキストアニメーションの作成

DamageTextMeshProTextダメージテキストが出来たので次はこれのアニメーションを作成します。

作り方はUI→Textバージョンと同じなのでやり方は省きますが、アニメーションクリップの名前をIdleTextMeshProとDamageTextMeshProという名前にしました。

ここまで出来たらDamageTextMeshProTextのみをAssetsフォルダにドラッグ&ドロップしてプレハブにします。

スクリプトの作成

スクリプトはUI→Textバージョンとほとんど同じですが、わたくしの都合で複製して作成します。

InstantiateDamagePointスクリプトを複製してInstantiateDamagePoint2スクリプトにします。

ダメージテキストの親を非アクティブにしたり、CreateDamageTextをCreateDamageText2としているだけですね。

作成したらMain Cameraに取り付けます。

次はCreateDamageTextを複製してCreateDamageText2を作成します。

ダメージポイントのText部分をTMP_Textと変更し、ダメージテキストの親のゲームオブジェクトの位置を子のテキストの幅の半分左に寄せてマウスクリックした位置にダメージテキストの真ん中がくるようにします。

その後、親のゲームオブジェクトをアクティブにしています。

次にEndDamageAnimationビヘイビアを複製し、EndDamageAnimation2を作ります。

CreateDamageTextをCreateDamageText2としているだけです。

これで機能が出来ました。

終わりに

ユニティちゃんのRPGを作ってみようカテゴリの記事でダメージポイントを表示しアニメーションをスクリプトを使って作成しましたが、なんだか難しい感じになっているので、アニメーション自体はAnimationウインドウで作成する方法を今回記事にしてみました。

こちらはこちらで個々のテキスト処理があるので面倒な感じもしますが・・・・(^_^;)

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます