【Unity】RPGを作るチュートリアルその68 マップ上のメッセージウィンドウの動作を実装

【Unity】RPGを作るチュートリアルその68 マップ上のメッセージウィンドウの動作を実装

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

第67回ではメニュー画面の機能のうち、アイテムの表示、使用の機能を実装していく中で、まずUIを作成しました。

今回はメニュー画面のアイテム機能について動作を実装する前に、アイテムを使った時のメッセージを表示するためのメッセージウィンドウの動作を作成していきます。

 

 

制作環境

MacBook Pro 2023 Apple M2 Max

Unity6 (6000.0.30f1) Silicon

 

作業内容と順序

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

 

チュートリアルの一覧

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

 

前回の内容

前回はメニュー画面の機能のうち、アイテムの表示、使用の機能を実装していく中で、まずUIを作成しました。

 

メニュー画面の実装方針

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

 

メニュー画面では、

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

の項目を作成します。今回はこのうち、アイテム使用の機能を実装する準備として、マップ上で表示するメッセージウィンドウの機能を実装します。

 

マップ上のメッセージウィンドウの動作を実装

マップ上のメッセージウィンドウの動作を実装するにあたっては、

  • メッセージウィンドウのコールバック先で実装するインタフェース
  • メッセージウィンドウ自体を制御するクラスのベースクラス
  • メッセージウィンドウ自体を制御するクラス

を作成したいと思います。メッセージウィンドウのUIを制御するクラスについては、戦闘画面のものをそのまま使えるので流用しちゃいましょう。ウィンドウの制御クラスについては、共通する部分をベースクラスにして、表示するメッセージの生成処理に関しては戦闘機能とそれ以外で個別に書けるようにします。

既存のクラスにも影響が出るので、そちらも修正しておきます。

 

メッセージウィンドウのコールバック先で実装するインタフェース

メッセージウィンドウに関しては、メッセージの表示完了後に処理を戻す動きを実装します。戦闘画面のメッセージウィンドウに関しては戻す先が「BattleManager」のみだったのですが、移動中のメッセージウィンドウに関しては、メニュー機能、イベント機能で呼び出す可能性があるため、処理終了の通知先を特定できるようにインタフェースを作成します。これに合わせて、戦闘機能の方もこのインタフェースを実装する形に変更したいと思います。

Projectウィンドウから「Assets/Scripts」のフォルダに移動し、メッセージ関連のスクリプトを配置するフォルダを作成します。名前は [Message] にしました。

フォルダの作成
フォルダの作成

 

作成した「Message」フォルダに移動して、空のスクリプトファイルを作成します。名前は [IMessageCallback] にしました。

コールバック用のインタフェース
コールバック用のインタフェース

 

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

メッセージの表示が完了したことを通知するメソッドを用意して、呼び出し元でこちらを実装するようにしましょう。

 

メッセージウィンドウ自体を制御するクラスのベースクラス

メッセージウィンドウ自体に関しては、戦闘画面とそれ以外で表示するメッセージを分けられるように、ベースクラスで基本機能を提供しつつ、継承先で動作を追加できるようにします。

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

ベースクラスの作成
ベースクラスの作成

 

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

戦闘画面の「MessageWindowController」に含まれていたフィールドや表示非表示の切り替え用メソッドをこちらに移しました。

また、フィールドとして「IMessageCallback」を保持するようにしています。

キー入力を待つ処理についてもこちらに移しています。現在の状態では、戦闘終了時の処理を行う「BattleResultManager」でキー入力を待つようにしていましたが、マップ上でメッセージを表示するケースを考えると入力待ちの処理を毎回呼び出し元で書くのは大変そうなので、メッセージウィンドウ側にその機能を持たせました。

 

MessageWindowControllerの変更

ベースクラスを追加したので、「MessageWindowController」についても変更を行います。動作に必要な部分は大半をベースクラスに移行したので、このクラスに残すのはメッセージを生成するメソッドが中心になっています。

SetUpController()のメソッドでは「BattleManager」の参照を受け取っていますが、「BattleManager」に「IMessageCallback」のインタフェースを実装することによって、インタフェースの動作を変えずに変更しています。

「BattleManager」側の変更は後ほど行うので、コンパイルエラーは出てきますが一旦このまま進めます。

 

メッセージウィンドウ自体を制御するクラス

戦闘画面と同様に、メッセージウィンドウを制御するクラスを追加します。このクラスはマップ上でメニュー画面による呼び出しやイベントによる呼び出しによって表示処理を行います。

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

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

 

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

メッセージ表示完了後のコールバック先をセットするメソッドと、アイテム関連のメッセージを生成するメソッドを入れています。メッセージ生成自体は戦闘時のメッセージをそのまま使えるので、同じように実装しています。

 

既存のクラスの変更

上記の変更に伴って、既存のクラスについても変更していきます。

 

BattleManagerの変更

「BattleManager」ではインタフェースを実装しておきます。インタフェース内のメソッド名は「BattleManager」で受け取っていたコールバックと同じにしてあるので、冒頭でMonoBehaviourの後ろに実装しましょう。

 

BattleResultManagerの変更

「BattleResultManager」では、このクラスで実装していたキー入力待ちの処理を削除し、メッセージウィンドウのものを呼び出すようにします。

キー入力待ちを行う際には、メッセージウィンドウのStartKeyWait()を呼び出してフラグを切り替えた後、そのフラグがfalseになるまでwhileループで待つようにします。フラグが切り替わったら次の処理に進むようになります。

 

スクリプトのアタッチ

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

 

MessageUIControllerのアタッチ

マップ用のメッセージウィンドウのUIに、既存のUI制御クラスである「MessageUIController」をアタッチします。Hierarchyウィンドウから「MenuScreen」と同じ階層にいる「MessageWindowParent」のゲームオブジェクトを選択し、Inspectorウィンドウから「MessageUIController」をアタッチします。(画像撮影の関係で、コンポーネントを折りたたんだ状態です)

テキストへの参照や、カーソルへの参照もアサインしておきましょう。

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

 

MapMessageWindowControllerのアタッチ

続いて、「MapMessageWindowController」のスクリプトをアタッチしていきます。Hierarchyウィンドウから「Managers」の下に空のゲームオブジェクトを作成します。名前は [MapMessageWindowController] にしました。

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

 

Inspectorウィンドウでは、「MapMessageWindowController」のスクリプトをアタッチします。「Ui Controller」の項目は、先ほどアタッチした「MessageWindowParent」のゲームオブジェクトをアサインします。戦闘画面のメッセージウィンドウと同じ名前になっているため、Hierarchyウィンドウからドラッグ&ドロップするのがおすすめです。

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

 

動作確認

今回作成した「MapMessageWindowController」に関しては次回メニュー画面のアイテムの動作と合わせて確認します。ここでは、変更を行なった戦闘画面のメッセージウィンドウについて確認していきます。

Hierarchyウィンドウから「MenuBackground」、「ItemMenuParent」、「MessageWindowParent」を非表示にします。「BattleTester」を使って戦闘を開始し、戦闘終了まで進めていきます。

あっ
あっ

 

……と、このまま「BattleTester」を使うと移動の制御などがない状態なので、ついでに修正したいと思います。戦闘機能を作成したタイミングでは「BattleManager」で移動の制御を行なっていたのですが、エンカウントの仕組みを作った時に「EncounterManager」に移したのでした。戦闘終了後のコールバックも受け取れるように、「BattleTester」にもインタフェースを実装したいと思います。

まずは「CharacterMoverManager」への参照用フィールドを追加します。

 

続いて、コールバック用のメソッドを追加します。StartBattle()の中では、移動の停止とコールバック先の登録も行うようにしました。

 

フィールドを追加したので、Hierarchyウィンドウから「BattleTester」を選択し、Inspectorウィンドウにて「Character Mover Manager」の項目にアサインしておきます。

参照のアサイン
参照のアサイン

 

再度「BattleTester」を使って戦闘を開始し、戦闘終了まで進めます。メッセージウィンドウにメッセージが表示され、次のメッセージが表示されることを確認します。戦闘終了時も、キー入力を受け取って次に進む点が確認できればOKです。

ほっ……(安堵)
ほっ……(安堵)

 

今回のブランチ

 

まとめ

今回はメニュー画面のアイテム機能について動作を実装する前に、アイテムを使った時のメッセージを表示するためのメッセージウィンドウの動作を作成しました。この辺りからだんだんと、なにかをいじると既存の影響範囲が大きくなってきますね。

次回はメニュー画面のアイテム機能について動作を実装していきます。

     

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

CTA-IMAGE

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


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


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