この講座はUnityとC#で作るタクティクス戦略シミュレーションRPGの作り方について解説する講座の第15回です。
前回でターン制ストラテジーシステムのゲーム管理処理(ゲームオーバー・ゲームクリア等)を実装し、繰り返し遊べるようになりました。
前回の記事:
前回までに完成させたこのゲームをさらに充実させるために追加要素を実装していきます。ここでさらに本格的なSRPGに仕上げていきましょう。
今回は味方のキャラクターごとに個別の特技スキルを付与し、攻撃の代わりのコマンドとして使用できるようにします。スキルを作ることで各キャラクターごとに個性を持たせ、戦略性をグッと高めることが可能です。
回数制限型の強化攻撃・バフ・デバフ・回復魔法・遠隔攻撃とSRPGで作りたくなる代表的なスキルを開発していきます。
辞書型とstaticクラスと列挙体で特技を定義する
まずは実装したい特技の名称を定義してから処理に組み込んでいく流れになります。
サンプルでは味方の数は3人なので3つ分の特技を用意すればOKですが、オマケとして以下の4つの実装方法を紹介していきます。
特技 | 定義名 | 説明 |
会心の一撃 | Critical | ダメージが2倍になる攻撃(1回しか使えない) |
シールド破壊 | DefBreak | 攻撃対象の防御力を0にする(特技を発動した戦闘のダメージは0) |
ヒール | Heal | 攻撃対象のHPを回復する(回復量はAtkの半分) |
ファイアボール | FireBall | 位置関係を無視して任意の敵をダメージ半減で攻撃する |
これらをどこで定義するかについては、11章で学んだようなstaticクラスを作成してその中に列挙型での定義と特技名までを設定していきます。
それではスキル定義専用のクラスSkillDefineを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
using System.Collections; using System.Collections.Generic; public static class SkillDefine { // 特技の種類を定義 public enum Skill { _None, // スキル無し Critical,// 会心の一撃 DefBreak,// シールド破壊 Heal, // ヒール FireBall, // ファイアボール } } |
staticクラスでの定義ですので、このスクリプトをシーン内のオブジェクトにアタッチする必要はありません。また、この定数値を他のクラスから参照する時にもクラス名を書くだけでOKになります。
さて、今の状態ではあくまで定数値ですので数字の情報しか持っていません。ゲーム上では特技名と説明文もあわせて表示したいので、「定数値と名前」「定数値と説明文」をそれぞれ紐づける何かがあると便利ですね。
C#ではその方法の1つとしてDictionary(辞書型)というものが存在します。DictionaryではKey値とValue値をセットで配列に定義する事ができ、Key値を渡せばそれに対応するValue値が返ってくるというものになります。
この2つは異なる型であっても良いため、Keyを上記のSkill型でセットして名前や説明文をstring側でvalue側にセットすれば紐づけが完了します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using System.Collections; using System.Collections.Generic; public static class SkillDefine { // 特技の種類を定義 public enum Skill {// 37個 _None, // スキル無し Critical,// 会心の一撃 DefBreak,// シールド破壊 Heal, // ヒール FireBall, // ファイアボール } // Dictionaryで特技定義と各データを紐づける // 特技名 public static Dictionary<Skill, string> dic_SkillName = new Dictionary<Skill, string> () { {Skill._None, "スキル無し"}, {Skill.Critical, "会心の一撃"}, {Skill.DefBreak, "シールド破壊"}, {Skill.Heal, "ヒール"}, {Skill.FireBall, "ファイアボール"}, }; // 表示する説明文 public static Dictionary<Skill, string> dic_SkillInfo = new Dictionary<Skill, string> () { {Skill._None, "----"}, {Skill.Critical, "ダメージ2倍の攻撃\n(1回限り)"}, {Skill.DefBreak, "敵の防御力を0にします\n(ダメージは0)"}, {Skill.Heal, "味方のHPを回復します"}, {Skill.FireBall, "どの位置に居る敵も攻撃できます\n(ダメージは半分)"}, }; } |
この実装によって、例えばdic_SkillName[Skill.Heal]と呼べば「ヒール」の文字列が返ってくるようになりました。
関連記事:辞書(ディクショナリー)の使い方 キーと値でデータを指定する
味方キャラクターに特技を割り当てる
定義が完了したらキャラクターそれぞれに特技を持たせておきます。データに変数を追加しInspectorから指定していきましょう。
Character.cs内 メンバ変数宣言部
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// メインカメラ private Camera mainCamera; // キャラクター初期設定(インスペクタから入力) [Header ("初期X位置(-4~4)")] public int initPos_X; // 初期X位置 [Header ("初期Z位置(-4~4)")] public int initPos_Z; // 初期Z位置 [Header ("敵フラグ(ONで敵キャラとして扱う)")] public bool isEnemy; // 敵フラグ // キャラクターデータ(初期ステータス) [Header ("キャラクター名")] public string charaName; // キャラクター名 [Header ("最大HP(初期HP)")] public int maxHP; // 最大HP [Header ("攻撃力")] public int atk; // 攻撃力 [Header ("防御力")] public int def; // 防御力 [Header ("属性")] public Attribute attribute; // 属性 [Header ("移動方法")] public MoveType moveType; // 移動方法 [Header ("特技")] public SkillDefine.Skill skill; // 特技 // ゲーム中に変化するキャラクターデータ [HideInInspector] public int xPos; // 現在のx座標 [HideInInspector] public int zPos; // 現在のz座標 [HideInInspector] public int nowHP; // 現在HP |
例では以下のような割り当てにしましたが、確認の際は自由に切り替えて試すと良いでしょう。
- 勇者:会心の一撃
- 戦士:シールド破壊
- 魔法使い:ヒール
特技を発動できるようにする
特技の発動は既に存在するコマンド「攻撃」「待機」に追加する3つ目の行動となります。まずはGUI上に特技ボタンを配置しましょう。
攻撃や待機のボタンUIをコピー&ペーストし、画面の左下に配置します。(Anchorも左下を基点に合わせるようにしましょう。)オブジェクト名はSkillCommandとしました。
続いて特技の名前と説明文を表示するTextUIオブジェクト(SkillText)を作成します。Canvasの子オブジェクトとして作成しましょう。ボタンよりも右側の位置に、多少文字数が多くなっても問題なく表示できるように設定しましょう。
文章については、特技名を書いた後に改行して説明文までを全てこのUIで表示します。この特技名を表示する部分のみフォントサイズを大きくする方法があるのであわせて実装すると以下のような表示内容になります。
1 2 |
<size=40>特技名</size> 特技の説明文 |
文章内を<size=(大きさ)></size>で囲うとその部分のみ指定の大きさに変化します。このような機能をRich Textと呼び、他にも以下のような種類があります。
- <b></b> … 囲った部分が太字になります。
- <color=(色コード)></color> … 囲った部分の文字色が変わります。
スクリプトで説明文を表示する
それではGUIマネージャ側から特技ごとに文章を分けて表示できるようにしましょう。表示内容の変更は全コマンドボタンが表示されるタイミングで行えばOKです。
GUIManager.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; // UIコンポーネントを扱うのに必要 using DG.Tweening; public class GUIManager : MonoBehaviour { // ステータスウィンドウUI public GameObject statusWindow; // ステータスウィンドウオブジェクト public Text nameText; // 名前Text public Image attributeIcon; // 属性アイコンImage public Image hpGageImage; // HPゲージImage public Text hpText; // HPText public Text atkText; // 攻撃力Text public Text defText; // 防御力Text // 属性アイコン画像 public Sprite attr_Water; // 水属性アイコン画像 public Sprite attr_Fire; // 火属性アイコン画像 public Sprite attr_Wind; // 風属性アイコン画像 public Sprite attr_Soil; // 土属性アイコン画像 // キャラクターのコマンドボタン public GameObject commandButtons; // 全コマンドボタンの親オブジェクト public Button skillCommandButton; // 特技コマンドのButton public Text skillText; // 選択キャラクターの特技の説明Text // バトル結果表示UI処理クラス public BattleWindowUI battleWindowUI; // 各種ロゴ画像 public Image playerTurnImage; // プレイヤーターン開始時画像 public Image enemyTurnImage; // 敵ターン開始時画像 public Image gameClearImage; // ゲームクリア画像 public Image gameOverImage; // ゲームオーバー画像 // 移動キャンセルボタンUI public GameObject moveCancelButton; // フェードイン用画像 public Image fadeImage; void Start () public void ShowStatusWindow (Character charaData) public void HideStatusWindow () /// <summary> /// コマンドボタンを表示する /// </summary> /// <param name="selectChara">行動中のキャラクターデータ</param> public void ShowCommandButtons (Character selectChara) { commandButtons.SetActive (true); // 選択キャラクターの特技をTextに表示する SkillDefine.Skill skill = selectChara.skill; // 選択キャラクターの特技 string skillName = SkillDefine.dic_SkillName[skill]; // 特技の名前 string skillInfo = SkillDefine.dic_SkillInfo[skill]; // 特技の説明文 // リッチテキストでサイズを変更しながら文字を表示 skillText.text = "<size=40>" + skillName + "</size>\n" + skillInfo; } public void HideCommandButtons () public void ShowLogo_PlayerTurn () public void ShowLogo_EnemyTurn () public void ShowMoveCancelButton () public void HideMoveCancelButton () public void ShowLogo_GameClear () public void ShowLogo_GameOver () public void StartFadeIn () } |
Inspectorから説明文UIの参照をセット(SkillText)するのと同時に特技ボタンUIの参照もセット(SkillCommandButton)しておきます。こちらは後ほど特技の使用可否を実装する時に扱います。
コマンドボタン表示メソッドShowCommandButtonsに渡すべき引数が増えたのでゲームマネージャ側も修正しておきます。
SRPGのバフ・デバフ・回復・遠隔攻撃処理の作り方まとめ
以上4種の特技の実装が無事終わりました。対象を選ぶタイプの特技ならこのように拡張していけば簡単に実装できるので是非オリジナルの特技も開発してみてください!
また敵のAIを拡張すれば敵にも特技の発動を行わせる事が出来るようにもなります。こちらもやる気があればチャレンジしてみるのも良いでしょう。
次回はいわゆる周回要素として、ゲーム終了後にキャラクターの能力を上昇させられるシーンを作成します。
また、その上昇状態をゲームを閉じても保持する機能もあわせて実装していきます。
次の記事:
コメント