【Unity】RPGを作るチュートリアルその38 テスト用に戦闘を開始する処理の作成

【Unity】RPGを作るチュートリアルその38 テスト用に戦闘を開始する処理の作成

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

第37回では戦闘の機能全体を管理するクラスを作成しました。

今回はテスト用に戦闘を開始するための処理を作っていきましょう。戦闘機能を簡単に呼び出せるようにしておくと後の作業が楽になるので、このタイミングで実装しちゃいましょう。

 

 

制作環境

MacBook Pro 2023 Apple M2 Max

Unity6 (6000.0.30f1) Silicon

 

作業内容と順序

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

 

チュートリアルの一覧

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

 

前回の内容

前回は戦闘の機能全体を管理するクラスを作成しました。

 

今回作成する範囲

前回紹介した図をもとに、戦闘機能のどの部分を実装していくかをざっくりと赤い四角で囲みました。

 

テスト用に戦闘機能を呼び出せるようにする
テスト用に戦闘機能を呼び出せるようにする

 

作りたいものとしては、

  • リソース類を読み込むクラス
  • テスト用に戦闘発生を通知するクラス

です。

戦闘開始処理の中では、各UIの操作も必要になっていくので、何回かに分けて順番に対処していきます。

処理の大まかな流れとしては、テスト用の戦闘発生を通知するクラスから「BattleManager」に対して通知を行います。具体的には「BattleManager」の中にpublicなメソッドを用意しておいて、それを使って知らせるようにします。今後エンカウント処理と組み合わせる際にも、同じメソッドを呼び出すことを想定しています。

「BattleManager」からは戦闘開始処理を行うクラスに対して通知を行います。具体的な処理はそちらのクラスに任せることとして、「BattleManager」から必要な情報を渡すようにします。

戦闘を実行するにあたっては、定義データ類のロードも必要になるので、各定義データの管理クラスに用意したロード用のメソッドを呼び出すためのクラスも作成したいと思います。ゲーム全体を作り込んでいく際には、起動時に呼ばれることになります。

 

リソース類を読み込むクラスの作成

戦闘機能に必要なデータを読み込むため、リソース類を読み込むクラスを作成しておきます。上述の通り、Start()のタイミングで各定義データの管理クラスに用意したロード用のメソッドを呼び出します。

今回のチュートリアルではローカルにファイルを同梱するのでほぼ遅延なくロードできるかと思います。サーバやCDN等にAddressablesのアセットバンドルを配置する場合は、ネットワークの速度なども考慮してロードや更新確認用のフェーズを用意しておくと安心です。

というわけでスクリプトファイルを作成していきましょう。Projectウィンドウの「Assets/Scripts」のフォルダでMonoBehaviourのスクリプトを作成します。名前は [ResourceLoader] にしました。

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

 

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

上でお伝えしたものをそのまま実装した形になります。このクラスはシーン内のゲームオブジェクトにアタッチしてStart()のタイミングで定義データ類を読み込むようにします。

アタッチする作業は、今回作成するスクリプト類を全部作った後にまとめてやってしまいましょう。

 

テスト用に戦闘発生を通知するクラス

戦闘機能を作っていくにあたって、テスト用に戦闘を発生させる機能を作っておきたいと思います。ゲームを実行してなるべくスムーズに戦闘機能を呼び出せるようにしておくと、開発の手間やストレスも減らせます。

このクラスでは、戦闘に必要な情報をInspectorウィンドウから設定できるようにします。

  • 敵キャラクターのID
  • 味方キャラクターのレベル
  • 装備中の武器のID
  • 装備中の防具のID
  • 所持しているアイテムの一覧

また、戦闘機能を呼ぶためのチェックボックスも用意しておいて、それがtrueになったら戦闘発生が通知されるようにします。このチェックボックスはゲーム実行中にtrueにすることを想定しています。というのも、trueにしたままゲームを実行すると、定義データ類を読み込む前に戦闘機能が呼ばれてエラーになるためです。念の為ゲーム実行からフレームカウントが5フレーム未満なら抜ける処理も入れておきましょうか。そうすればInspectorウィンドウでtrueにしたままでもいけそうですね。

フィールドで設定した情報をもとに、必要なデータを作成していきます。キャラクターの現在のステータス、所持アイテムをセットして、「BattleManager」に対しては敵キャラクターのIDを通知した上で戦闘開始用のメソッドを呼び出します。それに伴い、「BattleManager」でもいくつかメソッドを追加しましょう。

こちらもスクリプトファイルを作成していきます。Projectウィンドウの「Assets/Scripts/Debug」のフォルダでMonoBehaviourのスクリプトを作成します。名前は [BattleTester] にしました。

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

 

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

ちょっと長いですが解説していきます。

フィールド類は、通知先の「BattleManager」や、戦闘に必要なパラメータ類を用意しています。また、戦闘機能を呼び出すかどうかのフラグも「_executeBattle」として用意してあります。

Update()からはCheckStartFlag()のメソッドを呼んで、戦闘機能を呼び出すかどうかのフラグがtrueなら戦闘に必要な情報をセットアップする処理であるReadyForBattle()に進みます。

ReadyForBattle()では味方キャラクターの情報のセット、敵キャラクターの情報のセット、戦闘の開始、と順番に進めていきます。

味方キャラクターの情報のセットとしてSetPlayerStatus()の中で処理を行なっていきます。レベルに対応するパラメータの情報を取得し、ゲーム実行中にキャラクター全体の情報を管理する「CharacterStatusManager」のクラスに情報をセットしていきます。習得する魔法に関しては、レベルと魔法の対応表から取得して、指定したレベルでの戦闘がちゃんと動作するようにします。

SetEnemyId()では敵キャラクターのIDを「BattleManager」に通知しています。IDからステータス情報をセットする処理に関しては「BattleManager」から別のクラスに処理を任せる予定なので、ここではIDだけ伝えられればOKです。

StartBattle()では準備が完了したことを「BattleManager」に通知しています。敵キャラクターのIDだけ伝えればOKならこのメソッドの引数にしてしまう手もありますが、チュートリアル後の拡張を考えた時に、敵キャラクターが複数いるケースを作るとなるとリスト形式で渡すなどの引数の変更が発生することから、値のセットと完了の通知は分けています。

SetEnemyId()とStartBattle()ではまだ存在しないメソッドを呼び出してエラーになっているかと思いますので、続けて「BattleManager」にメソッドを追加しましょう。

 

BattleManagerへのメソッドの追加

戦闘が発生した情報を受け取るために、「BattleManager」にメソッドを追加します。追加するのは、上の「BattleTester」から呼び出したい以下の2つのメソッドです。

  • 敵キャラクターのステータスを準備するメソッド
  • 戦闘開始の通知を受け取るメソッド

これらは以下のように実装しました。

前回作成したものの末尾にメソッドを2つ追加しました。

SetUpEnemyStatus()では引数のIDを「BattleManager」のフィールドにセットしています。メソッド名でお気づきかもしれませんが、受け取ったIDをもとに敵キャラクターのステータス情報のセットアップも行いたいと考えています。実際には別のクラスにその作業をさせるので、このタイミングで呼び出すイメージです。

StartBattle()では「BattleManager」から他のクラスに対して各種の準備作業を呼び出していく想定です。今回はまず「BattleTester」から処理が呼び出せたことを確認したいので、コンソールにメッセージを表示するようにしました。

 

スクリプトのアタッチ

作成したスクリプトをゲームオブジェクトにアタッチしていきます。Hierarchyウィンドウの「Managers」の下に2つの空のゲームオブジェクトを作成し、それぞれ [ResourceLoader] 、[BattleTester] と名前を変更します。

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

 

Hierarchyウィンドウで「ResourceLoader」を選択し、Inspectorウィンドウから [ResourceLoader] のスクリプトをアタッチします。

スクリプトのアタッチ
スクリプトのアタッチ

 

同様にHierarchyウィンドウで「BattleTester」を選択し、Inspectorウィンドウから [BattleTester] のスクリプトをアタッチします。「BattleManager」への参照もアサインしておきましょう。

BattleManagerへの参照もアサイン
BattleManagerへの参照もアサイン

 

動作確認

スクリプトをアタッチしたら動作を確認していきましょう。今回確認したいのは、

  • 「BattleTester」から戦闘機能が呼ばれること
  • キャラクターの情報のセットアップ時にエラーなく処理が行われること
  • 「BattleManager」のStartBattle()のメソッドが呼ばれること

の3点です。

1点目は、ゲーム実行時に「BattleTester」の「Execute Battle」をtrueにして確認しましょう。

2点目は、定義データ類がロードされていればエラーなく進む想定です。もしエラーが発生したら、各定義データの管理クラスや、Addressablesの設定、ラベル名の設定などを見直していきましょう。

3点目は、単純にコンソールにメッセージが表示されることを確認します。

ゲームを実行して、以下のように「BattleManager」側で実装したメッセージが表示されればOKです。

OK 戦闘開始OK!!
OK 戦闘開始OK!!

 

今回のブランチ

 

まとめ

今回はテスト用に戦闘を開始するための処理を作成しました。戦闘機能を作っていく際は、簡単に動作確認を行えるようにしておくとスムーズに作業が進みます。

次回は戦闘開始時の処理を担当するクラスを作成していきます。このクラス内では、他の様々なクラスの処理を呼び出したいので、まずは枠組みだけ作って、必要なクラスを作っていく流れになりそうです。

     

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

CTA-IMAGE

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


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


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