【设计模式】Unity3D 状态模式

Unity3D 状态模式

提示:个人学习总结,如有错误,尽请指正。



一、状态模式是什么?

  1. 经典定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来是改变了其类
  2. 简单来说,状态决定行为

二、实现方式

1.枚举

1.用枚举去设置各种状态
2.使用switch case去转换状态

    public enum LightState
    {
        Off,
        Warm,
        White,
        WarmWhite
    }
    public LightState CurrentState = LightState.Off;
    public void OnChangeState()
    {
        //状态转换
        switch (CurrentState)
        {
            case LightState.Off:
                CurrentState = LightState.Warm;
                break;
            case LightState.Warm:
                CurrentState = LightState.White;
                break;
            case LightState.White:
                CurrentState = LightState.WarmWhite;
                break;
            case LightState.WarmWhite:
                CurrentState = LightState.Off;
                break;
            default:
                CurrentState = LightState.Off;
                break;
        }
        //状态行为
        switch (CurrentState)
        {
            case LightState.Off:
                mLight.color = Color.black;
                mMat.SetColor("_EmissionColor", mLight.color);
                break;
            case LightState.Warm:
                mLight.color = new Color(0.8f, 0.5f, 0);
                mMat.SetColor("_EmissionColor", mLight.color);
                break;
            case LightState.White:
                mLight.color = new Color(0.8f, 0.8f, 0.8f);
                mMat.SetColor("_EmissionColor", mLight.color);
                break;
            case LightState.WarmWhite:
                mLight.color = new Color(1, 0.85f, 0.6f);
                mMat.SetColor("_EmissionColor", mLight.color);
                break;
            default:
                mLight.color = Color.black;
                mMat.SetColor("_EmissionColor", mLight.color);
                break;
        }
    }

2.多态、虚函数

1.状态接口类

为状态定义一个接口。每一个与状态相关的行为都定义成虚函数。
虚方法:如果使用override重写,则在派生类中调用重写的方法,否则则调用基类中的方法
抽象方法必须被子类重写

using UnityEngine.UI;
public abstract class IState 
{
    public float Duration;
    //状态行为
    public abstract void SwitchState(ImgState imgState);
    //切换状态
    public abstract void StateStart(ImgState imgState);
}

2.具体状态类

为每个状态创建一个类

using UnityEngine;
public class RedState : IState
{
    public RedState(float Duration)
    {
        this.Duration = Duration;
    }

    public override void StateStart(ImgState imgState)
    {
        imgState.Img.color = Color.red;
        imgState.timer = Duration;
    }

    public override void SwitchState(ImgState imgState)
    {
        imgState.SetState(new GreenState(2.0f));
    }
}


using UnityEngine;
public class GreenState : IState
{
    public GreenState(float Duration)
    {
        this.Duration = Duration;
    }
    public override void StateStart(ImgState imgState)
    {
        imgState.Img.color = Color.green;
        imgState.timer = Duration;
    }
    public override void SwitchState(ImgState imgState)
    {
        imgState.SetState(new RedState(1.0f));
    }
}

3.对象状态切换

using UnityEngine;
using UnityEngine.UI;
public class ImgState : MonoBehaviour
{
    [SerializeField] Image img;
    public Image Img
    {
        get
        {
            return img;
        }
    }
    public IState state;
    public float timer = 1.0f;

    void Start()
    {
        SetState(new RedState(1.5f));
    }

    void Update()
    {
        timer-= Time.deltaTime;
        if (timer <= 0)
        {
            state.SwitchState(this);
        }
    }
    //设置当前状态
    public void SetState(IState state)
    {
        this.state = state;
        state.StateStart(this);
    }
}

三、优缺点

1.优点

1.把复杂的判断逻辑简化,当然如果本身很简单可以直接用switch-case
2.消除了庞大的条件分支语句,代码的阅读性增强。
3.状态模式可以将各种状态的转换逻辑放入状态子类之间,减少互相间的依赖。
4.让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

2.缺点

1.大量状态会造成大量的类产生,增加系统中类和对象的个数
2.对“开闭原则”的支持并不太好,修改或者新增新的状态,需要去修改状态转换的代码


四、适用场景

1.当一个对象的行为取决于它的状态,并且它必须在运行时时刻根据状态改变它的行为,可以考虑状态模式
2.对象的行为依赖于它的状态,减少大量对象的产生。

附:参考链接

游戏设计模式
大话设计模式

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值