【Unity】3DダンジョンRPGの作り方 第5回|キャラクターデータと戦闘システムの実装 | Unity入門の森 ゲームの作り方

【Unity】3DダンジョンRPGの作り方 第5回|キャラクターデータと戦闘システムの実装

Unity 3DダンジョンRPGの作り方 ~世界樹・ウィザードリィ風ゲームを作ろう~

現場レベルのゲーム制作が、すべてここで学べます。

【永久会員チケット】

永久会員チケット|Unity入門の森

全講座を見放題で学ぶ

ソースコード・素材・プロジェクトすべて公開。
Unityの基礎から応用まで、一生使えるスキルを体系的に習得。

この講座は3Dダンジョン探索型RPGの作り方について説明しています。今回はその第5回目になります。

前回は戦闘画面用のシーンを新規作成し、そこで表示するUIオブジェクトを用意していきました。

前回の記事:

Unity 3DダンジョンRPGの作り方4 複数パーティー戦闘画面の作成【前衛・後衛あり】
この講座では3Dダンジョン探索型RPGの作り方について説明しています。今回はその第4回目になります。前回はプレイヤーオブジェクトとミニマップを実装し、自由にダンジョン内を探索できるようになりました。前回の記事:ダンジョンシステムの開発はここ...

ここからは主にスクリプトを拡張し、戦闘システムの実現に向けて順番に開発を進めていきます。

【ゲームの作り方講座プレゼント中!】

キャラクターデータを定義・作成

戦闘シーンで使用される味方(アクター)および敵(エネミー)のデータはそれぞれキャラクターデータ(ScriptableObjectのクラス)として作成し扱います。

アクターとエネミーで必要になるパラメータが異なることもあれば共通することもあります。共通するパラメータの例として現在・最大HPや状態異常、行動速度などがあります。

アクタークラスとエネミークラスを完全に別のクラスとして作成しても問題はありませんが、前述した共通部分をまとめた1つのベースクラスから作成し、アクタークラス・エネミークラスについてはベースクラスから派生する形にした方が管理がしやすくスマートです。

基底クラス・派生クラスとは?

C#で開発を行うにあたって、似ているけれど少しだけ機能が違うクラスを複数作る場合があります。

前述のように、アクターもエネミーも同じキャラクターというくくりで扱う事ができるのもその一例です。

このような場合にはC#の機能の1つである継承という仕組みを用いて基底クラスや派生クラスを作成するのが便利です。

 

継承とは、あるクラスが持つ機能(変数やメソッド)を、別のクラスがそのまま受け継いで利用できる仕組みのことです。

この時、機能の元となる設計図のようなクラスを「基底クラス」(または親クラス)、その設計図を受け継いで作られるクラスを「派生クラス」(または子クラス)と呼びます。

基底クラスと派生クラスの例

この例では基底クラスとしてCharacterを定義し、その下ではそれを継承する形でWarriorクラスを定義しています。

クラス名を宣言する部分の右側を :(コロン) で区切り、その右に継承元のクラス名を書きます。普段はMonoBehaviourやScriptableObjectなどを入れている場所です。

このようにする事でクラスの継承が行え、継承元が持っている変数やメソッドをそのまま引き継ぐようになります。

virtual と override

基底クラスの機能を受け継ぐだけでは、どの派生クラスも全く同じ動きしかしません。「攻撃する」という処理を、キャラクターの種類(派生クラス)ごとに違う内容にしたい場合があります。

そんな時に使うのがvirtualoverrideです。

  • virtual:基底クラスのメソッドに付けて、「このメソッドは、派生クラスで処理内容を上書き(オーバーライド)しても良いですよ」と許可を与えるキーワードです。

  • override:派生クラスのメソッドに付けて、「基底クラスのvirtualが付いたメソッドを、このクラス独自の処理で上書きします」と宣言するキーワードです。

このように設定すると、MagicianクラスのインスタンスでAttack()を呼び出すと「魔法で攻撃!」と表示されるようになります。

難しい言葉が並びましたが、ひとまず「クラスの機能を使い回しつつ、一部だけ独自のものに変える仕組み」という認識で問題ありません。

この仕組みを上手く使うことでコードの重複を減らし、より整理されたプログラムを作ることができるようになります。今後の講座でも登場しますので少しずつ慣れていきましょう。

(関連記事:UnityC# クラスの継承・抽象メソッドとオーバライド is, as, null, this, baseの使い方も解説

UnityC# クラスの継承・抽象メソッドとオーバライド is, as, null, this, baseの使い方も解説
今回の記事ではクラスの継承についてみていきます。Unityではコンポーネント自体がUnityEngine.MoneBehaviourを継承したものなので実は既に使用している機能になります。さらにUnityEngine.MonoBehavio...

キャラクターデータのベースクラス作成

それでは最初にベースクラスとなるCharacterDataクラスを作成しましょう。フォルダ分けをする場合はScripts/Definesフォルダ以下に作成するのが良いでしょう。

CharacterData.cs (新規)

  • 7行目の[System.Serializable]は、今後このデータをゲーム内でセーブ&ロードする機能を実装する時に必要になります。

アクターもエネミーも共通で持つことになるであろうパラメータを1つずつ定義しました。

またScriptableObjectでデータを作成することを想定し、HPやTPの現在値などはInspectorで表示しないようにしています。

 

これだけでも戦闘システムを作成するにあたって必要最低限のものは揃っていますが、のちほど状態異常のシステムを実装したり、一時的に変化したパラメータを取得する機能(たとえば装備によって上昇する攻撃力など)を取得するための拡張の余地が欲しいです。

C#の基底クラス・派生クラスの仕組みをうまく活用し、今後の拡張を行いやすい形を整えていきましょう。

CharacterData.cs

主に以下の拡張を加えています。

  • 状態異常の種類および攻撃の属性をenumで定義。
  • 「現在かかっている状態異常」を、残りターン数とともにDictionaryで管理。
  • 状態異常Dictionaryを操作し、状態異常の追加や残りターン数の更新を行えるメソッドを追加。
  • 現在の各パラメータ(攻撃力など)を取得するためのGet系メソッドを追加。virtualプロパティを付与することで上書き可能にする。
  • 属性ダメージの計算式を追加。戦闘システムの深い部分を実装する時に関わってくる。今は無視してOK。その属性の耐性値が高いほど、その属性から受けるダメージが減少するようにしている。

状態異常および属性の種類(enum)はクラス外で定義しています。他のファイルからよく参照する情報になるためクラス外に置いていますが、本来はファイルごと分けた上でnamespaceで区切った方が好ましいです。

 

状態異常の管理はDictionaryで行っています。単にそのキャラクターが抱えている状態異常を保存したいだけならList<CharacterState>を使用する事で実現可能ですが、実際には状態異常の種類だけでなく「あと何ターンで解除されるか(残りターン数)」という情報もそれぞれペアで持っておきたいですね。

Dictionaryを使用すると、任意の型でKey(キー)とValue(値)のペアの情報をリストとして管理できます。Keyは一意(他の要素と重複しない)のものである必要がありますが、これによりKeyを渡せばそれに対応するValueを取得する事ができます。

ここで用意したメソッドは戦闘システム実装の際にターン経過処理時に呼び出されるようにします。

 

攻撃力などのパラメータの現在値を取得するメソッドもそれぞれ用意しています。virtual属性を付けることによって、この後作成する派生クラスにて拡張できる形にしています。

今はあまり入り組んだ仕様にはしないため基本的にbaseの変数をそのまま返すようにしていますが、例えば速度取得メソッドのように「特定の状態異常にかかっているなら値に補正を掛けてから返す」ような機能が必要であればここで用意しておくと良いでしょう。

アクターデータクラス作成

このCharacterDataクラスから継承した、アクターデータを管理するクラスを作成しておきましょう。

ActorData.cs (新規)

5つの変数しか宣言していませんが、CharacterDataがもつ全ての変数もこのクラスは併せ持っている形になります。

このActorDataクラスはすぐには使用しませんが、どの職業に就いているかや立ち絵を番号で指定できるようにし、レベルと経験値を保存するようにしています。

 

なおScriptableObjectも間接的に継承しているためアセットとして作成できるようにすることも可能ですが、アクターデータは全てプログラム内で作成されるので今回は不要です。

エネミーデータクラス作成

続けてエネミーデータを管理する方のクラスも作成してみましょう。

EnemyData.cs (新規)

エネミーのデータについては、それぞれScriptableObjectで予め用意しておく必要があるためそれを踏まえた設定をしています。

立ち絵画像をInspectorから指定できるようにする事でこの後の表示確認に用いていきます。

エネミーデータのScriptableObject作成

エネミーデータクラスのScriptableObjectを作成できるようになったので、ここで試しに1~2体分のデータを用意してみましょう。

アセットはCreate→Dungeon→EnemySOの順にクリックで作成が可能です。ScriptableObjectフォルダ以下にエネミーデータ格納用のフォルダを用意しておく事をおすすめします。

Inspectorを開くと、EnemyDataクラス内で用意した5つの項目の他にCharacterDataクラスのパラメータのほとんどが表示されていることを確認できるはずです。これらの値を編集してエネミーのデータを作成していきます。

値の設定にあたってのポイントは以下です。

  • HPやTP、攻撃力などのパラメータ(速度と耐性以外)は基礎値を入力します。各キャラクターのレベル1のパラメータにはそれぞれ基礎値の5倍の値がセットされ、1レベル上昇するごとに基礎値分の値が追加されます。
  • 属性耐性値(Resist_)はレベルによって変化しません。0で耐性なし、1で耐性あり(ダメージ無効)、-1で弱点(ダメージ2倍)になります。
  • Enemy_Name_JPには日本語でのエネミー名、Enemy_Name_ENには英語でのエネミー名を入力します。今後ローカライズ機能を実装する時に用いられます。
  • 立ち絵画像は好きな画像を使用してください。
  • 顔グラフィック画像も同様に任意の画像を使用可能ですが、アスペクト比(縦横比)が 2:1 の画像が好ましいです。(例:横幅150px・縦幅75pxの画像)
  • Enemy_ExpおよびEnemy_Goldは、その敵1体を撃破した時の獲得経験値量・獲得ゴールド量を設定します。今は適当な値でOKです。

複数の敵との戦闘もテストできるようにするため、もう1体ほど作っておくと良いでしょう。バランス調整は後で行えば良いため値は深く考える必要はありません。

戦闘シーンにエネミーを表示する

立ち絵画像の情報をともなったエネミーのデータを用意できたので、シーン開始時(戦闘開始時)にエネミーインスタンスを作成して表示する所までを行ってみましょう。

まずはBattleシーンにおけるエネミー管理クラスとしてEnemyManagerを作成します。ここではエネミーデータにまつわる全般を扱います。

EnemyManager.cs (新規)

続きを読む

このコンテンツはパスワードで保護されています。 コンテンツを読みたい方はUnity入門の森ショップ(https://unityforest.shop/)で講座閲覧権を取得してね。

まとめ

基底クラスや派生クラス、シングルトンの機能を活かしてキャラクターやゲームデータを取り扱うクラスを作成しました。

引き続き戦闘システムの開発を続け、アクターやエネミーが通常攻撃を行える状態を目指していきます。

次の記事:

【Unity】3DダンジョンRPGの作り方 第6回|スキルシステムとダメージ処理の実装
この講座は3Dダンジョン探索型RPGの作り方について説明しています。今回はその第6回目になります。前回は戦闘シーンに敵キャラクターやプレイヤーパーティーのデータクラスを構築し、Scriptable Objectを用いてステータス管理を行う方...

Unity 3DダンジョンRPGの作り方講座に戻る >>

【ゲームの作り方講座もプレゼント中!】

現場レベルのゲーム制作が、すべてここで学べます。

【永久会員チケット】

永久会員チケット|Unity入門の森

全講座を見放題で学ぶ

ソースコード・素材・プロジェクトすべて公開。
Unityの基礎から応用まで、一生使えるスキルを体系的に習得。

コメント

タイトルとURLをコピーしました