Unityのゲームで高い所から落下した時にダメージを与える

今回はUnityのアクションゲームで高い所から落下した時にキャラクターにダメージを与えたいと思います。

キャラクターが地面から離れた時にその位置を記憶しておき、再度地面にふれた時にその距離を計算します。

高い所から落下した時にダメージを与えると言ってもキャラクターが30cmぐらいの高さから落ちた時にもダメージを与えていたのではシャレになりません・・・(+_+)

その為、落下する前の地面のY座標から、落下した後の地面のY座標の距離を計算し、ある程度の高さ(これは設定出来るようにします)を越えていたらダメージを与えるようにしたいと思います。

また、ジャンプをした時に最初の落下地点より上に飛んだ場合の事も考慮し、ジャンプの最高到達点から地面までの距離でダメージを計算するようにします。
(ジャンプした時を考慮しない場合は最初の落下地点を使って計算してください)

スポンサーリンク

キャラクターのHP表示UIを作成

まずはキャラクターのHPを表示するUIとカメラの方を向かせるスクリプトを取りつけ、視覚的にキャラクターのHPが見えるようにしておきます。

キャラクターのHP機能に関しては

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

も参照してください。

Ethan直下にHP用UIを作成

HP表示UIの作成

キャラクター(Ethan)の直下に右クリック→UI→Canvasを作成し名前をHPとします。

その直下にUI→Textを作成します。

HPCanvasの設定

HPのインスペクタは↑のようにRect TransformのWidthやHeight、Scaleを変更し、
CanvasのRencer ModeをWorld Spaceに変更します。

HPのUIを常にカメラの向きにするスクリプト

RotateDamageUIとMyHPスクリプトを取りつけます。

RotateDamageUIはHPのUIを常にカメラの方向を向かせるスクリプトです。

Update関数で角度を変更すると画面のチラつきが発生するのでLateUpdate関数内で処理しています。

HPの管理スクリプトの作成

MyHPスクリプトはキャラクターのHPを管理しているスクリプトでHPをUIに表示したりダメージの処理をしています。

テキストの書き換えが頻繁にあると処理が遅くなりそうなので、前のHPと変更がない場合はUIの書き換えは行いません。

そもそもUpdate関数内でずっとHPの監視をしなくてもDamage関数内でUIのテキストとhpを更新しているのでUpdate関数の処理は要らないです。

じゃあ載せるなぁぁぁぁ(-_-)/~~~ピシー!ピシー!

HPCanvas直下のTextの設定

↑がTextの設定でキャンバスであるHPとサイズを合わせたり位置を調整して設定してあります。

キャラクターの頭上にHPを表示した所

↑が実際にキャラクターの上にHPのUIを表示した画像になります。

ここまででHPの処理に関しての設定が終わりました。
HPの処理に関しての詳しい内容はさきほど紹介した記事を参照してください。

キャラクターが落下した時のダメージ処理の作成

キャラクターが落下したと判断する場合

次にキャラクターが落下した時の処理を作成していきます。
キャラクターが落下する時というのは地面からキャラクターが離れた時です。

キャラクターが離れた時を検知するには地面のコライダのOnCollisionExitで検知出来そうですがCharacterControllerの場合検知出来ないっぽいです。

それにゲーム内の地面全部に検知するスクリプトを設定するのは現実的ではありません。

そこでキャラクターの体からレイを飛ばし地面と接地しているかどうかを常に監視しておきます。

レイが地面に当たっていなければ落下したと判断し落下位置を設定するようにします。

CharacterControllerで接地をレイで確認する方法は

UnityのCharacterControllerの接地が判断出来ない時にスクリプトを使う
UnityのキャラクターをCharacterControllerで動かしている場合に地面とキャラクター(厳密にはコライダ)が接地しているかどうかはIsGroundedプロパティで判断していますが、坂を下っている時はこの値がfalseになっています。そんな時にスクリプトで接地を判断してみます。

を参照してください。

キャラクターが落下した時のダメージを計算するスクリプトToFallFromAHeight

キャラクターの落下と地面との距離を計算し、ダメージを与えるスクリプトToFallFromAHeightを作成します。

Update関数内で常にキャラクターから下にレイを飛ばし地面と接地しているかを確認します。

地面と接地した時にfallFlagがtrueであれば落下地点から現在のキャラクターの位置を引いて距離を計算します。

落下のダメージが発生する距離を越えた落下だった場合はMyHPスクリプトのDamage関数を呼び出します。

今回はダメージを

落下距離 – ダメージを受けない限界距離

で計算しています。

地面にレイが届いていない時はキャラクターが接地していない時なのでfallPositionにキャラクターの現在の距離を入れます。

一度設定したらfallFlagにtrueを入れ、落下中ずっと更新されないようにしておきます。

fallPosition = Mathf.Max(fallPosition, transform.position.y);

で落下位置(fallPosition)と現在のキャラクターの位置でより高い方をfallPositionに入れます。

これはキャラクターがジャンプした時の事を考慮した処理です。

ジャンプして上に飛び上がった距離を計算しない場合はこの部分は削除してください。

キャラクターを落下させ動作確認をする

ToFallFromAHeightをキャラクターに取りつけ、

ToFallFromAHeightのインスペクタの設定

インスペクタで↑のように設定します。

damageDistanceを1に設定し、1m上から落下した時にダメージを与えるようにします。

これで機能が完成したのでUnityの実行ボタンを押して確認してみましょう。

高い所から落下した時にダメージを与えるサンプル

↑のように1mより上から落下した時にキャラクターのHPが減るようになりました。

より高い位置から落下させると距離分だけダメージ量が大きくなっているのがわかりますね!

ゲームなので高いところから落下してもダメージを受けないというものも多いですが、

リアルな感じのゲームを作成したい時は高いところから落下した時にダメージを与えたり、より高いところから落下したら一発で終わり。

というゲームにすると緊張感も増してくると思います。

わたくしの場合リアルなゲームだと3D酔いをしたり、高いところから落ちたりすると実際に落ちたような感じを受けてしまうので、ものによっては避けてしまいます。

バーチャルリアリティを使ったゲームをやったら体に悪そう・・・・(^_^;)