unity状态模式

  开始的时候我写属性类时只写了一个类,当属性增多时我开始意识到这个类已经失败了,每一次修改都要滚动来滚动去的,更繁琐的是我不得不准备个记事本写上属性变量好查询。

  记得我曾看过一篇有限状态机的文章,把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)));
    }

    
}






Unity 中常用的设计模式包括以下几种: 1. 单例模式(Singleton Pattern):用于确保一个类只有一个实例,并提供全局访问点。在 Unity 中,可以使用静态变量或者脚本组件的方式实现单例模式。 2. 观察者模式(Observer Pattern):用于实现对象间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都会得到通知并自动更新。在 Unity 中,可以使用事件系统或者委托实现观察者模式。 3. 工厂模式(Factory Pattern):用于封装对象的创建过程,隐藏具体类的实例化逻辑。在 Unity 中,可以通过工厂类或者抽象工厂来创建游戏对象或其他资源。 4. 命令模式(Command Pattern):用于将请求封装成一个对象,从而可以将请求的发送者和接收者解耦。在 Unity 中,可以通过委托或者事件来实现命令模式。 5. 组合模式(Composite Pattern):用于将对象组织成树形结构,并且可以以相同的方式处理单个对象和组合对象。在 Unity 中,可以使用游戏对象的层级结构来实现组合模式。 6. 状态模式(State Pattern):用于封装对象内部状态的变化,并根据状态的变化来改变对象的行为。在 Unity 中,可以使用状态机或者策略模式来实现状态模式。 这些设计模式可以帮助开发者更好地组织和管理 Unity 项目中的代码,提高代码的可维护性和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值