实现的功能:AI在固定的路径上巡逻,当玩家靠近AI的视野范围时,AI会追击玩家。当玩家跑出AI的视野范围时,AI则会放弃追击继续回到原来的地方进行巡逻。
参考资料:http://wiki.unity3d.com/index.php/Finite_State_Machine.
效果:
FSM基类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//状态转化的条件枚举
public enum Transition
{
DefualtNull=0,//空条件
SeePlayer,//看向玩家
LostPlayer,//放弃追击玩家
}
//当前状态的枚举
public enum StateID
{
NullState=0,//空状态
MonstersWay, //enemy巡逻状态
ChasePlayer,//enemy追玩家
}
/// <summary>
/// FSM状态基类
/// </summary>
public abstract class FSMState
{
protected StateID _stateID;
public StateID ID { get { return _stateID; } }
//保存所有状态转化条件和状态的字典
protected Dictionary<Transition, StateID> Map = new Dictionary<Transition, StateID>();
//区分哪个状态机管理自身
protected FSMControl _fsm;
public FSMState(FSMControl fsm)
{
this._fsm = fsm;
}
//添加
public void AddTransition(Transition _trans, StateID _state)
{
if (_trans==Transition.DefualtNull)
{
Debug.Log("状态转化条件为空!");
return;
}
if (_state== StateID.NullState)
{
Debug.Log("状态为空!");
return;
}
if (Map.ContainsKey(_trans))
{
Debug.Log("字典中已经存在了"+_state+"状态!");
return;
}
Map.Add(_trans,_state);
}
//移除
public void RemoveTransition(Transition _trans)
{
if (_trans == Transition.DefualtNull)
{
Debug.Log("状态转化条件为空!");
return;
}
if (Map.ContainsKey(_trans))
{
Debug.Log("字典中不存在了" + _trans + "状态转化条件!");
return;
}
Map.Remove(_trans);
}
//得到
public StateID GetOutputState(Transition _trans)
{
//如果字典中不包含就返回空
if (Map.ContainsKey(_trans))
{
return Map[_trans];
}
return StateID.NullState;
}
public virtual void DoBeforEnter() { } //状态进入
public virtual void DoBeforLeaving() { }//状态离开
public abstract void Reson(GameObject go);//状态过渡
public abstract void Act(GameObject go);//当前状态
}
控制管理类:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class FSMControl
{
//保存所有的状态
private Dictionary<StateID, FSMState> states = new Dictionary<StateID, FSMState>();
//当前状态
private StateID currentStateID;
private FSMState currentFSM;
public void UpdateState(GameObject go)
{
currentFSM.Act(go);
currentFSM.Reson(go);
}
public void AddState(FSMState fsm)
{
if (fsm==null)
{
Debug.Log("传进来的fsm为空!");return;
}
if (currentFSM== null)
{
currentFSM = fsm;
currentStateID = fsm.ID;
}
if (states.ContainsKey(fsm.ID))
{
Debug.Log("状态"+fsm.ID+"已经存在!");return;
}
states.Add(fsm.ID,fsm);
}
public void DeleteState(StateID id)
{
if (id==StateID.NullState)
{
Debug.Log("传进来的id为空!");return;
}
if (!states.ContainsKey(id))
{
Debug.Log("无法移除不存在的id!");return;
}
states.Remove(id);
}
//根据转化条件转化状态
public void PerformTransition(Transition tran)
{
if (tran==Transition.DefualtNull)
{
Debug.Log("转化条件为空,状态无法进行转化!");return;
}
StateID _id = currentFSM.GetOutputState(tran);
if (_id==StateID.NullState)
{
Debug.Log("状态为空,无法进行转化!");return;
}
if (!states.ContainsKey(_id))
{
Debug.Log("状态字典中不存在状态,无法转化!");return;
}
FSMState _state = states[_id];
currentFSM.DoBeforLeaving();//当前状态离开调用方法
currentFSM = _state;
currentStateID = _id;
currentFSM.DoBeforEnter();//新的状态进入调用方法
}
}