【Unity】RPGを作るチュートリアルその51 戦闘中の敵キャラクターの状態を管理するクラス

【Unity】RPGを作るチュートリアルその51 戦闘中の敵キャラクターの状態を管理するクラス

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

第50回では選択されたコマンドに応じて行動を登録するためのクラスを作成しました。

今回は敵キャラクターの行動を決定するにあたって、敵キャラクターの戦闘中のステータスを保持するクラスを作成していきます。

 

 

制作環境

MacBook Pro 2023 Apple M2 Max

Unity6 (6000.0.30f1) Silicon

 

作業内容と順序

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

 

チュートリアルの一覧

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

 

前回の内容

前回は選択されたコマンドに応じて行動を登録するためのクラスを作成しました。

 

戦闘中の敵キャラクターの状態を保持するクラス

キャラクターと同様に、敵キャラクターについても現在HPやMPを保持するクラスを作成します。必要な項目としては、

  • 敵キャラクターのID
  • 敵キャラクターの戦闘中の通しID
  • 敵キャラクターの定義データ
  • 現在のHP
  • 現在のMP
  • 敵キャラクターが倒されたフラグ
  • 敵キャラクターが逃げたフラグ

あたりです。敵キャラクターのIDは定義データで設定したID、戦闘中の通しIDは出現順に割り振られるIDです。ドラクエでいうスライムA、スライムB、といった区別に該当します。

敵キャラクターが倒されたフラグがtrueなら、戦闘終了時に経験値やゴールドの計算対象として、逃げたフラグがtrueなら計算対象としないようにします。

このクラスについては、後ほど作成する敵キャラクターの状態全体を管理するクラスでリスト形式で保持するようにします。今回のチュートリアルの範囲では1対1なのでそこまでいらない気もしますが、拡張性を考慮してこの形にしています。

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

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

 

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

内容としては、上で列挙した項目をそのままフィールドにした形になっています。

 

戦闘中の敵キャラクターの状態全体を管理するクラス

続いて、敵キャラクターの状態全体を管理するクラスを作成していきます。キャラクターのステータスのように、個別の敵キャラクターのステータスをリスト形式で保持するのに加えて、便利な計算クラスも用意していきます。

  • 敵キャラクターのステータス一覧を初期化するメソッド
  • 敵キャラクターのステータス一覧を取得するメソッド
  • 敵キャラクターのステータスを戦闘中のIDで取得するメソッド
  • 戦闘中の敵キャラクターのうち、最大の戦闘中IDを取得するメソッド
  • 敵キャラクターのステータスをセットするメソッド
  • 敵キャラクターのステータスを変更するメソッド
  • 敵キャラクターが倒れたかどうかを取得するメソッド
  • 引数の敵キャラクターが倒れたフラグをセットするメソッド
  • 引数の敵キャラクターが逃げたフラグをセットするメソッド
  • 全ての敵キャラクターが倒れた、または逃げたかどうかを取得するメソッド

あると便利そうな機能を用意してみました。フラグの確認系は戦闘終了の判断にも関わってくるので、簡単に取得できるようにしておくと便利です。

キャラクターのステータスを管理するクラスについてはstaticなクラスとして実装しましたが、敵キャラクターに関しては戦闘中に使うのみなので、MonoBehaviourで実装したいと思います。

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

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

 

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

「_enemyStatuses」のリストに敵キャラクター個別のステータス情報を保持します。

InitializeEnemyStatusList()を使って、リストを初期化するようにしています。これは戦闘終了時に呼ぶ想定です。

GetEnemyStatusList()ではリストをそのまま返すようにしています。リストのフィールドはprivateなので、Get用途のメソッドを用意しています。

GetEnemyStatusByBattleId()は戦闘中IDに対応する敵キャラクターのステータスを取得します。

GetMaxBattleId()はIDの最大値を取得するメソッドです。戦闘中IDを割り振る際に、現在割り振られているIDの最大値を取得する形になります。リストの中身がない場合は-1を返すようにしています。新しくIDを割り当てる際には、このメソッドで取得したIDに1を加えて割り当てるようにします。なので、一番最初の敵キャラクターの戦闘中IDは0が割り当てられます。

SetUpEnemyStatus()では敵キャラクターの定義データをもとにステータス情報を作成していきます。このメソッド内で先ほどのGetMaxBattleId()を呼んで、戦闘中IDを割り当てています。

ChangeEnemyStatus()は敵キャラクターのステータスを変更するメソッドです。引数としてHPの変化量とMPの変化量を渡し、現在HPや現在MPを変更するようにしています。

IsEnemyDefeated()では現在HPを使って撃破されたかどうかを返します。

OnDefeatEnemy()でフラグを実際にセットしています。OnDefeatEnemy()は逃走フラグをセットします。

IsAllEnemyDefeated()はリスト内の敵キャラクターを確認して、すべての敵キャラクターで撃破フラグまたは逃走フラグがたっている場合にtrueを返します。主に戦闘終了の確認用のメソッドです。

 

既存のクラスの修正

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

  • BattleManager

です。

 

BattleManagerの修正

「BattleManager」では参照用のフィールドを追加するのと、参照を返すメソッド、敵のステータスセットアップの呼び出しなどを追加していきます。

まずはフィールドを追加します。「_characterMoverManager」の下に新しく追加しておきましょう。

 

続いてSetUpEnemyStatus()のメソッドで「EnemyStatusManager」で実装したSetUpEnemyStatus()を呼びます。これによって戦闘中の敵キャラクターのIDが割り当てられるようになります。

 

また、参照を返すメソッドも用意しておきます。既存のGetBattleSpriteController()のメソッドの下に入れておきましょう。

 

スクリプトのアタッチ

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

 

EnemyStatusManagerのアタッチ

Hierarchyウィンドウから「BattleParent」の下にある「Managers」のゲームオブジェクトを選択します。「Managers」の下に、空のゲームオブジェクトを作成しましょう。名前は [EnemyStatusManager] にしました。

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

 

Inspectorウィンドウで今回作成した「EnemyStatusManager」をアタッチします。

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

 

BattleManagerへのアサイン

続いて、「BattleManager」に「EnemyStatusManager」への参照をアサインします。

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

 

動作確認

今回は戦闘を開始してエラーがないことだけ確かめておきましょう。

 

今回のブランチ

 

まとめ

今回は敵キャラクターの行動を決定するにあたって、敵キャラクターの戦闘中のステータスを保持するクラスを作成しました。撃破判定などもこのクラスを使って行います。

次回は敵キャラクターの行動を決定するクラスを作成していきます。

     

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

CTA-IMAGE

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


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


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