Unity 游戏框架搭建--简易有限状态机
2016-10-24 10:22
821 查看
为什么用有限状态机?
之前做过一款跑酷游戏,跑酷角色有很多状态:跑、跳、二段跳、死亡等等。一开始是使用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();
}
}带给我震撼的是下面的两个方法:
//添加状态
根据名字从状态字典获取里面对应的跳转字典,再new一个,实现添加。
这个值得我思考很久很久,但如果我想通了,对我应该有很大的提升.......
原文:点击打开链接
之前做过一款跑酷游戏,跑酷角色有很多状态:跑、跳、二段跳、死亡等等。一开始是使用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一个,实现添加。
这个值得我思考很久很久,但如果我想通了,对我应该有很大的提升.......
原文:点击打开链接
相关文章推荐
- Unity 游戏框架搭建 (四) 简易有限状态机
- Unity 游戏框架搭建 (四) 简易有限状态机
- Unity 游戏框架搭建 (四) 简易有限状态机
- Unity 游戏框架搭建 (四) 简易有限状态机
- Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)
- Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)
- Unity 游戏框架搭建 (五) 简易消息机制
- Unity 游戏框架搭建 (五) 简易消息机制
- Unity 游戏框架搭建 (五) 简易消息机制
- Unity 游戏框架搭建 (十一) 简易AssetBundle打包工具(一)
- Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)
- Unity 游戏框架搭建 (十一) 简易AssetBundle打包工具(一)
- Unity 游戏框架搭建 (一) 概述
- Unity 游戏框架搭建 (八) 减少加班利器-QLog
- Unity 游戏框架搭建 (七) 减少加班利器-QApp类
- Unity 游戏框架搭建 (八) 减少加班利器-QLog
- Unity 游戏框架搭建 (三) MonoBehaviour单例的模板
- Unity 游戏框架搭建 (一) 概述
- Unity 游戏框架搭建 (十三) 无需继承的单例的模板
- Unity 游戏框架搭建 (六) 关于框架的一些好文和一些思考