系统类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 状态机系统
/// </summary>
public class FSMSystem {
private Dictionary<StateID, FSMState> states = new Dictionary<StateID, FSMState>();//Key:状态 Value:状态的具体类 管理所有状态
private StateID currentStateID;//当前状态
private FSMState currentState;//当前状态的具体类
/// <summary>
/// 某个实体的执行行为和触发因素
/// </summary>
/// <param name="npc"></param>
public void Update(GameObject npc)
{
currentState.Act(npc);
currentState.Reason(npc);
}
/// <summary>
/// 添加状态
/// </summary>
/// <param name="s"></param>
public void AddState(FSMState s)
{
if (s == null)//空不能添加
{
Debug.LogError("FSMState不能为空");return;
}
if (currentState == null)//如果当前状态ID和状态为空 给他们赋值
{
currentState = s;
currentStateID = s.ID;
}
if (states.ContainsKey(s.ID))//存在无法添加
{
Debug.LogError("状态" + s.ID + "已经存在,无法重复添加");return;
}
states.Add(s.ID, s);//合格添加
}
/// <summary>
/// 移除状态
/// </summary>
/// <param name="id"></param>
public void DeleteState(StateID id)
{
if (id == StateID.NullStateID)//无法删除空状态
{
Debug.LogError("无法删除空状态");return;
}
if (states.ContainsKey(id) == false)//字典不存在移除不了
{
Debug.LogError("无法删除不存在的状态:" + id);return;
}
states.Remove(id);//合格移除
}
/// <summary>
/// 执行状态
/// </summary>
/// <param name="trans"></param>
public void PerformTransition(Transition trans)
{
if (trans == Transition.NullTransition)//无法执行空的转换条件
{
Debug.LogError("无法执行空的转换条件");return;
}
StateID id= currentState.GetOutputState(trans);//拿当前状态获取状态的ID 传参位转换条件
if (id == StateID.NullStateID)//状态ID等于NullStateID的话,就无法通过转换条件转换状态
{
Debug.LogWarning("当前状态" + currentStateID + "无法根据转换条件" + trans + "发生转换");return;
}
if (states.ContainsKey(id) == false)//在状态机里面不存在状态
{
Debug.LogError("在状态机里面不存在状态" + id + ",无法进行状态转换!");return;
}
//达成转换条件
FSMState state = states[id];//根据ID拿出这个状态
currentState.DoAfterLeaving();
currentState = state;//当前状态发生变化
currentStateID = id;//当前状态ID发生变化
currentState.DoBeforeEntering();
}
}
基类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 过渡(转换条件)
/// </summary>
public enum Transition
{
NullTransition = 0,
SeePlayer,//看到角色
LostPlayer//没看到角色
}
/// <summary>
/// 状态ID
/// </summary>
public enum StateID
{
NullStateID = 0,
Patrol,//巡逻
Chase//追逐
}
/// <summary>
/// 添加状态和移除状态和获取状态的抽象类
/// </summary>
public abstract class FSMState
{
protected StateID stateID;//类的状态ID
public StateID ID { get { return stateID; } }//可以被获取
protected Dictionary<Transition, StateID> map = new Dictionary<Transition, StateID>();//Key:转换条件 Value:状态ID
protected FSMSystem fsm;//持有状态机系统 可以根据实现的子类调用状态机系统的方法(添加、移除、执行)
public FSMState(FSMSystem fsm)//构造传状态机系统
{
this.fsm = fsm;
}
/// <summary>
/// 添加装换条件和状态ID
/// </summary>
/// <param name="trans"></param>
/// <param name="id"></param>
public void AddTransition(Transition trans, StateID id)
{
if (trans == Transition.NullTransition)
{
Debug.LogError("不允许NullTransition"); return;
}
if (id == StateID.NullStateID)
{
Debug.LogError("不允许NullStateID"); return;
}
if (map.ContainsKey(trans))
{
Debug.LogError("添加转换条件的时候," + trans + "已经存在于map中"); return;
}
map.Add(trans, id);
}
/// <summary>
/// 删除装换条件和状态ID
/// </summary>
/// <param name="trans"></param>
public void DeleteTransition(Transition trans)
{
if (trans == Transition.NullTransition)
{
Debug.LogError("不允许NullTransition"); return;
}
if (map.ContainsKey(trans) == false)
{
Debug.LogError("删除转换条件的时候," + trans + "不存在于map中"); return;
}
map.Remove(trans);
}
/// <summary>
/// 根据转换条件获取状态ID的方法(返回状态ID)
/// </summary>
/// <param name="trans"></param>
/// <returns></returns>
public StateID GetOutputState(Transition trans)
{
if (map.ContainsKey(trans))
{
return map[trans];
}
return StateID.NullStateID;
}
public virtual void DoBeforeEntering() { }
public virtual void DoAfterLeaving() { }
public abstract void Act(GameObject npc);//行为
public abstract void Reason(GameObject npc);//触发因素
}