Unity 有限状态机FSM原理剖析
2018-02-28 09:53
609 查看
本文分析的是wiki上有限状态机给出的代码:链接地址。
下面是删除注释精简后的代码:using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Transition
{
/*输入切换状态触发量,如OnFirstButtonClick=0,
OnSecondButtonClick=1,
……
*/
}
public enum StateID
{
/*输入状态ID,如ShowFirstPanelID=0,
ShowSecondPanelID=1,
……
*/
}
public abstract class FSMState
{
protected Dictionary<Transition, StateID> map = new Dictionary<Transition, StateID>();
protected StateID stateID;
public StateID ID { get { return stateID; } }
//关联切换状态触发量与要切换到的状态ID
public void AddTransition(Transition trans, StateID id)
{
if (map.ContainsKey(trans))
{
return;
}
map.Add(trans, id);
}
public void DeleteTransition(Transition trans)
{
if (map.ContainsKey(trans))
{
map.Remove(trans);
return;
}
}
public StateID GetOutputState(Transition trans)
{
if (map.ContainsKey(trans))
{
return map[trans];
}
return 0;//若查询不到对应的id,将返回StateID的第一个枚举量
}
public virtual void DoBeforeEntering() { }
public virtual void DoBeforeLeaving() { }
public abstract void Reason(GameObject player, GameObject npc);
public abstract void Act(GameObject player, GameObject npc);
}
//FSMSystem-------------------------------------------------
public class FSMSystem
{
private List<FSMState> states;
private StateID currentStateID;
public StateID CurrentStateID { get { return currentStateID; } }
private FSMState currentState;
public FSMState CurrentState { get { return currentState; } }
public FSMSystem()
{
states = new List<FSMState>();
}
public void AddState(FSMState s)
{
//默认是将第一个传入的state设置为当前状态
if (states.Count == 0)
{
states.Add(s);
currentState = s;
currentStateID = s.ID;
return;
}
fore
4000
ach (FSMState state in states)
{
if (state.ID == s.ID)
{
return;
}
}
states.Add(s);
}
public void DeleteState(StateID id)
{
foreach (FSMState state in states)
{
if (state.ID == id)
{
states.Remove(state);
return;
}
}
}
public void PerformTransition(Transition trans)
{
StateID id = currentState.GetOutputState(trans);
// Update the currentStateID and currentState
currentStateID = id;
foreach (FSMState state in states)
{
if (state.ID == currentStateID)
{
currentState.DoBeforeLeaving();
currentState = state;
currentState.DoBeforeEntering();
break;
}
}
}
}
使用方法:直接在Unity下创建FSMSystem.cs,将代码全部复制过去即可。
代码中包含两个类:FSMSystem、抽象类FSMState。 其中FSMState底下分了几个state继承类,每个类都有各自的ID号。当执行FSMSystem下的PerformTransition函数时,需要传入与切换到下一状态事件相关的枚举触发量,FSMSystem会根据此枚举量找到切换到对应事件的id,接着遍历所有FSMState继承类的id,寻找相符合的,然后执行当前事件的Leaving方法,与执行下一事件的Enting方法,并将当前事件=下一事件。
代码实现效果:调用FSMSystem中PerformTransition函数,告诉它要切换到什么状态,FSMSystem即会执行当前状态的Leving方法与下一状态的Entering方法。
下面是删除注释精简后的代码:using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Transition
{
/*输入切换状态触发量,如OnFirstButtonClick=0,
OnSecondButtonClick=1,
……
*/
}
public enum StateID
{
/*输入状态ID,如ShowFirstPanelID=0,
ShowSecondPanelID=1,
……
*/
}
public abstract class FSMState
{
protected Dictionary<Transition, StateID> map = new Dictionary<Transition, StateID>();
protected StateID stateID;
public StateID ID { get { return stateID; } }
//关联切换状态触发量与要切换到的状态ID
public void AddTransition(Transition trans, StateID id)
{
if (map.ContainsKey(trans))
{
return;
}
map.Add(trans, id);
}
public void DeleteTransition(Transition trans)
{
if (map.ContainsKey(trans))
{
map.Remove(trans);
return;
}
}
public StateID GetOutputState(Transition trans)
{
if (map.ContainsKey(trans))
{
return map[trans];
}
return 0;//若查询不到对应的id,将返回StateID的第一个枚举量
}
public virtual void DoBeforeEntering() { }
public virtual void DoBeforeLeaving() { }
public abstract void Reason(GameObject player, GameObject npc);
public abstract void Act(GameObject player, GameObject npc);
}
//FSMSystem-------------------------------------------------
public class FSMSystem
{
private List<FSMState> states;
private StateID currentStateID;
public StateID CurrentStateID { get { return currentStateID; } }
private FSMState currentState;
public FSMState CurrentState { get { return currentState; } }
public FSMSystem()
{
states = new List<FSMState>();
}
public void AddState(FSMState s)
{
//默认是将第一个传入的state设置为当前状态
if (states.Count == 0)
{
states.Add(s);
currentState = s;
currentStateID = s.ID;
return;
}
fore
4000
ach (FSMState state in states)
{
if (state.ID == s.ID)
{
return;
}
}
states.Add(s);
}
public void DeleteState(StateID id)
{
foreach (FSMState state in states)
{
if (state.ID == id)
{
states.Remove(state);
return;
}
}
}
public void PerformTransition(Transition trans)
{
StateID id = currentState.GetOutputState(trans);
// Update the currentStateID and currentState
currentStateID = id;
foreach (FSMState state in states)
{
if (state.ID == currentStateID)
{
currentState.DoBeforeLeaving();
currentState = state;
currentState.DoBeforeEntering();
break;
}
}
}
}
使用方法:直接在Unity下创建FSMSystem.cs,将代码全部复制过去即可。
代码中包含两个类:FSMSystem、抽象类FSMState。 其中FSMState底下分了几个state继承类,每个类都有各自的ID号。当执行FSMSystem下的PerformTransition函数时,需要传入与切换到下一状态事件相关的枚举触发量,FSMSystem会根据此枚举量找到切换到对应事件的id,接着遍历所有FSMState继承类的id,寻找相符合的,然后执行当前事件的Leaving方法,与执行下一事件的Enting方法,并将当前事件=下一事件。
代码实现效果:调用FSMSystem中PerformTransition函数,告诉它要切换到什么状态,FSMSystem即会执行当前状态的Leving方法与下一状态的Entering方法。
相关文章推荐
- Unity协程(Coroutine)原理深入剖析
- Unity协程(Coroutine)原理深入剖析再续
- Unity协程(Coroutine)原理深入剖析
- Unity协程(Coroutine)原理深入剖析再
- Unity协程(Coroutine)原理深入剖析再续
- Unity协程(Coroutine)原理深入剖析
- Unity协程(Coroutine)原理深入剖析
- Unity协程(Coroutine)原理深入剖析(转载)
- 第二章 内存原理基础篇+FSM有限状态机
- Unity协程(Coroutine)原理深入剖析(转载)
- Unity3D - Unity协程(Coroutine)原理深入剖析
- Unity协程(Coroutine)原理深入剖析
- Unity协程(Coroutine)原理深入剖析
- Unity协程(Coroutine)原理深入剖析
- Unity协程(Coroutine)原理深入剖析(转)
- 有限状态机(FSM)设计原理
- 在Unity中实现FSM有限状态机
- Unity协程(Coroutine)原理深入剖析
- Unity协程(Coroutine)原理深入剖析
- Unity协程(Coroutine)原理深入剖析