【Unity】RPG制作 その28-戦闘時の能力値処理実装
今回は戦闘時の能力値周りの処理を実装していきます。PlayerManager.csに戦闘時に実際に参照される能力値を保持するDictionaryを新しく作成します。
クリックで展開
public Dictionary<GeneralEnum.STATUS, int> battleStatusValues = new Dictionary<GeneralEnum.STATUS, int>(); //戦闘で実際に参照される能力値のDictionary。//New public Dictionary<GeneralEnum.ELEMENT, int> battleResistanceOfElementValues = new Dictionary<GeneralEnum.ELEMENT, int>(); //戦闘で実際に参照される属性有効率のDictionry new public Dictionary<GeneralEnum.STATUSCONDITION, int> battleResistanceOfStatusValues = new Dictionary<GeneralEnum.STATUSCONDITION, int>(); //戦闘で実際に参照される状態異常有効率のDictionary new
これらのDictionaryの初期化関数を作成します。
クリックで展開
public void InitBattleDictionary() { foreach (GeneralEnum.STATUS value in Enum.GetValues(typeof(GeneralEnum.STATUS))) { if (value != GeneralEnum.STATUS.NONE) { battleStatusValues[value] = afterEquipStatusValue[value];//装備反映後の値で初期化 } } foreach (GeneralEnum.ELEMENT value in Enum.GetValues(typeof(GeneralEnum.ELEMENT))) { battleResistanceOfElementValues[value] = afEqResistanceOfElementValue[value]; } foreach (GeneralEnum.STATUSCONDITION value in Enum.GetValues(typeof(GeneralEnum.STATUSCONDITION))) { battleResistanceOfStatusValues[value] = afEqResistanceOfStatusValue[value]; } }
EnemyManager.csにも同様の記述をします。
クリックで展開
public Dictionary<GeneralEnum.STATUS, int> baseStatusValue = new Dictionary<GeneralEnum.STATUS, int>(); //基本能力値Dictionary。New public Dictionary<GeneralEnum.STATUS, int> battleStatusValues = new Dictionary<GeneralEnum.STATUS, int>(); //戦闘で実際に参照される能力値のDictionary。New public Dictionary<GeneralEnum.ELEMENT, int> baseResistanceOfElementValue = new Dictionary<GeneralEnum.ELEMENT, int>(); //属性耐性の数値(100が通常) New public Dictionary<GeneralEnum.ELEMENT, int> battleResistanceOfElementValues = new Dictionary<GeneralEnum.ELEMENT, int>(); //戦闘で実際に参照される属性有効率のDictionry new public Dictionary<GeneralEnum.STATUSCONDITION, int> ResistanceOfStatusValue = new Dictionary<GeneralEnum.STATUSCONDITION, int>(); //状態変化のかかりやすさ(100が通常) New public Dictionary<GeneralEnum.STATUSCONDITION, int> battleResistanceOfStatusValues = new Dictionary<GeneralEnum.STATUSCONDITION, int>(); //戦闘で実際に参照される状態異常有効率のDictionary New private void Start() { battleManager = GameObject.Find("BattleManager").GetComponent<BattleManager>(); hp = maxHp; mp = maxMp; tp = UnityEngine.Random.Range(0, 51);//敵のtpの初期値を0~50にする InitResistanceValueOfElement(); //New InitResistanceValueOfStatusCondition(); //New InitStatusCondi(); InitStatusUp(); InitStatusDown(); InitBaseStatusValue(); //New InitBattleDictionary();//New } public void InitResistanceValueOfElement() //New { foreach (GeneralEnum.ELEMENT value in Enum.GetValues(typeof(GeneralEnum.ELEMENT))) { baseResistanceOfElementValue[value] = 100; } } public void InitResistanceValueOfStatusCondition() //New { foreach (GeneralEnum.STATUSCONDITION value in Enum.GetValues(typeof(GeneralEnum.STATUSCONDITION))) { ResistanceOfStatusValue[value] = 100; } } public void InitBaseStatusValue() //New { baseStatusValue[GeneralEnum.STATUS.HP] = maxHp; baseStatusValue[GeneralEnum.STATUS.MP] = maxMp; baseStatusValue[GeneralEnum.STATUS.ATK] = at; baseStatusValue[GeneralEnum.STATUS.DEF] = def; baseStatusValue[GeneralEnum.STATUS.AGI] = agi; baseStatusValue[GeneralEnum.STATUS.LUK] = luk; baseStatusValue[GeneralEnum.STATUS.SENCE] = sence; baseStatusValue[GeneralEnum.STATUS.MAGPOW] = magPow; baseStatusValue[GeneralEnum.STATUS.MAGDEF] = magDef; baseStatusValue[GeneralEnum.STATUS.LEARNABI] = learnAbi; baseStatusValue[GeneralEnum.STATUS.TP] = maxTp; baseStatusValue[GeneralEnum.STATUS.HIT] = hitRate; baseStatusValue[GeneralEnum.STATUS.EVASION] = evasionRate; baseStatusValue[GeneralEnum.STATUS.CRITICAL] = criticalRate; } public void InitBattleDictionary() //New { foreach (GeneralEnum.STATUS value in Enum.GetValues(typeof(GeneralEnum.STATUS))) { if (value != GeneralEnum.STATUS.NONE) { battleStatusValues[value] = baseStatusValue[value];//装備反映後の値で初期化 } } foreach (GeneralEnum.ELEMENT value in Enum.GetValues(typeof(GeneralEnum.ELEMENT))) { battleResistanceOfElementValues[value] = baseResistanceOfElementValue[value]; } foreach (GeneralEnum.STATUSCONDITION value in Enum.GetValues(typeof(GeneralEnum.STATUSCONDITION))) { battleResistanceOfStatusValues[value] = ResistanceOfStatusValue[value]; } }
battleStatusValueディクショナリの値をセットする関数を作成します。
クリックで展開
public void CalcBattleStatusValues() { foreach (GeneralEnum.STATUS value in Enum.GetValues(typeof(GeneralEnum.STATUS))) { if (value != GeneralEnum.STATUS.NONE) { if(statusUpWithLastTurn[value] > 0) { battleStatusValues[value] = (int)(baseStatusValue[value] * statusUpRate[value] / 100f); } } } }
クリックで展開
public void CalcBattleStatusValues() { foreach (GeneralEnum.STATUS value in Enum.GetValues(typeof(GeneralEnum.STATUS))) { if (value != GeneralEnum.STATUS.NONE) { if (statusUpWithLastTurn[value] > 0) { battleStatusValues[value] = (int)(baseStatusValue[value] * statusUpRate[value] / 100f); } } } }
Attack関数を戦闘時能力値を参照するようにします。
クリックで展開
public int Attack(EnemyManager enemy, bool isCritical)//変更 { CalcBattleStatusValues();//戦闘時ステータスを計算する New enemy.CalcBattleStatusValues();//敵も New //プレイヤー攻撃力とエネミー防御力を取得する int atkValue = battleStatusValues[GeneralEnum.STATUS.ATK]; int defValue = enemy.battleStatusValues[GeneralEnum.STATUS.DEF]; float calcDamage = atkValue - defValue / 4f;//プレイヤーの攻撃力-(エネミーの防御力/4) calcDamage = calcDamage * UnityEngine.Random.Range(1.0f - 0.2f, 1.0f + 0.2f);//ダメージに-20%から+20%の幅をもたせる if (isCritical) calcDamage *= 2; int damage = enemy.Damage((int)calcDamage);//計算した値をenemyのダメージ関数に渡す return damage; } //魔法攻撃の場合に呼び出す攻撃関数 public int CalcAttackForMagic(EnemyManager enemy, bool isCritical)//New { CalcBattleStatusValues();//戦闘時ステータスを計算する New enemy.CalcBattleStatusValues();//敵も New //プレイヤー魔力とエネミー魔法防御力を取得する int atkValue = battleStatusValues[GeneralEnum.STATUS.MAGPOW]; int defValue = enemy.battleStatusValues[GeneralEnum.STATUS.MAGDEF]; float calcDamage = atkValue - defValue / 4f;//プレイヤーの攻撃力-(エネミーの防御力/4) calcDamage = calcDamage * UnityEngine.Random.Range(1.0f - 0.2f, 1.0f + 0.2f);//ダメージに-20%から+20%の幅をもたせる if (isCritical) calcDamage *= 2; int damage = enemy.Damage((int)calcDamage);//計算した値をenemyのダメージ関数に渡す return damage; }
クリックで展開
//攻撃する public int Attack(PlayerManager player, bool isCritical) { CalcBattleStatusValues();//戦闘時ステータスを計算する New player.CalcBattleStatusValues();//プレイヤー側も計算 New //プレイヤー魔力とエネミー魔法防御力を取得する int atkValue = battleStatusValues[GeneralEnum.STATUS.ATK];//New int defValue = player.battleStatusValues[GeneralEnum.STATUS.DEF];//New float calcDamage = atkValue - defValue / 4f;//エネミーの攻撃力-(プレイヤーの防御力/4) calcDamage = calcDamage * UnityEngine.Random.Range(1.0f - 0.2f, 1.0f + 0.2f);//ダメージに-20%から+20%の幅をもたせる if (isCritical) calcDamage *= 2; int damage = player.Damage((int)calcDamage);//計算した値をplayerのダメージ関数に渡す return damage; } //魔法攻撃の場合に呼び出す攻撃関数 public int CalcAttackForMagic(PlayerManager player, bool isCritical)//New { CalcBattleStatusValues();//戦闘時ステータスを計算する New player.CalcBattleStatusValues();//敵も New //プレイヤー魔力とエネミー魔法防御力を取得する int atkValue = battleStatusValues[GeneralEnum.STATUS.MAGPOW]; int defValue = player.battleStatusValues[GeneralEnum.STATUS.MAGDEF]; float calcDamage = atkValue - defValue / 4f;//プレイヤーの攻撃力-(エネミーの防御力/4) calcDamage = calcDamage * UnityEngine.Random.Range(1.0f - 0.2f, 1.0f + 0.2f);//ダメージに-20%から+20%の幅をもたせる if (isCritical) calcDamage *= 2; int damage = player.Damage((int)calcDamage);//計算した値をenemyのダメージ関数に渡す return damage; }
BattleManagerで能力値を参照している処理をすべて書き直します。
クリックで展開
public void CalcAttackOrder() //変更 { Debug.Log("行動順の計算"); AgiDic.Clear(); //念の為行動順を格納する前にAgiDicの要素全消去 player.CalcBattleStatusValues(); AgiDic[0] = player.battleStatusValues[GeneralEnum.STATUS.AGI]; //0番 プレイヤー for(int i = 0;i < 3; i++) { if (enemysList.ContainsKey(i)) { enemysList[i].CalcBattleStatusValues();//バトル時ステータス計算 int enemyAgiValue = enemysList[i].battleStatusValues[GeneralEnum.STATUS.AGI]; AgiDic[i + 1] = enemyAgiValue + (int)(enemyAgiValue * (UnityEngine.Random.Range(-0.3f, 0.3f)));//1番 enemysID0の敵 } } Debug.Log("速さのリストを表示"); Debug.Log("playerの速さ" + AgiDic[0]); for(int i = 0; i < 3; i++) { if (enemysList.ContainsKey(i)) { Debug.Log("enemyindex" + i + "の速さ" + AgiDic[i + 1]); } } } public bool PlayerCheckCritical(int enemyIndex) //変更 { player.CalcBattleStatusValues(); enemysList[enemyIndex].CalcBattleStatusValues(); int calcCriticalRate; int pCriticalRate = player.battleStatusValues[GeneralEnum.STATUS.CRITICAL]; int pHitRate = player.battleStatusValues[GeneralEnum.STATUS.HIT]; int pLuk = player.battleStatusValues[GeneralEnum.STATUS.LUK]; int eEvasionRate = enemysList[enemyIndex].battleStatusValues[GeneralEnum.STATUS.EVASION]; int eLuk = enemysList[enemyIndex].battleStatusValues[GeneralEnum.STATUS.LUK]; calcCriticalRate = (int)((pCriticalRate + (pHitRate / 10.0f) + (pLuk / 10.0f)) - ((eEvasionRate / 30.0f) + (eLuk / 20.0f))); if (calcCriticalRate >= UnityEngine.Random.Range(1, 101)) { return true; } else { return false; } } public bool EnemyCheckCritical(int enemyIndex) //変更 { player.CalcBattleStatusValues(); enemysList[enemyIndex].CalcBattleStatusValues(); int calcCriticalRate; int eCriticalRate = enemysList[enemyIndex].battleStatusValues[GeneralEnum.STATUS.CRITICAL]; int eLuk = enemysList[enemyIndex].battleStatusValues[GeneralEnum.STATUS.LUK]; int pEvasionRate = player.battleStatusValues[GeneralEnum.STATUS.EVASION]; int pLuk = player.battleStatusValues[GeneralEnum.STATUS.LUK]; calcCriticalRate = (int)((eCriticalRate + (eLuk / 10.0f)) - ((pEvasionRate / 30.0f) + (pLuk / 20.0f))); if (calcCriticalRate >= UnityEngine.Random.Range(1, 101)) { return true; } else { return false; } } public bool PlayerCheckHitAttack(int enemyIndex) //変更 { player.CalcBattleStatusValues(); enemysList[enemyIndex].CalcBattleStatusValues(); int calcHitRate; int pHitRate = player.battleStatusValues[GeneralEnum.STATUS.HIT]; int pSence = player.battleStatusValues[GeneralEnum.STATUS.SENCE]; int pLuk = player.battleStatusValues[GeneralEnum.STATUS.LUK]; int eEvasionRate = enemysList[enemyIndex].battleStatusValues[GeneralEnum.STATUS.EVASION]; int eAgi = enemysList[enemyIndex].battleStatusValues[GeneralEnum.STATUS.AGI]; int eLuk = enemysList[enemyIndex].battleStatusValues[GeneralEnum.STATUS.LUK]; calcHitRate = (int)((pHitRate + (pSence / 10.0f) + (pLuk / 50.0f)) - (eEvasionRate + (eAgi / 10.0f) + (eLuk / 20.0f))); if (calcHitRate >= UnityEngine.Random.Range(1, 101)) { return true; } else { return false; } } public bool EnemyCheckHitAttack(int enemyIndex) //New { player.CalcBattleStatusValues(); enemysList[enemyIndex].CalcBattleStatusValues(); int calcHitRate; int eHitRate = enemysList[enemyIndex].battleStatusValues[GeneralEnum.STATUS.HIT]; int eAgi = enemysList[enemyIndex].battleStatusValues[GeneralEnum.STATUS.AGI]; int eLuk = enemysList[enemyIndex].battleStatusValues[GeneralEnum.STATUS.LUK]; int pEvasionRate = player.battleStatusValues[GeneralEnum.STATUS.EVASION]; int pAgi = player.battleStatusValues[GeneralEnum.STATUS.AGI]; int pLuk = player.battleStatusValues[GeneralEnum.STATUS.LUK]; calcHitRate = (int)((eHitRate + (eAgi / 10.0f) + (eLuk / 50.0f)) - (pEvasionRate + (pAgi / 10.0f) + (pLuk / 20.0f))); if (calcHitRate >= UnityEngine.Random.Range(1, 101)) { return true; } else { return false; } }
これで戦闘時に使用するディクショナリの実装ができました。次回は特技の実装をやっていきたいと思います。