【Unity】RPGを作るチュートリアルその43 コマンド入力のUIを制御するクラス

【Unity】RPGを作るチュートリアルその43 コマンド入力のUIを制御するクラス

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

第42回ではUI単位のウィンドウ制御と、UI自体の制御を行うクラスのうち、敵キャラクターの名前を表示する機能について作成しました。

今回は同様にUI単位のウィンドウ制御と、UI自体の制御を行うクラスのうち、コマンド入力の機能について作成していきましょう。

 

 

制作環境

MacBook Pro 2023 Apple M2 Max

Unity6 (6000.0.30f1) Silicon

 

作業内容と順序

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

 

チュートリアルの一覧

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

 

前回の内容

前回はUI単位のウィンドウ制御と、UI自体の制御を行うクラスのうち、敵キャラクターの名前を表示する機能について作成しました。

 

UIを制御するクラス

戦闘画面のUIとして、5つのグループを作成しました。

  • ステータス表示のUI
  • 敵キャラクターの名前表示のUI
  • コマンドのUI ◀︎今回はここ
  • 選択ウィンドウのUI
  • メッセージ表示のUI

これらのUIに関しては、ひとつのまとまりをウィンドウとみなして、そのウィンドウ自体を制御するクラスと、ウィンドウ内のUIを制御するクラスの2つをセットにして実装していきます。

今回はコマンド入力のUIやウィンドウを制御するクラスを作っていきましょう。

 

コマンド入力のUIを制御するクラス

コマンド入力のUIを制御するクラスを作っていきます。このクラスで実装したいのは、

  • カーソルのゲームオブジェクトへの参照を保持するフィールド
  • カーソルを一括で非表示にするメソッド
  • 選択中のコマンドにのカーソルを表示するメソッド
  • UIを表示するメソッド
  • UIを非表示にするメソッド

です。下2つは以前作成した「IBattleUIController」のインタフェースによって実装が強制されます。

Projectウィンドウから「Assets/Scripts/Battle/UI」のフォルダを開き、MonoBehaviourのスクリプトを作成します。名前は [CommandUIController] にしました。

UIを制御するクラス
UIを制御するクラス

 

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

フィールドとしては、各カーソルオブジェクトへの参照を保持するようにしています。

カーソルの表示に関してはSetActiveを使って切り替えるようにして、HideAllCursor()のメソッドでは全てのカーソルを非表示に、ShowSelectedCursor()のメソッドでは選択されているコマンドに応じたカーソルを表示するようにします。

UIの表示/非表示はインタフェースによって実装を強制されるもので、このスクリプトをアタッチする「CommandParent」のゲームオブジェクトの表示/非表示ができるようにします。

 

コマンド入力のウィンドウを制御するクラス

コマンド入力のウィンドウを制御するクラスを作っていきます。このクラスで実装したいのは、

  • UI制御のクラスへの参照を保持するフィールド
  • BattleManagerの参照を保持するフィールド
  • 選択したコマンドを保持するフィールド
  • セットアップするためのメソッド
  • コマンド選択を検知するメソッド
  • コマンド選択を初期化するメソッド
  • ウィンドウを表示するメソッド
  • ウィンドウを非表示にするメソッド

です。セットアップするメソッドと、下2つの合計3つのメソッドは前回作成した「IBattleWindowController」のインタフェースによって実装が強制されます。

同じくProjectウィンドウの「Assets/Scripts/Battle/UI」のフォルダにて、MonoBehaviourのスクリプトを作成します。名前は [EnemyNameWindowController] にしました。

ウィンドウを制御するクラス
ウィンドウを制御するクラス

 

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

フィールドは3つ作成し、UIの制御クラスへの参照はInspectorウィンドウからアサインするようにします。選択したコマンドを保持して、それを「BattleManager」に伝えるので、それぞれフィールドを用意しています。

セットアップ用意のメソッドでは「BattleManager」への参照をフィールドにアサインしています。

コマンド入力は上矢印キーでひとつ上のコマンド、下矢印キーでひとつ下のコマンドを選択するようにします。キー入力はUpdate()から呼ばれるSelectCommand()で検知しています。矢印キーが入力されたら、上方向に移動させる処理、下方向に移動させる処理をそれぞれ呼ぶようにしています。コマンドの上端で上矢印キーを入力したら下端に、コマンドの下端で下矢印キーを入力したら上端に、それぞれループするようにしておきます。

SelectCommand()の中で決定キーの入力を検知した場合は、「BattleManager」側でコマンド入力の結果を受け取るメソッドを呼び出します。このメソッドはこの後実装します。

 

既存のクラスの修正

新しく作ったクラスと繋ぎ合わせるため、既存のクラスも修正していきます。対象は、

  • BattleWindowManager
  • BattleManager
  • BattleStarter

です。

 

BattleWindowManagerの修正

ウィンドウを制御するクラスを追加したので、ウィンドウの管理クラスを修正していきましょう。修正したいポイントは、

  • フィールドの追加
  • リストに追加するコントローラの追加
  • 参照を取得するメソッドの追加

です。やることは前回と同様です。

既存の処理に加えて、今回追加したコマンドウィンドウに関連する部分を追加しています。

 

BattleManagerの修正

次に「BattleManager」 のクラスを修正していきます。追加したいのは、

  • コマンド入力を開始するメソッド
  • コマンド入力の結果を受け取るメソッド
  • 入力されたコマンドを処理するメソッド

です。まだ具体的な処理までは行わないので、入力されたことが分かるようにコンソールにメッセージを表示するようにします。

既存のGetBattleSpriteController()の後に3つメソッドを追加します。

StartInputCommandPhase()では戦闘のフェーズを切り替えています。コマンド入力のフェーズ中は、コマンドウィンドウのカーソルを動かせるようにしています。

OnCommandSelected()は選択されたコマンドを受け取るメソッドで、フィールドにセットした後に後続のハンドリング処理を行っていきます。

HandleCommand()はコマンド入力に応じた処理を行うメソッドです。攻撃、逃げるのコマンドを選択した際には行動に移り、魔法、アイテムのコマンドを選択した場合には、選択ウィンドウを表示することを想定しています。現時点では選択ウィンドウを作っていないので、コンソールにメッセージを出力するだけにとどめます。

 

BattleStarterの修正

続いて「BattleStarter」も修正していきます。テスト用に「BattleManager」のStartInputCommandPhase()を呼び出す機能を追加していきましょう。

StartBattle()の処理の末尾に、テスト用にStartInputCommandPhase()を呼び出すようにしました。本来の流れとしては、メッセージ表示の完了後にコマンド入力に移る流れですが、メッセージウィンドウの実装後にその流れにするようにします。

また、コマンドウィンドウについても表示するようにShowCommand()の処理を記載します。

 

スクリプトのアタッチ

スクリプトを保存したら、ゲームオブジェクトを作成してスクリプトをアタッチしましょう。

 

CommandUIControllerのアタッチ

まずはコマンド入力のUIを制御するスクリプトからです。Hierarchyウィンドウから「CommandParent」のゲームオブジェクトを選択します。

ゲームオブジェクトの選択
ゲームオブジェクトの選択

 

Inspectorウィンドウで今回作成した「CommandUIController」をアタッチします。カーソルオブジェクトの参照フィールドにはそれぞれカーソルのゲームオブジェクトをアサインします。カーソルの親オブジェクトをアサインしてしまうと、コマンドのテキスト表示も消えてしまうのでご注意を(1敗)

カーソルのアサイン
カーソルのアサイン

 

CommandWindowControllerのアタッチ

続いてコマンド入力のウィンドウを制御するクラスをアタッチしていきます。Hierarchyウィンドウで「BattleWindowManager」の下に空のゲームオブジェクトを作成します。名前は [CommandWindowController] にしました。

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

 

Inspectorウィンドウでは「CommandWindowController」のスクリプトをアタッチします。「Ui Controller」のフィールドには、先ほどスクリプトをアタッチした「CommandParent」をアサインしましょう。

スクリプトをアサイン
スクリプトをアサイン

 

また、「BattleWindowManager」のスクリプトでもフィールドを追加したので、「CommandWindowController」をアサインしておきます。

スクリプトをアサイン
スクリプトをアサイン

 

動作確認

ここまでの設定を終えたら動作確認をしてみます。ゲームを実行して、「BattleTester」のスクリプトにて「Execute Battle」にチェックを入れて戦闘を開始します。画像のようにコマンド入力用のウィンドウが表示されて、上矢印キーや下矢印キーでカーソルの位置が切り替わればOKです。また、決定キーを入力した際にコンソールにメッセージが表示されることも確認しておきましょう。

コマンド入力のウィンドウが表示される
コマンド入力のウィンドウが表示される

 

気になる点

動作確認してお気づきかと思いますが、戦闘中の入力と、移動中の入力が同時に行われてしまっている状態です。そのため、戦闘が始まるタイミングで移動を止めるような処理を次回作っていきたいと思います。

 

今回のブランチ

 

まとめ

今回はUI単位のウィンドウ制御と、UI自体の制御を行うクラスのうち、コマンド入力の機能について作成しました。

次回はUIの作業を一度中断して、戦闘が開始したら操作キャラクターやNPCの移動を停止させる処理を入れていきたいと思います。

     

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

CTA-IMAGE

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


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


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