シンプルなアクションゲームを作ってみよう17-キャラクターのHPを表示する-

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

シンプルなアクションゲームを作ってみようの第17回です。

今回はプレイヤーキャラクターのHPをScriptableObjectでアセットファイルとして保持し、それをUIに表示したり、敵に接近された時にHPを減らす機能を作成していきます。

前回は障害物を作成しました。

シンプルなアクションゲームを作ってみよう16-障害物を作成する-
シンプルなアクションゲームでプレイヤーキャラクターを邪魔する障害物を作成し、障害物が消えたらナビメッシュ上を動く敵も移動出来るようにしていきます。

シンプルなアクションゲームを作ってみようの他の記事は

シンプルなアクションゲームを作ってみよう

シンプルなアクションゲームを作るのを通してUnityの使い方を学ぶカテゴリです。

から参照出来ます。

スポンサーリンク

ステータスを管理するスクリプトを作成する

プレイヤーキャラクターのPlayerControllerスクリプトでは、キャラクターの操作に関する処理を記述しました。

ここにキャラクターのhpに関するフィールドを用意し、敵にダメージを受けた時のメソッドを書いていくということも出来ます。

ですが、今回はHPに関する処理をステータスを管理する別のスクリプトに処理をまかせるようにします。

なのでPlayerControllerでは敵にダメージを受けたというメソッドを用意し、実際にHPを減らすのはそのスクリプトで行うという感じです。

このステータスを管理するスクリプトはScriptableObjectを継承したクラスとし、そのインスタンスをアセットにして使います。

ScriptableObjectはゲームオブジェクトに取り付ける必要がないスクリプトで、大量のデータを使う時等に便利です。

また、ひとつのデータを複数のゲームオブジェクトで共有したい時にも便利です。

ScriptableObjectのアセットを作るには、スクリプトでScriptableObjectを継承してクラスを作成し、アトリビュートでメニューからアセットを作れるように設定するという流れです。

ScriptableObjectでステータスアセットを作成する

文章だけを見ても分かり辛いので実際に作ってみましょう。

まずはAssets/Scriptsフォルダに新しくPlayerStatusスクリプトを作成し以下のように記述します。

PlayerStatusはScriptableObjectを継承するようにします。

また、アトリビュートでCreateAssetMenuを取り付け、UnityエディターのメニューのAssetsにCreatePlayerStatusという項目を追加します。

また作成するアセットの名前はPlayerStatusという名前にします。

hpはフィールドでプレイヤーキャラクターのHPを入れます。

SetHpメソッドは引数で受け取ったhpをプレイヤーキャラクターのHPを設定します。

ただし、hpが0以下だった場合は0にします。

またHPを設定するだけでなく、その値を呼び出し元にも返しています。

GetHpメソッドはプレイヤーキャラクターのHPを返すメソッドです。

ResetメソッドはHPを10にセットするメソッドです。

これはプレイヤーキャラクターのHPの最大値を10に想定しているので10というマジックナンバーをそのまま入れています。

マジックナンバーというのはいきなり現れた数値等の事をいい(いきなり現れるので何を表しているか分かり辛い)、普通はフィールド等で用意しておいて10の部分をフィールド名にする方が良いです。

これでスクリプトが出来ました。

PlayerStatusアセットの作成

先ほど作成したスクリプトでCreateAssetMenuアトリビュートを取り付けたので、UnityエディターのメニューのAssetsに新しい項目が表示されています。

UnityメニューのAssets→Create→CreatePlayerStatusを選択します。

CreatePlayerStatus項目を選択する

すると開いているProjectフォルダに新しくPlayerStatusフォルダが作成されます。

PlayerStatusのHPのデフォルト値はResetメソッドで設定した値になるようです。

新しく出来たPlayerStatusファイルはAssets/Dataフォルダを作成し、その中に入れていくようにします。

PlayerStatusアセットファイルが作成された

これでHPの管理をするアセットが出来ました。

PlayerStatusを選択してインスペクタを確認すると以下のようにHPを確認出来ます。

PlayerStatusアセットのインスペクタ

HP表示用のUIを作成する

次にプレイヤーキャラクターのHPを表示するUIを作成していきます。

UIゲームオブジェクトを選択した状態で、右クリックからUI→Canvasを選択し、名前をLifeとします。

Lifeキャンバスを作成した

次にLifeゲームオブジェクトを選択した状態で右クリックからUI→Panelを選択し、名前をLifePanelとします。

LifePanelパネルを作成した

次にヒエラルキーのLifePanelを選択し、シーンビューでLifePanelの四隅に矢印があるのを確認したら、右上か左上の矢印をShiftキーを押しながらドラッグし、ライフを表示する場所をゲーム画面の下にします。

ライフを表示する領域はゲーム画面の横の比率は100%で縦の比率が10%ぐらいにしました。

ライフの表示領域を変更する

ライフを表示する領域の背景イメージは使わないので、ヒエラルキーでLifePanelを選択し、Imageコンポーネントのチェックを外します。

LifePanelのImageコンポーネントを非アクティブにする

ライフの表示領域が出来たので次は表示するライフゲージを作成します。

LifePanelを選択した状態で右クリックからUI→Imageを選択し、名前をLifeとします。

LifePanelの子要素にライフゲージを作成する

ヒエラルキーでLifeゲームオブジェクトを選択し、インスペクタの設定をします。

ライフのImageにBackground画像を設定する

ImageコンポーネントのSource Imageの丸のアイコンを押し、検索窓にbackgroundと入力して出てくる画像を設定します。

これでライフゲージが一つ出来たのでヒエラルキーのLifeを選択した状態でCtrl+Dキーを9回押してライフゲージを10個にします。

ライフゲージを10個に複製する

これで10個のライフゲージが出来ました。

ライフゲージを整列させる

ライフゲージは10個出来ましたが、同じ位置に表示されています。

ライフゲージが一か所に表示されている

個々のLifeのRect Transformの数値を変更したり、シーンビューで少しずつズラすということも出来ますが、ここではLifePanelゲームオブジェクトにHorizontal Layout Groupというコンポーネントを取り付け、子要素のゲームオブジェクトのサイズをコントロールし、横に綺麗に並ぶようにします。

ヒエラルキーのLifePanelゲームオブジェクトを選択し、インスペクタのAdd ComponentからLayout→Horizontal Layout Groupを選択し取り付けます。

Horizontal Layout Groupで子要素のライフゲージの並びを管理する

PaddingのLeft、Right、Top、Bottomに2を入れ、表示領域の各方向からの距離を設定しています。

Child Alignmentは子要素の配置方法で中央の左側に表示します。

Control Child Sizeは子要素のライフゲージの幅と高さをHorizontal Layout Groupでコントロールする場合にチェックを入れます。

ここにチェックを入れると子要素のゲームオブジェクトの幅と高さが変更されます(チェックを外しても元に戻りません)。

Child Force Expandは子要素のゲームオブジェクトを強制的に拡張するかどうかで、高さのみ拡張するようにします。

Horizontal Layout Groupの設定を行うとライフゲージが横に整列されたと思います。

ライフゲージが横に整列された

これでライフゲージのUIが出来ました。

ライフゲージ更新スクリプトの作成

ライフゲージを更新するLifeGaugeUpdateScriptスクリプトを作成し、LifePanelゲームオブジェクトに取り付けます。

playerStatusは先ほど作ったPlayerStatusアセットをインスペクタで設定します。

StartメソッドではUpdateLifeGaugeメソッドを呼んでライフゲージを更新しています。

UpdateLifeGaugeメソッドではfor文を使って繰り返し処理をしていますが、条件でtransform.childCountを使って子要素のライフゲージ分の繰り返しを行います。

iの値とplayerStatusのHPを比較し、iがHPより低い場合はtransform.GetChild(i)でLifePanelの子要素のi番目のTransformを取得し、そこからImageコンポーネントに青色を設定しています。

これはHPがある分のライフゲージを青色に変更しています。

それ以外の時、つまり既にHPが減っている部分のライフゲージは白色に設定します。

これでスクリプトが出来たのでLifePanelのインスペクタのLifeGaugeUpdateScriptのPlayer StatusにAssets/DataフォルダにあるPlayerStatusアセットをドラッグ&ドロップします。

LifeGaugeUpdateScriptのPlayer StatusにPlayerStatusアセットを設定する

PlayerControllerスクリプトに処理を追加する

PlayerControllerスクリプトに処理を追加します。

まずはフィールドを追加します。

playerStatusはインスペクタでPlayerStatusアセットを設定します。

lifeGaugeUpdateScriptはインスペクタにLifePanelをドラッグ&ドロップしてLifeGaugeUpdateScriptを設定します。

次に敵にダメージを受けた時に呼び出すメソッドを追加します。

引数で受けるダメージ数を受け取ります。

playerStatusのGetHpメソッドで現在のプレイヤーのHPを取得し、ダメージ数分を引いた値をplayerStatusのSetHpメソッドで設定しています。

返ってきた値(HP)が0以下だった時はgameManagerのEndGameメソッドを呼んでゲームを終了します。

その後lifeGaugeUpdateScriptのUpdateLifeGaugeメソッドを呼んでライフゲージの更新をしています。

スクリプトへの追加が出来たのでPlayerゲームオブジェクトのPlayerControllerの設定をします。

PlayerのPlayerControllerにPlayerStatus等をセットする

Player StatusにはPlayerStatusアセットをドラッグ&ドロップして、Life Gauge Update ScriptにはLifePanelをドラッグ&ドロップしてLifeGaugeUpdateScriptを設定します。

敵が接近したらダメージを与える

最後に敵が接近したらプレイヤーキャラクターにダメージを与える処理をEnemyControllerスクリプトに追加します。

まずはフィールドを追加します。

attackPowerは敵の攻撃力で、playerControllerはプレイヤーに取り付けてあるPlayerControllerを入れます。

次にStartメソッドに処理を追加します。

playerに代入している処理の後にplayerからPlayerControllerを取得する処理を追加します。

次にUpdateメソッドに処理を追加しますが、一部だけだと分かり辛いのでUpdateメソッド全部を載せました。

敵がプレイヤーにダメージを与えるのはプレイヤーに接近した時なのでそこでPlayerControllerのTakeDamageメソッドを呼び出してダメージを与えています。

実行して確認してみる

機能が出来たので実行して確認してみましょう。

上のようになりました。

現時点ではHPが減ると回復させていないので、HPが減ったらPlayerStatsuアセットのHPに10を入力して回復してください。

またHPが0になったらゲームオーバーになっていますが、ゲームオーバーであることを示すUIの作成もしていないので分かり辛くなっております。

終わりに

今回はプレイヤーキャラクターのHPの作成とそれをUIで表示、また敵キャラクターが接近した時のダメージ処理などを作りました。

次回は敵キャラクターとは別に大砲を作ってプレイヤーを狙う機能を作成していきます。

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