今回は、アイテムでステータスを更新する処理(第23回)に関連して、最大・最小値を加味したパラメータへの加算を実装します。
<目次>
最大・最小を超えない範囲で値を加減算する
インターフェース
最大・最小を持つパラメータ値Aに、値Bを加算する処理を、以下のインターフェースにします。
実際の加算量B = 値の加算(最大・最小を持つパラメータ値A、値B);
最大・最小を持つパラメータの構造
パラメータ値Aは、以下の構造で表します。
class 最大・最小を持つパラメータ値A {
値
最大値
最小値
}
コード
最大・最小(ParamRange.cs)
public class ParamRange { public int val; public int max; public int min; }
加算処理(今回はPartyCharacterStatus.cs内)
// パラメータへの加算(加算量を返す) int CulcParam(ParamRange range, int val) { int a, b, a_old, b_old, lim; // a: 足される数, b:足す数 a_old = a = range.val; b_old = b = val; if( b > 0 ){ // 加算 lim = range.max; if( a + b > lim ){ b = lim - a; } a += b; } else if( b < 0 ){ // 減算 lim = range.min; if( a + b < lim ){ b = lim - a; } a += b; } if ( b ) { // 加算量の確認 // 例:90/100 (20) -> 100/100 : 10 Debug.Log( a_old + "/" + range.max + " (" + b_old + ") -> " + a + "/" + range.max + " : " + b ); } return b; }
パラメータ名から最大・最小値を自動で判別する
実際は、パラメータ毎に最大・最小値は一意に決まるので、毎回最大値・最小値を渡さないで、パラメータ名だけを指定できる方が楽です。そのため、上記の計算式をラッピングする以下のインターフェースを考えます。
パラメータ名(enum、配列)
enum パラメータ名 { パラメータ名1, パラメータ名2, : PARAM_MAX // パラメータの個数 }; List<short> パラメータ;
インターフェース
実際の加算量 = パラメータへの加算(パラメータ名、加算量);
コード
using UnityEngine; // Debug.Log using System.Collections; using System.Collections.Generic; // パラメータ名 public enum CharacterStatusParams { LIFE = 0, // 生命力(削る対象) LIFEMAX, // 生命力の最大値 ATTACK, // 攻撃力(削る力) SPEED, // 速度(削る速さ) PARAM_MAX // パラメータの個数 }; public class PartyCharacterStatus { // パラメータ値 private List<short> param; // コンストラクタ public PartyCharacterStatus(short life, short lifeMax, short attack, short speed){ param = new List<short>(); param.Add( life ); param.Add( lifeMax ); param.Add( attack ); param.Add( speed ); } // パラメータへの加算 public int SumValue( CharacterStatusParams id, int val ) { ParamRange r = new ParamRange(); r.val = param[(int)id]; if( id == (int)CharacterStatusParams.LIFE ){ r.max = param[(int)CharacterStatusParams.LIFEMAX]; r.min = 0; } else { r.max = 255; r.min = 0; } return CulcParam( r, val ); } // 先ほどの計算処理もとりあえずここに追加(そのうちにファイル分割する) int CulcParam(ParamRange range, int val) { // 略 } }
出力テスト
ステータス値とアイテム効果の値を境界値付近に設定して、加算しようとする値がステータス値の最大・最小でクリップされるか確認します。
60/100 + 20 → 80/100 : 20 90/100 + 20 → 100/100 : 10 60/100 - 20 → 40/100 : -20 10/100 - 20 → 0/100 : -10 100/100 + 20 → 100/100 : 0 0/100 + 20 → 20/100
アイテムを使用した時の例
QueryUseWindow.cs
public void OnSubmit(BaseEventData eventData) { // 中略 // アイテムの作用と表示 if( context.itemContext.itemOperation == (int)ItemUsage.USE ){ Efficacy efficacy = context.itemContext.itembag[ context.itemContext.itemId ].efficacy; if( efficacy != null ){ if( efficacy.value != 0 ){ string showEffect = null; int effect = context.party.member[0].status.SumValue( efficacy.status, efficacy.value ); if( effect == 0 ){ showEffect = "Nothing Happened"; } else { if( effect > 0 ){ if( efficacy.status == CharacterStatusParams.LIFE ){ showEffect = "Cured: " + effect; } else { showEffect = "Increased: " + effect; } } else { showEffect = "Decreased: " + -(effect); } } Debug.Log( showEffect ); } } } // 以下略 }
次回
第22回で作成したテキスト出力画面を一工夫して、複数行の出力に対応します。