您的位置:首页 > 移动开发 > Unity3D

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();
}
}带给我震撼的是下面的两个方法:

//添加状态
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一个,实现添加。

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

原文:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: