管理类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 管理类
/// </summary>
public class FSMSystem {
public Dictionary<StateID, FSMState> states = new Dictionary<StateID, FSMState>();
private StateID currentStateID;
private FSMState currentState;
public void Update(GameObject obj)
{
currentState.Act(obj);
currentState.Reason(obj);
}
/// <summary>
/// 添加状态
/// </summary>
/// <param name="s">状态</param>
public void AddState(FSMState s)
{
if(s==null)
{
Debug.LogError("FSMState为空");
return;
}
if (currentState ==null)
{
currentState = s;
currentStateID = s.ID;
}
if (states .ContainsKey (s.ID))
{
Debug.LogError("该状态已存在");
return;
}
states.Add(s.ID, s);
}
/// <summary>
/// 状态删除
/// </summary>
/// <param name="id"></param>
public void DelegateState(StateID id)
{
if(id ==StateID .NullStateID)
{
Debug.LogError("无法删除空状态");
return;
}
if (states .ContainsKey (id )==false)
{
Debug.LogError("无法删除不存在的状态");
return;
}
states.Remove(id);
}
/// <summary>
/// 状态转换
/// </summary>
/// <param name="trans"></param>
public void PerfromTransition(Transition trans)
{
if(trans==Transition.NullTransition)
{
Debug.LogError("空的转换条件");
return;
}
StateID id = currentState.GetOutputState(trans);
if (id == StateID.NullStateID)
{
Debug.LogError("无法根据条件转换");
return;
}
if (states.ContainsKey(id )==false)
{
Debug.LogError("状态机里不存在该转态,无法转换");
return;
}
FSMState state = states[id];
currentState.DoAdterLeaving();
currentState = state;
currentStateID = id;
currentState.DoBeforEntering();
}
}
基类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Transition
{
NullTransition=0,
/// <summary>
/// 看见主角
/// </summary>
SeePlayer,
/// <summary>
/// 主角消失
/// </summary>
LostPlayer
}
public enum StateID
{
NullStateID=0,
/// <summary>
/// 巡逻
/// </summary>
Patorl,
/// <summary>
/// 追逐主角
/// </summary>
Chase
}
/// <summary>
/// 状态基类
/// </summary>
public abstract class FSMState {
protected StateID stateID;
public StateID ID {get{return stateID ;}}
protected Dictionary<Transition, StateID> map = new Dictionary<Transition, StateID>();
protected FSMSystem fsm;
protected FSMState(FSMSystem fsm )
{
this.fsm = fsm;
}
/// <summary>
/// 添加状态
/// </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("不允许Nullstate");
return;
}
if (map .ContainsKey (trans ))
{
Debug.LogError("已存在");
return;
}
map.Add(trans, id);
}
/// <summary>
/// 删除状态
/// </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("不存在");
return;
}
map.Remove(trans);
}
/// <summary>
/// 判断当前状态
/// </summary>
/// <param name="trans"></param>
/// <returns></returns>
public StateID GetOutputState(Transition trans)
{
if (map.ContainsKey (trans))
{
return map[trans];
}
return StateID.NullStateID;
}
/// <summary>
/// 进入状态之前所做的状态
/// </summary>
public virtual void DoBeforEntering() { }
/// <summary>
/// 离开状态的时候
/// </summary>
public virtual void DoAdterLeaving() { }
/// <summary>
/// 在当前状态下要做的事情
/// </summary>
public abstract void Act(GameObject obj);
/// <summary>
/// 判断转换条件
/// </summary>
public abstract void Reason(GameObject obj);
}
两个AI状态:1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 巡逻状态
/// </summary>
public class PatrolState : FSMState
{
private List <Transform > path=new List<Transform> ();
private int index = 0;
private Transform playerTransform;
public float jvLi = 3;
public PatrolState (FSMSystem fsm):base (fsm)
{
stateID = StateID.Patorl;
Transform pathTransform = GameObject.Find("Path").transform;
Transform[] children = pathTransform.GetComponentsInChildren<Transform > ();
foreach (Transform item in children )
{
if (item !=pathTransform)
{
path.Add(item);
}
}
playerTransform = GameObject.FindGameObjectWithTag(StringText .Player ).transform;
}
/// <summary>
/// 处于当前状态时要做的事
/// </summary>
/// <param name="obj"></param>
public override void Act(GameObject obj)
{
obj.transform.LookAt(path[index].position );
obj.transform.Translate(Vector3.forward * Time.deltaTime * 2);
if (Vector3 .Distance (obj.transform .position ,path[index ].position) < 0.5f)
{
index++;
index %= path.Count;
}
}
/// <summary>
/// 判断转换条件
/// </summary>
/// <param name="obj"></param>
public override void Reason(GameObject obj)
{
//throw new System.NotImplementedException();
if (Vector3 .Distance (playerTransform .position ,obj .transform .position) < jvLi )
{
fsm.PerfromTransition(Transition.SeePlayer);
}
}
}
2
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 追逐Player
/// </summary>
public class ChaseState : FSMState
{
public float speed = 2;
private Transform playerTransform;
private float jvLi=6;
public ChaseState(FSMSystem fsm) : base(fsm)
{
stateID = StateID.Chase;
playerTransform = GameObject.FindGameObjectWithTag(StringText.Player).transform;
}
public override void Act(GameObject obj)
{
obj.transform.LookAt(playerTransform.position);
obj.transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
public override void Reason(GameObject obj)
{
if (Vector3.Distance(playerTransform.position, obj.transform.position) > jvLi)
{
fsm.PerfromTransition(Transition.LostPlayer);
}
}
}
调用:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 敌人
/// </summary>
public class Enemy : MonoBehaviour {
FSMSystem fsm;
void Start () {
fsm = new FSMSystem();
FSMState patrolState = new PatrolState(fsm);
patrolState.Addtransition(Transition.SeePlayer, StateID.Chase);
FSMState chaseState = new ChaseState(fsm);
chaseState.Addtransition(Transition.LostPlayer, StateID.Patorl);
fsm.AddState(patrolState);
fsm.AddState(chaseState);
}
void Update () {
fsm.Update(this.gameObject);
}
}