【Unity】RPGを作るチュートリアルその72 メニュー画面の装備箇所選択の動作を実装

【Unity】RPGを作るチュートリアルその72 メニュー画面の装備箇所選択の動作を実装

シンプルなRPGをUnityで作るチュートリアルシリーズの72回目です。

第71回ではメニュー画面の装備機能についてUIを実装しました。

今回は装備機能について、動作を実装していきます。まずはトップ画面から遷移する、装備する箇所の選択のウィンドウの動作から実装していきます。

 

 

制作環境

MacBook Pro 2023 Apple M2 Max

Unity6 (6000.0.30f1) Silicon

 

作業内容と順序

シンプルなRPGを作る上でどんな作業が必要か、どんな順番で作っていくと良さそうか、別ページで検討しました。基本的にこの流れに沿って進めていきます。

 

チュートリアルの一覧

このシリーズ全体の一覧は以下のページにまとめています。

 

前回の内容

前回はメニュー画面の装備機能についてUIを実装しました。

 

メニュー画面の実装方針

メニューの表示を確認
メニューの表示を確認

 

メニュー画面では、

  • アイテムの使用
  • 魔法の使用
  • 装備の選択 ◀︎いまここ
  • ステータスの確認
  • セーブ
  • ゲームの終了
  • メニューを閉じる

の項目を作成します。今回はこのうち、装備の機能について、装備する箇所の選択ウィンドウから実装していきます。

 

装備する箇所の選択画面

装備の選択画面
装備の選択画面

 

装備画面のウィンドウ構成として、

  • 装備する箇所の選択画面
  • 装備するアイテムの選択画面
  • 情報を表示する画面

に分けてUIを作成しています。このうち、装備する箇所の選択画面と情報を表示する画面に関しては、メニューのトップ画面から遷移した時に表示される部分になっているので、こちらからまず実装していきます。それぞれUIを制御するクラス、ウィンドウ自体を制御するクラスに分けて実装していきます。

 

装備する箇所の選択画面の実装

この画面に関しては、

  • 装備ウィンドウ自体を制御するクラス
  • 装備する場所の定義(Enum)
  • 装備する箇所の選択画面のUIを制御するクラス
  • 装備する箇所の選択画面のウィンドウ自体を制御するクラス
  • 情報ウィンドウのUIを制御するクラス
  • 情報ウィンドウ自体を制御するクラス

を作成します。作るものが多くて大変ですが、ひとつひとつやっていきましょう。

 

装備ウィンドウ自体を制御するクラス

装備ウィンドウ自体を制御するクラスでは、メニューのトップ画面から装備を選択した場合に、ウィンドウを表示する機能を実装します。装備画面内のそれぞれのウィンドウに対して指示を出す役割も持たせて、個別の処理についてはそれぞれのウィンドウ自体を制御するクラスで行います。

Projectウィンドウの「Assets/Scripts/Menu」のフォルダに移動し、MonoBehaviourのスクリプトファイルを作成します。名前は [MenuEquipmentWindowController] にしました。

スクリプトファイルの作成
スクリプトファイルの作成

 

作成した「MenuEquipmentWindowController」の中身は以下のように記載しました。

「MenuEquipmentWindowController」のクラスから、装備箇所の選択画面や情報ウィンドウの画面の処理を呼び出していきます。

フィールドとして、各コントローラへの参照を保持するほかに、「_equipmentParent」のフィールドで装備画面のUIの親オブジェクトに対しても参照を保持しています。これは装備画面全体の表示/非表示を切り替えたいためです。

装備画面全体で保持したい情報についてはこのクラスに入れたいので、選択された装備箇所の「SelectedParts」や、装備しているアイテムがない時の表示名の定義なども入れています。

アイテム名を取得する処理に関しては、このクラスに入れています。対応するアイテムがない時の表示名をこのクラスで定義しているので、GetItemName()のメソッド内でデフォルト名としてセットしています。装備中のアイテム名の取得は、装備箇所の選択画面、装備するアイテムの選択画面の両方で必要になるので、装備画面全体で共通して使う処理として実装しています。

OnSelectedEquipmentParts()のメソッドは、装備する箇所が選択された時のコールバックです。装備箇所の選択画面で決定ボタンが押された時の値を渡して、それを元に装備するアイテムの選択画面を表示していきます。

ShowWindow()では画面の表示処理を行なっていますが、メニューで装備画面が選択された場合は装備する箇所の選択画面を表示するため、そのセットアップも行なっています。

 

装備する場所の定義(Enum)

装備する箇所に関しては、戦闘画面のコマンドと同じようにEnumで定義します。このチュートリアルでは武器、防具の2箇所を定義します。実際のゲームでは、右手、左手、頭、……、といったように体の部分に対応させることが多いかもしれません。

Projectウィンドウの「Assets/Scripts/Enums」のフォルダに移動し、空のスクリプトファイルを作成します。名前は [EquipmentParts] にしました。

スクリプトファイルの作成
スクリプトファイルの作成

 

作成した「EquipmentParts」の中身は以下のように記載しました。

選んだコマンドに応じて、画面上に表示されるアイテムの種類も変えていきましょう。

 

装備する箇所の選択画面のUIを制御するクラス

装備する箇所の選択画面のUIを制御するクラスでは、現在装備中の武器や防具の名前とカーソルを制御します。今回のチュートリアルでは数が少ないので、このクラスからフィールドを指定する形で制御していきます。やることとしては、カーソルの表示/非表示の切り替え、名前のセットなので、かなりシンプルです。

Projectウィンドウの「Assets/Scripts/Menu」のフォルダに移動し、MonoBehaviourのスクリプトファイルを作成します。名前は [MenuEquipmentPartsUIController] にしました。

スクリプトファイルの作成
スクリプトファイルの作成

 

作成した「MenuEquipmentPartsUIController」の中身は以下のように記載しました。

装備する箇所の選択画面では、戦闘画面のコマンド選択画面と同じような形で、カーソルへの参照を入れています。また、装備しているアイテム名もセットするため、アイテム名テキストへの参照も入れています。

カーソルの非表示や表示機能は選択中の「EquipmentParts」に応じて切り替えています。武器名、防具名はウィンドウが表示される際にセットします。

 

装備する箇所の選択画面のウィンドウ自体を制御するクラス

装備する箇所の選択画面のウィンドウ自体を制御するクラスでは、現在の装備をステータスから取得したり、カーソルの移動を制御します。武器か防具が選択されたら、装備ウィンドウ全体の制御クラスに通知するようにします。

Projectウィンドウの「Assets/Scripts/Menu」のフォルダに移動し、MonoBehaviourのスクリプトファイルを作成します。名前は [MenuEquipmentPartsWindowController] にしました。

ファイル名が長くなってきた……
ファイル名が長くなってきた……

 

作成した「MenuEquipmentPartsWindowController」の中身は以下のように記載しました。

操作に必要なクラスへの参照用フィールドを実装しています。情報表示ウィンドウに対しても処理の呼び出しを行うため、この後作成する情報表示ウィンドウの制御クラスに対しても参照用フィールドを用意してあります。

フィールドとしては、現在選択中の装備箇所や、装備箇所の合計値を保持するもの、装備箇所を選択できるかどうかのフラグを入れています。装備箇所の合計値については、ファイルの後半に記載してあるInitializeSelect()中で自動的に計算しています。Enumの名前の配列を取得して、その大きさを取得することで、カーソルの上下移動時のループ処理に使っています。……戦闘画面でもこれを使えば良かったかもしれません。

SetUpWindow()では、インタフェースの初期化メソッドとは別に装備画面固有の初期化処理を入れています。アイテム名のセット、ステータスのセット、初期選択など、画面表示時に必要な処理を行なっています。

SelectParts()のメソッドではカーソルの移動や選択を制御しています。ここは戦闘時のコマンド選択と同じような形ですね。必要な参照があり、メニューで装備画面を表示していて、かつ選択可能フラグがtrueな時に選択できるようにしています。装備画面では、装備箇所の選択ウィンドウと装備するアイテムの選択ウィンドウの2つでカーソル操作があるので、フラグによる制御も入れています。

SetDescription()のメソッドはカーソルの位置のアイテムの説明テキストをセットする処理です。今カーソルが表示されている場所のアイテムのIDを取得して情報表示ウィンドウに渡しています。情報表示ウィンドウ側でIDを使ってアイテムデータを取得し、説明文をそのままUIにセットする流れを担当します。

SetItemName()のメソッドでは装備中の武器IDや防具IDを、SetStatus()に関してもキャラクターIDを情報表示ウィンドウに渡しています。情報表示ウィンドウ内ではもらった引数を元に、情報を取得するようにしています。

 

情報ウィンドウのUIを制御するクラス

情報ウィンドウに関しては、説明ウィンドウとステータス表示ウィンドウの両方をまとめて制御してしまいましょう。装備する場所の選択画面やアイテム選択画面ではアイテムのIDを取得して、装備画面の制御クラスを経由して情報ウィンドウに投げることで、必要な情報をセットするようにします。

Projectウィンドウの「Assets/Scripts/Menu」のフォルダにて、MonoBehaviourのスクリプトファイルを作成します。名前は [MenuEquipmentInformationUIController] にしました。

名前空間で分けようかな……
名前空間で分けようかな……

 

作成した「MenuEquipmentInformationUIController」の中身は以下のように記載しました。

説明テキスト、キャラクターの名前テキスト、パラメータの値テキスト、パラメータの変動分テキストへの参照用フィールドを作成してあります。また、実装は次回になりますが、装備するアイテムの選択画面でアイテムを選択する際に、パラメータが増加する場合の色と減少する場合の色も定義してあります。

メソッドとしては主にテキストに値をセットするものになります。各パラメータのセット用メソッドでは、計算後の値と、現在からの変動分を一括で渡すようにしています。変動する値が正の値なら、明示的に「+」をつけて表示するようにします。また、内部で増加か減少かに応じて色をセットするメソッドのSetTextColor()も呼んでいます。

また、装備する箇所の選択画面では変動分の表示は必要ないので、一括で非表示にするClearDeltaValues()のメソッドも入れています。

 

情報ウィンドウ自体を制御するクラス

UIを制御するクラスとセットで情報ウィンドウ自体を制御するクラスも作成します。必要な値の取得などはこのクラスで行なって、UIの制御クラスに渡してセットしてもらうようにします。

Projectウィンドウの「Assets/Scripts/Menu」のフォルダにて、MonoBehaviourのスクリプトファイルを作成します。名前は [MenuEquipmentInformationWindowController] にしました。う〜ん、ながい。

いつかリファクタリングしよう
いつかリファクタリングしよう

 

作成した「MenuEquipmentInformationWindowController」の中身は以下のように記載しました。

説明文テキストや名前テキストなどに関して、必要なIDを渡してもらって、データの取得等についてはこのクラス内で行うようにしています。取得したデータはUIの制御クラスに渡しています。

SetStatusValue()のメソッドの方は変動分なしで現在のステータスを表示するメソッドです。装備品を含めたパラメータ取得は「CharacterStatusManager」クラスのGetCharacterBattleParameterById()のメソッドを使っています。キャラクターのデータが見つからない場合は0で表示するため、ローカル変数を定義してそこにセットする形にしています。

SetSelectedItemStatusValue()のメソッドでは、選択したアイテムによるステータスと現在からの変動分を表示します。選択したアイテムのIDを使って基礎パラメータと足し合わせて、今装備中のものからどれだけ変わるかも表示したいと思います。

選択中のアイテムのIDは、武器を選択中なら「newWeaponId」に選択中のアイテムのものを、「newArmorId」に現在装備中の防具のものを入れます。防具を選択中ならその逆ですね。それぞれ分けると計算が大変だったので、既存のメソッドをそのまま使える形で使用時にちょっと工夫を入れていきます。

 

既存のクラスの変更

作成したクラスに合わせて、既存のクラスも変更を加えていきます。変更したいクラスは以下の通りです。

  • MenuManager
  • CharacterStatusSetter

 

MenuManagerの変更

「MenuManager」では、今回作成した装備画面の制御クラスの「MenuEquipmentWindowController」への参照を追加します。

 

また、メニューで「装備」を選んだ時の分岐も実装します。分岐内で呼ぶShowEquipmentMenu()のメソッドは、ShowItemMenu()の下に追加しました。

 

最後に、装備する箇所の選択画面でキャンセルボタンを押したらメニューのトップに戻れるように、コールバック用のメソッドも用意します。アイテム画面用のコールバックの下に追加してあります。分ける意味はあるかな……? と若干心配ですが、個別になにか処理を入れたくなったときに変更が大変になるので、今のうちから分けておきます。

 

CharacterStatusSetterの変更

「CharacterStatusSetter」のクラスでは、ゲーム開始時の装備品を設定できるようにします。今思えば、「BattleTester」からそのまま移植すれば良かったですね(1敗)

レベルの設定用フィールドの下に、武器と防具のIDを設定できるフィールドを追加します。

 

 

キャラクターのステータスをセットするSetPlayerStatus()のメソッド内で、CharacterStatusの値をセットする際に「equipWeaponId」と「equipArmorId」への代入としてフィールドとして追加したものを指定します。元々は0で指定していた部分ですね。

 

スクリプトのアタッチ

スクリプトファイルを保存したら、ゲームオブジェクトにアタッチします。

 

ゲームオブジェクトの作成

必要なゲームオブジェクトについては先に作ってしまいましょう。

Hierarchyウィンドウから「MenuManager」の子オブジェクトとして空のゲームオブジェクトを作成し、名前を [MenuEquipmentWindowController] にします。

さらに、その子オブジェクトとして同じく空のゲームオブジェクトを作成し、名前をそれぞれ [MenuEquipmentPartsWindowController] 、[MenuEquipmentInformationWindowController] にします。画像では見切れました。

ゲームオブジェクトの作成
ゲームオブジェクトの作成

 

UIを制御するクラスのスクリプトファイルをアタッチ

UIを制御するクラスからアタッチしていきます。Hierarchyウィンドウから「EquipmentParent」のゲームオブジェクトを選択します。

装備箇所の選択画面の親オブジェクトを選択
装備箇所の選択画面の親オブジェクトを選択

 

Inspectorウィンドウから「MenuEquipmentPartsUIController」のスクリプトファイルをアタッチします。対応するゲームオブジェクトについてもアサインしましょう。

スクリプトのアタッチと参照のアサイン
スクリプトのアタッチと参照のアサイン

 

続いて情報表示ウィンドウに関してもUIを制御するクラスをアタッチします。Hierarchyウィンドウから「EquipmentInformationParent」のゲームオブジェクトを選択します。

情報表示ウィンドウの親オブジェクトを選択
情報表示ウィンドウの親オブジェクトを選択

 

Inspectorウィンドウから「MenuEquipmentInformationUIController」のスクリプトファイルをアタッチします。対応するゲームオブジェクトについてもアサインしましょう。こちらは数が多いので大変ですが、頑張ってドラッグ&ドロップしていきます。

スクリプトのアタッチと参照のアサイン
スクリプトのアタッチと参照のアサイン

 

ウィンドウを制御するクラスのスクリプトファイルをアタッチ

先ほど作成した「MenuEquipmentPartsWindowController」のゲームオブジェクトを選択し、Inspectorウィンドウから同名の「MenuEquipmentPartsWindowController」のスクリプトファイルをアタッチします。UIを制御するクラスについてもアサインしましょう。

装備箇所の選択ウィンドウ
装備箇所の選択ウィンドウ

 

同様に「MenuEquipmentInformationWindowController」のゲームオブジェクトを選択し、Inspectorウィンドウから同名の「MenuEquipmentInformationWindowController」のスクリプトファイルをアタッチします。こちらもUIを制御するクラスについてアサインしましょう。

情報表示ウィンドウ
情報表示ウィンドウ

 

「MenuEquipmentWindowController」のゲームオブジェクトを選択し、Inspectorウィンドウから同名の「MenuEquipmentWindowController」のスクリプトファイルをアタッチします。先ほどアタッチしたウィンドウ制御のクラスについてもアサインします。また、装備画面全体の親オブジェクトである「EquipmentMenuParent」もアサインします。

装備画面の制御クラス
装備画面の制御クラス

 

装備画面の制御クラスのアサイン

「MenuManager」では装備画面の制御クラスへの参照用フィールドを追加したので、こちらもアサインしておきましょう。

装備画面の制御クラスのアサイン
装備画面の制御クラスのアサイン

 

動作確認

スクリプトをアタッチしたら動作確認に入ります。

  • EquipmentMenuParent
  • EquipmentParent
  • EquipmentInformationParent

についてそれぞれチェックボックスを外して非表示にしておきましょう。

ゲームを開始して、メニュー画面を開き、装備メニューを選択します。武器と防具の装備箇所が表示され、カーソルを移動できることを確認します。また、「CharacterStatusSetter」で装備品のIDを指定した場合は、以下の画像のようにアイテム名が表示され、説明も表示されることを確認しましょう。装備品の種別については検証処理を入れていないので、薬草を装備することもできます。検証処理は次回の装備するアイテムの選択画面で入れていきます。

装備する箇所の選択画面
装備する箇所の選択画面

 

今回のブランチ

 

まとめ

今回はメニュー画面の装備の機能について、装備箇所の選択画面、情報表示ウィンドウの動作部分を実装しました。2つのウィンドウの制御を実装したのでどうしても長くなってしまいますね。辛い。

次回はメニュー画面の装備の機能について、装備するアイテムを選択するウィンドウの動作部分を実装していきます。

     

ゲーム開発の攻略チャートを作りました!

CTA-IMAGE

「ゲームを作ってみたいけど、何から手を付けていいか分からない!」


そんなお悩みをお持ちの方向けに、todoがアプリをリリースした経験を中心に、ゲーム作りの手順や考慮すべき点をまとめたe-bookを作成しました。ゲーム作りはそれ自体がゲームのように楽しいプロセスなので、「攻略チャート」と名付けています。


ゲームを作り始めた時にぶつかる壁である「何をしたら良いのか分からない」という悩みを吹き飛ばしましょう!