-
简单框架实现
1、IState
using UnityEngine;
namespace FSMLearn
{
public interface IState
{
void OnEnter();
void OnUpdate();
void OnExit();
}
2、BaseFSM
using System.Collections.Generic;
using UnityEngine;
namespace FSMLearn
{
public class BaseFSM : MonoBehaviour
{
public IState CurState;
protected Dictionary<State_Enum, IState> states = new Dictionary<State_Enum, IState>();
public virtual void Awake()
{
Init();
}
public virtual void Init()
{
}
public virtual void Update()
{
if(CurState != null)
{
CurState.OnUpdate();
}
}
public void TransitionState(State_Enum state)
{
if(CurState != null)
{
CurState.OnExit();
}
if(states.ContainsKey(state))
{
CurState = states[state];
CurState.OnEnter();
}
else
{
Debug.LogError("states中没有该状态:" + state.ToString());
}
}
}
}
3、State_Enum
// BaseFSM脚本
/// <summary>
/// 状态枚举类型
/// </summary>
public enum State_Enum
{
//自己定义所有的状态枚举
}
-
简单使用
-
需要实现功能,敌人巡逻,玩家和敌人距离小于3米,敌人追逐玩家,距离大于5米时则继续巡逻
1、实现所有需要用到的状态类,并完成对应功能,Patrol ,Figh
public class Patrol : FSMLearn.IState
{
public EnemyFSM baseFSM;
public Transform[] patrolPos;
private int curIndex = 0;
public Patrol(Transform[] posArr, EnemyFSM baseFSM)
{
patrolPos = posArr;
this.baseFSM = baseFSM;
}
void FSMLearn.IState.OnEnter()
{
//throw new System.NotImplementedException();
}
void FSMLearn.IState.OnExit()
{
//throw new System.NotImplementedException();
}
void FSMLearn.IState.OnUpdate()
{
//throw new System.NotImplementedException();
if(Vector3.Distance(baseFSM.transform.position, patrolPos[curIndex].position) < 0.2f)
{
curIndex = (curIndex + 1) % patrolPos.Length;
baseFSM.transform.LookAt(patrolPos[curIndex].position);
}
Vector3 dir = (patrolPos[curIndex].position - baseFSM.transform.position).normalized;
baseFSM.transform.LookAt(patrolPos[curIndex].position);
baseFSM.transform.position += dir * 3 * Time.deltaTime;
}
}
public class Fight : FSMLearn.IState
{
public EnemyFSM baseFSM;
public Transform target;
public Fight(EnemyFSM baseFSM)
{
this.baseFSM = baseFSM;
}
void FSMLearn.IState.OnEnter()
{
target = GameObject.FindWithTag("Player").transform;
baseFSM.transform.LookAt(target.position);
}
void FSMLearn.IState.OnExit()
{
//throw new System.NotImplementedException();
}
void FSMLearn.IState.OnUpdate()
{
Vector3 dir = (target.position - baseFSM.transform.position).normalized;
baseFSM.transform.LookAt(target.position);
baseFSM.transform.position += dir * 3 * Time.deltaTime;
}
}
2、定义状态类枚举,巡逻状态,追逐敌人状
// BaseFSM脚本
/// <summary>
/// 状态枚举类型
/// </summary>
public enum State_Enum
{
巡逻状态,
追逐敌人状态
}
3、继承BaseFSM,注册状态并在Update函数实现状态条件切换
using FSMLearn;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class EnemyFSM : FSMLearn.BaseFSM
{
public Transform[] patrolPosArr;
public Transform player;
public override void Init()
{
base.Init();
states.Add(State_Enum.巡逻状态, new Patrol(patrolPosArr, this));
states.Add(State_Enum.追逐敌人状态, new Fight(this));
TransitionState(State_Enum.巡逻状态);
}
public override void Update()
{
base.Update();
if(Vector3.Distance(player.position, transform.position) < 3)
{
TransitionState(State_Enum.追逐敌人状态);
}
if(Vector3.Distance(player.position, transform.position) > 5)
{
TransitionState(State_Enum.巡逻状态);
}
}
}