Unity 游戏框架搭建--简易有限状态机

为什么用有限状态机?

  之前做过一款跑酷游戏,跑酷角色有很多状态:跑、跳、二段跳、死亡等等。一开始是使用if/switch来切换状态,但是每次角色添加一个状态(提前没规划好),所有状态处理相关的代码就会指数级增长,那样就会嗅出代码的坏味道了。在这种处理状态并且状态数量不是特别多的情况下,自然就想到了引入状态机。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// 状态机实现
/// </summary>
public class QFSM
{
    public delegate void FSMCallfunc();
    /// <summary>
    /// 状态类
    /// </summary>
    class QState
    {
        public string name;

        public QState (string name)
        {
            this.name = name;
        }
        /// <summary>
        /// 存储对应事件转换的条件
        /// </summary>
        public Dictionary<string, FSMTranslation> TranslationDit = new Dictionary<string, FSMTranslation>();
    }

    /// <summary>
    /// 跳转类
    /// </summary>
    public class FSMTranslation
    {
        public string fromState;
        public string name;
        public string toState;
        public FSMCallfunc callfunc;

        public FSMTranslation (string fromState,string name, string toState,FSMCallfunc callfunc)
        {

            this.fromState = fromState;
            this.toState = toState;
            this.name = name;
            this.callfunc = callfunc;
        }
    }

    private string mCurState;

    public string State
    {
        get
        {
            return mCurState;
        }
    }
    /// <summary>
    /// 状态
    /// </summary>
    Dictionary<string, QState> stateDic = new Dictionary<string, QState>();

    /// <summary>
    /// 添加状态
    /// </summary>
    /// <param name="name"></param>
    public void AddState(string name)
    {
        stateDic[name] = new QState(name);
    }
    /// <summary>
    /// 添加跳转
    /// </summary>
    public void AddTranslation(string fromState, string name, string toState, FSMCallfunc callfunc)
    {
        stateDic[fromState].TranslationDit[name] = new FSMTranslation(fromState, name, toState, callfunc);
    }
    /// <summary>
    /// 启动
    /// </summary>
    /// <param name="name"></param>
    public void Start(string name)
    {
        mCurState = name;
    }
    /// <summary>
    /// 处理事件
    /// </summary>
    /// <param name="name"></param>
    public void HandlerEvent(string name)
    {
        if (mCurState != null && stateDic[mCurState].TranslationDit.ContainsKey(name))
        {
            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            FSMTranslation tempTranslation = stateDic[mCurState].TranslationDit[name];
            tempTranslation.callfunc();

            watch.Stop();
        }
    }

    public void Clear()
    {
        stateDic.Clear();
    }
}
带给我震撼的是下面的两个方法:

//添加状态
public void AddState(string name)
    {
        stateDic[name] = new QState(name);
    }
//添加跳转
<pre name="code" class="html"> public void AddTranslation(string fromState, string name, string toState, FSMCallfunc callfunc)
    {
        stateDic[fromState].TranslationDit[name] = new FSMTranslation(fromState, name, toState, callfunc);
    }

 根据名字从状态字典获取里面对应的跳转字典,再new一个,实现添加。 

这个值得我思考很久很久,但如果我想通了,对我应该有很大的提升.......


原文:点击打开链接


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值