今回は戦闘シーンに味方キャラクターの名前、HP、MPを表示する機能を作成していきます。
前回は戦闘シーンで使用するキャラクターのAnimatorControllerを作成しました。
ユニティちゃんのRPGを作ってみようの他の記事は
から見ることが出来ます。
今回の機能は以前作成した何もしていない時にステータス画面を表示する機能とほぼ同じです。
戦闘シーンにステータスを表示する機能の作成
戦闘シーンにステータスを表示する機能を作成していきます。
ステータス表示用UIの作成
まずはBattleシーンのヒエラルキー上で右クリックからUI→Canvasを選択し、名前をBattleUIとします。
BattleUIを選択してインスペクタのCanvas ScaleのUI Scale ModeをScale With Screen Sizeにして画面サイズによってUIのサイズを変えます。
Reference ResolutionのXは1024、Yは768を基準とし、Screen Match ModeをExpandにして、UIを広げるようにします。
BattleUIを選択した状態で右クリックからUI→Panelを選択し、名前をStatusPanelとします。
StatusPanelのサイズを調整し右下に表示されるようにします。
またImageのColorを黒色の半透明にします。
ここで表示するStatusPanelのサイズはVillagerシーンやWorldMapシーンで何もしていない時に表示するステータス画面とサイズを合わせておくと統一感があるかもしれません。
StatusPanelのインスペクタのAdd ComponentからLayout→Vertical Layoutを選択、Add ComponentからLayout→Canvas Groupを選択し、以下のように設定します。
Vertical Layout Groupコンポーネントで子要素の個々のキャラクターステータスを縦に整列させ、子要素の幅を制御し広げます。
Canvas Groupのinteractableのチェックを外し子要素のSlider等が選択されないようにします。
子要素のHPSliderやMPSliderのinteractableのチェックを外す事でも出来ますが、親のStatusPanelにCanvas Groupを取り付けinteractableのチェックを外すことで一括で子要素のUI要素を選択出来ないようにしています。
個々のキャラクターのステータスを作成していきます。
StatusPanelの子要素にAssets/RPG/Prefabs/UI/Command/CharacterPanelをドラッグ&ドロップします。
ヒエラルキー上のCharacterPanelを選択した状態で右クリックからUnpack Prefab Complitelyを選択し元のプレハブとのリンクを解除します。
CharacterPanelプレハブを使ったのは単にUI作成を簡単にする為です。
CharacterPanelを選択し名前をCharacterPanel0とします。
CharacterPanel0を選択しCtrl+Dキーを押して3つ複製し、名前をCharacterPanel1~3に変更します。
WorldMapシーンのステータス表示ではCharacterPanelプレハブをキャラクター分インスタンス化して表示しましたが、今回は味方キャラクターが最大4人だと仮定し、予め個々のキャラクターのUIを作成しておきます。
ここまでのヒエラルキーは以下のようになります。
味方パーティーステータスの表示をする
ステータス表示用のUIが出来たので次は戦闘が始まった時に味方パーティーのステータスを表示させるスクリプトを作成します。
Assets/RPG/Scripts/Battleフォルダに新しくBattleStatusScriptスクリプトを作成します。
BattleStatusScriptはStatusPanelゲームオブジェクトに取り付けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class BattleStatusScript : MonoBehaviour { public enum Status { HP, MP, } // パーティーステータス [SerializeField] private PartyStatus partyStatus = null; // キャラクターステータス表示Transformリスト private Dictionary<CharacterStatus, Transform> characterStatusDictionary = new Dictionary<CharacterStatus, Transform>(); // Start is called before the first frame update void Start() { // 最初の全データ表示 DisplayStatus(); } // ステータスデータの表示 public void DisplayStatus() { CharacterStatus member; Transform characterPanelTransform; for (int i = 0; i < 4; i++) { characterPanelTransform = transform.Find("CharacterPanel" + i); if (i < partyStatus.GetAllyStatus().Count) { member = partyStatus.GetAllyStatus()[i]; characterPanelTransform.Find("CharacterName").GetComponent<Text>().text = member.GetCharacterName(); characterPanelTransform.Find("HPSlider").GetComponent<Slider>().value = (float)member.GetHp() / member.GetMaxHp(); characterPanelTransform.Find("HPSlider/HPText").GetComponent<Text>().text = member.GetHp().ToString(); characterPanelTransform.Find("MPSlider").GetComponent<Slider>().value = (float)member.GetMp() / member.GetMaxMp(); characterPanelTransform.Find("MPSlider/MPText").GetComponent<Text>().text = member.GetMp().ToString(); characterStatusDictionary.Add(member, characterPanelTransform); } else { characterPanelTransform.gameObject.SetActive(false); } } } // データの更新 public void UpdateStatus(CharacterStatus characterStatus, Status status, int destinationValue) { if (status == Status.HP) { characterStatusDictionary[characterStatus].Find("HPSlider").GetComponent<Slider>().value = (float)destinationValue / characterStatus.GetMaxHp(); characterStatusDictionary[characterStatus].Find("HPSlider/HPText").GetComponent<Text>().text = destinationValue.ToString(); } else if(status == Status.MP) { characterStatusDictionary[characterStatus].Find("MPSlider").GetComponent<Slider>().value = (float)destinationValue / characterStatus.GetMaxMp(); characterStatusDictionary[characterStatus].Find("MPSlider/MPText").GetComponent<Text>().text = destinationValue.ToString(); } } } |
列挙型のStatusはHPとMPのどちらのデータを更新するかです。
partyStatusは味方パーティーのデータを保持しているPartyStatusをインスペクタで設定します。
characterStatusDictionaryはキーをCharacterStatusにして、値をステータスを表示しているUIのTransformとしています。
何らかのデータが更新されたらステータス全部を更新してもいいんですが、今回はとりあえず個別にどのキャラクターのどのパラメータのUIを更新するかを指定して更新出来るようにしています。
DisplayStatusメソッドで4人分のステータスを設定する為にfor文を使いその中でpartyStatusに保持しているキャラクター分の繰り返しを行います。
1 2 3 | partyStatus.GetAllyStatus()[i]; |
でユニティちゃんと大鳥ゆうじの二人しかパーティーメンバーがいない時にpartyStatus.GetAllyStatus()[2]等とするとエラーが出る為、条件を設けています。
キャラクターメンバーがいなくなったら、他のステータスUIは表示する必要がない為にSetActiveを使って非表示にしています。
UpdateStatusメソッドは引数でキャラクターステータス、どのステータスか?、設定する値を受け取りUIのデータを更新しています。
戦闘シーンでキャラクターステータスが表示されるか確認する
機能が出来たので、戦闘シーンに遷移したらキャラクターステータスが表示されるかどうかを確認してみましょう。
上のようになりました。
終わりに
今回作成した機能は以前作成した機能とほとんど同じなので問題はないと思います。
UpdateStatusメソッドは味方キャラクターが攻撃を受けた時や魔法を使った時に呼び出し、そのステータスを更新します。
この作品はユニティちゃんライセンス条項の元に提供されています