开始的时候我写属性类时只写了一个类,当属性增多时我开始意识到这个类已经失败了,每一次修改都要滚动来滚动去的,更繁琐的是我不得不准备个记事本写上属性变量好查询。
记得我曾看过一篇有限状态机的文章,把if 或 switch 都改成枚举,用枚举去查询状态,那么我觉得一定也有一种方式提高可阅读性,我找到了状态模式,具体自行搜索
首先写个基础类,就是用来修改值得
public class BaseStat {
private string _name;
private int _baseValue;
private int _buffValue;
public BaseStat() {
_baseValue = 0;
}
public string Name {
get { return _name; }
set { _name = value; }
}
public int BaesValue {
get { return _baseValue + _buffValue; }
}
public int BuffValue
{
get { return _buffValue; }
}
public void AdjustBuffValue(int buff)
{
_buffValue = buff;
}
}
再写个属性类,顺便枚举几个属性
public class Attribute : BaseStat
{
public Attribute(string name)
{
Name = name;
}
}
public enum AttributeName
{
Might,
Constituion,
Nimbleness,
Speed,
Concentration,
Willpower,
Charisma
}
由于一个属性改变后,连带着有N个属性会被改变,所以加了个链表用来存储将会被改变的属性,由于C#不new地址并不会改变,所以可以放心修改
当修改Buff值的时候调用子类更新附属的值
using System.Collections.Generic;
public class ModifiedStat : BaseStat
{
public List<ModifyingAttribute> _mod { get; set; }
public ModifiedStat()
{
_mod = new List<ModifyingAttribute>();
}
public void AddModifying(ModifyingAttribute mod)
{
_mod.Add(mod);
}
public void ModifyBuffValue(int Value)
{
AdjustBuffValue(Value);
Update();
}
protected virtual void Update() { }
}
public struct ModifyingAttribute
{
public Attribute _attr;
public ModifyingAttribute(Attribute attr)
{
_attr = attr;
}
}
当然这只是示范一下,公式不一定只写在一个函数里
using System;
public class Vital : ModifiedStat
{
public Vital(string name)
{
Name = name;
}
protected override void Update()
{
foreach(ModifyingAttribute mod in _mod)
{
CalculationHealth(mod);
}
}
void CalculationHealth(ModifyingAttribute mod)
{
//属性计算公式
if(mod._attr.Name == Enum.GetName(typeof(AttributeName),AttributeName.Might))
mod._attr.AdjustBuffValue(BuffValue*3);
}
}
public enum VitalName
{
Health,
Energy,
Mana
}
public class Skill : ModifiedStat
{
public Skill(string name)
{
Name = name;
}
protected override void Update()
{
foreach (ModifyingAttribute mod in _mod)
{
mod._attr.AdjustBuffValue(100);
}
}
}
public enum SkillName
{
Melee_Offence,
Melee_Defence,
Ranged_Offence,
Ranged_Defence,
Magic_Offence,
Magic_Defence,
}
using UnityEngine;
using System.Collections;
using System;
public class test : MonoBehaviour {
Attribute[] _attribute;
Vital []_vital;
Skill []_skill;
// Use this for initialization
void Start () {
_attribute = new Attribute[Enum.GetValues(typeof(AttributeName)).Length];
_vital = new Vital[Enum.GetValues(typeof(VitalName)).Length];
_skill = new Skill[Enum.GetValues(typeof(SkillName)).Length];
SetupAttribute();
SetupSkill();
SetupVital();
GetVital((int)VitalName.Health).ModifyBuffValue(10);
GetSkill((int)SkillName.Magic_Defence).ModifyBuffValue(10);
Output();
}
void Output()
{
string tmp = "";
foreach(Attribute at in _attribute)
{
tmp += (at.Name + ":" + at.BaesValue+"\n");
}
foreach (Vital at in _vital)
{
tmp += (at.Name + ":" + at.BaesValue + "\n");
}
foreach (Skill at in _skill)
{
tmp += (at.Name + ":" + at.BaesValue + "\n");
}
Debug.Log(tmp);
}
void SetupAttribute()
{
for(int i = 0; i < _attribute.Length; i++)
{
_attribute[i] = new Attribute(Enum.GetName(typeof(AttributeName),i));
}
}
void SetupVital()
{
for (int i = 0; i < _vital.Length; i++)
{
_vital[i] = new Vital(Enum.GetName(typeof(VitalName), i));
}
VitalModified();
}
void SetupSkill()
{
for (int i = 0; i < _skill.Length; i++)
{
_skill[i] = new Skill(Enum.GetName(typeof(SkillName), i));
}
SkillModified();
}
Attribute GetAttribut(int index)
{
return _attribute[index];
}
Vital GetVital(int index)
{
return _vital[index];
}
Skill GetSkill(int index)
{
return _skill[index];
}
void VitalModified()
{
//如果_vital[VitalName.Health] 改变 则 _attribute[AttributeName.Might] 改变
GetVital((int)VitalName.Health).AddModifying(new ModifyingAttribute(GetAttribut((int)AttributeName.Might)));
GetVital((int)VitalName.Energy).AddModifying(new ModifyingAttribute(GetAttribut((int)AttributeName.Concentration)));
GetVital((int)VitalName.Mana).AddModifying(new ModifyingAttribute(GetAttribut((int)AttributeName.Willpower)));
}
void SkillModified()
{
GetSkill((int)SkillName.Magic_Defence).AddModifying(new ModifyingAttribute(GetAttribut((int)AttributeName.Willpower)));
}
}