現場レベルのゲーム制作が、すべてここで学べます。
この記事はUnity入門の森のノンフィールドRPG講座で作ったゲームを改良アップデートしてSlay the Spire風デッキ構築系オリジナルJRPGを作る講座の第10回目です。
前回は取得したレリックや状態異常のアイコンを表示する実装を行いました。
前回の記事:

ですが、まだUI部分の表示部分のみで実際の数値としては状態が反映されていませんでした。そこで、第10回では取得したレリックや状態異常の内容を能力に反映させます。
また、状態異常になった時のサウンド処理もここで行っておきます。
サウンドを増やす
まずは[Assets]→[Scenes]にある[Title]をダブルクリックしてタイトルシーンを開きます。
バフカードやデバフカードを使ったときに再生する効果音の準備をします。
ScriptsフォルダにあるSoundManager.csを修正します。
SoundManager.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
using UnityEngine; public class SoundManager : MonoBehaviour { public static SoundManager Instance; private AudioSource[] audioSources;// アタッチした2つのAudioSorceを代入 private AudioSource audioSource; private AudioSource bgmSource;// BGM用のAudioSource public AudioClip TitleBGM; public AudioClip DungeonBGM; public AudioClip BattleBGM; public AudioClip ResultBGM; public AudioClip TouchSE; public AudioClip RecoverySE; public AudioClip DamageSE; public AudioClip EnemyDamageSE; public AudioClip GuardSE; public AudioClip LevelupSE; public AudioClip BuffSE;// (追加)バフの効果音 public AudioClip DebuffSE;// (追加)デバフの効果音 private void Awake() { if (Instance == null) { Instance = this; audioSource = GetComponent<AudioSource>();// コンポーネントの取得 audioSources = GetComponents<AudioSource>();// アタッチした2つのAudioSourceを配列で取得 audioSource = audioSources[0];// 1つめを効果音用にする bgmSource = audioSources[1];// 2つめをBGM用にする DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { } // Update is called once per frame void Update() { } private void PlayBgm(AudioClip audioClip) { if (bgmSource.clip == audioClip) return;// すでに再生されているBGMなら処理しない bgmSource.clip = audioClip; bgmSource.Play(); } public void PlayTitleBGM() { PlayBgm(TitleBGM); } public void PlayDungeonBGM() { PlayBgm(DungeonBGM); } public void PlayBattleBGM() { PlayBgm(BattleBGM); } public void PlayResultBGM() { PlayBgm(ResultBGM); } public void PlayTouchSE() { audioSource.PlayOneShot(TouchSE); } public void PlayRecoverySE() { audioSource.PlayOneShot(RecoverySE); } public void PlayDamageSE() { audioSource.PlayOneShot(DamageSE); } public void PlayEnemyDamageSE() { audioSource.PlayOneShot(EnemyDamageSE); } public void PlayGuardSE() { audioSource.PlayOneShot(GuardSE); } public void PlayLevelupSE() { audioSource.PlayOneShot(LevelupSE); } public void PlayBuffSE()// (追加)バフの効果音を再生するメソッド { audioSource.PlayOneShot(BuffSE); } public void PlayDebuffSE()// (追加)デバフの効果音を再生するメソッド { audioSource.PlayOneShot(DebuffSE); } public void StopBGM() { bgmSource.Stop();// BGMを止める } } |
SoundManagerにオーディオクリップをアタッチする
Hierarchyウィンドウにある[SoundManager]オブジェクトをクリックして、Inspectorビューを表示します。[BuffSE]と[DebuffSE]が表示されているので、下の画像のとおりアタッチします。

効果音素材は[Assets/Leohpaz/RPG_Essentials_Free/8_Buffs_Heals_SFX]の中にあります。
レリックと状態異常の効果を反映する
取得したレリックと状態異常がキャラクターに反映されるようにします。ScriptsフォルダからUnitStatus.csを開きます。
UnitStatus.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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
using System.Collections.Generic; using UnityEngine; [System.Serializable] public class UnitStatus { public string ID; public int Level; public int Exp; public int HP; public bool IsGuard = false;// ガードしているかどうか public int SP;// スキルポイント public int GP;// ガードポイント public List<string> Deck = new List<string>();// 所有しているカード public List<string> Hand = new List<string>();// 配布されたカード public List<ConditionStatus> Conditions = new List<ConditionStatus>();// 状態異常のリスト public List<string> Relics = new List<string>();// 所有しているレリック public UnitStatus(string id, int bonus, List<string> deck)// 所有カードを指定して初期化 { ID = id; Level = GameConstants.StartLevel + bonus;// レベルの初期値にボーナスを加えて初期化 Exp = 0; HP = GetMaxHP(); Deck = deck;// キャラクターの初期カード } // 最大HPを取得する public int GetMaxHP() { if (ID == "HERO") { return GameConstants.HeroBaseHp + Level * GameConstants.HeroRateHp; } else { return GameConstants.EnemyBaseHp + Level * GameConstants.EnemyRateHp; } } // 回復量を取得する public int GetRecovery() { return (int)(GetMaxHP() * GameConstants.RecoveryRate);// 最大HPをRecoveryRateの割合だけ回復 } // 回復 public void Recovery() { HP += GetRecovery(); if (HP > GetMaxHP()) HP = GetMaxHP();// 最大HPを超えないようにする } // 割合回復 public void RecoveryRate(int rate) { HP += Mathf.CeilToInt(GetMaxHP() * (rate * 0.01f)); if (HP > GetMaxHP()) HP = GetMaxHP();// 最大HPを超えないようにする } // 攻撃力を取得する(変更) public int GetAttack() { int basePower = 0; if (ID == "HERO") { basePower = GameConstants.HeroBaseAttack + Level * GameConstants.HeroRateAttack; } else { basePower = Level;// 敵キャラはレベルがそのまま攻撃力 } int relicPower = Mathf.CeilToInt(basePower * GetRelicPower("Hammer") * 0.01f);// レリック「ハンマー」の効果 int conditionPower = GetCondition("AttackUp");// 状態異常「攻撃力アップ」の効果 return basePower + relicPower + conditionPower; } // 防御力を取得する(変更) public int GetDefense() { int basePower = 0; if (ID == "HERO") { basePower = GameConstants.HeroBaseDefense + Level * GameConstants.HeroRateDefense; } else { basePower = Level;// 敵キャラはレベルがそのまま防御力 } int relicPower = Mathf.CeilToInt(basePower * GetRelicPower("Shield") * 0.01f);// レリック「盾」の効果 int conditionPower = GetCondition("DefenseUp");// 状態異常「防御力アップ」の効果 return basePower + relicPower + conditionPower; } // (追加)バフ・デバフの効果量を取得する public int GetBuffDebuffPower() { return Level;// バフ・デバフの効果量はレベルに比例させる } // HPを減らす(GPで相殺して減った値を返す) public int SetDamage(int damage) { if (IsGuard) damage = 0;// 完全ガード if (GP >= damage)// GPでのダメージの相殺 { GP -= damage; damage = 0; } else { damage -= GP; GP = 0; } HP -= damage; if (HP < 0) HP = 0; return damage;// 減った値を返す } // 獲得できる経験値(敵キャラのみ使用) public int GetExp() { return Level;// レベルがそのまま経験値となる } // 次のレベルアップに必要な経験値(主人公のみ使用) public int GetNextExp() { return Level * Level;// 計算式は「現在のレベル × 現在のレベル」 } // レベルアップしたかどうかの判定(レベルアップしたらTrueを返す) public bool LevelUp() { if (Exp >= GetNextExp()) { Exp -= GetNextExp();// 必要経験値を減らしておく Level++; return true; } return false; } // カードを配布する処理 public void Deal(int dealNum) { // デッキのインデックスリストを作成 List<int> indices = new List<int>(); for (int i = 0; i < Deck.Count; i++) { indices.Add(i); } // 指定枚数分、インデックスリストからランダムに抽出 for (int i = 0; i < dealNum && indices.Count > 0; i++) { int randomIndex = Random.Range(0, indices.Count);// インデックスリストの中からランダムな位置を選ぶ int deckIdx = indices[randomIndex];// 選ばれた「デッキの添字」を取得 Hand.Add(Deck[deckIdx]);// 手札にデッキの該当するカードを追加 indices.RemoveAt(randomIndex);// 選ばれたインデックスはリストから削除(重複回避) } } // 毎ターン呼ばれる public void StartTurn() { if (ID == "HERO") SP = GameConstants.HeroInitSP + GetRelicPower("Gauntlet");// (変更)SPのリセット、レリック「ガントレット」の効果 IsGuard = false;// 完全ガード状態のリセット GP = 0;// ガードポイントのリセット } // 戦闘終了のときに呼ばれる public void EndBattle() { Hand.Clear();// 配布されたカードを削除 IsGuard = false;// 完全ガード状態のリセット GP = 0;// ガードポイントのリセット Conditions = new List<ConditionStatus>();// (追加)状態異常のリセット } // (追加)状態異常の効果量を取得する public int GetCondition(string id) { foreach (ConditionStatus condition in Conditions) { if (condition.ID == id) return condition.Power; } return 0; } // (追加)状態異常を追加・更新する public void SetCondition(string id, int power) { foreach (ConditionStatus condition in Conditions) { if (condition.ID == id) { condition.AddPower(power); return; } } Conditions.Add(new ConditionStatus(id, power)); } // (追加)レリックの効果量を取得する public int GetRelicPower(string id) { foreach (string relic in Relics) { if (relic == id) return GameManager.Instance.RelicData.GetPower(id); } return 0; } } |
主な変更点・コードの意図
いくつかの修正点があるので説明していきます。
攻撃力・防御力の計算式の変更
|
1 2 3 4 5 6 7 8 9 |
// 攻撃力の計算 基本攻撃力 + レリック「Hammer」の効果(基本攻撃力の何%加算) + 状態異常「AttackUp」の効果量 // 防御力も同様 基本防御力 + レリック「Shield」の効果 + 状態異常「DefenseUp」の効果量 |
状態異常とレリックのパラメータを取り出す処理を追加
GetCondition() → 指定した状態異常の効果量を返す。なければ0
SetCondition() → 状態異常を追加する。すでにある場合はAddPower()で重ねがけ
GetRelicPower() → 指定したレリックを持っていれば効果量を返す。なければ0
GetBuffDebuffPower() → バフ・デバフの効果量をレベルに比例させる
ターン開始時と戦闘終了時の処理を追加
|
1 2 3 4 5 6 7 8 9 10 |
// ターン開始時 SP = GameConstants.HeroInitSP + GetRelicPower("Gauntlet"); // SPリセット+ガントレット効果 IsGuard = false; GP = 0; // 戦闘終了時 Hand.Clear(); IsGuard = false; GP = 0; Conditions = new List<ConditionStatus>(); // 状態異常リセット |
ターン開始時にレリック「ガントレット」を保有していればSPを効果量の分だけ上昇させます。
また、状態異常はターンをまたいで継続しますが、戦闘が終わると全てリセットされる設計です。
カードの種類を増やす
今しがた作成した攻撃力増加と防御力増加のバフ効果を実現するカードを追加してみましょう。
[Assets/Data/CardData]をクリックしてInspectorビューを表示します。以下の画像のとおりカードを2つ増やします。

CardController.cs
新しいカードごとの数値表示を追加します。
まとめ

今回はレリックや状態異常の効果を攻撃力・防御力の計算式に組み込み、実際のゲームプレイに反映させました。バフカードの追加とあわせて、デッキ構築型のRPGらしい戦略的なステータス強化の仕組みが完成しています。
次回はスクロール対応のデッキ画面UIを作成し、ダンジョン中にいつでも所有カードの一覧を確認できる仕組みを実装します。カードをタップすると詳細情報が表示される機能も組み込み、デッキ構築ゲームに必須のカード管理画面が完成します。
次の記事:

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







コメント