**************************************************************************************************************
using System;
using System.Collections.Generic;
using UnityEngine;
///
/// 状态机类,管理各个状态实例。
/// 作用
/// 1.把能够切换管理的各个状态注册到状态机里。
/// 2.移除状态
/// 3.在各个状态间切换的逻辑
/// 4.不断的更新当前状态
///
///
///
/// 通俗点讲,
/// 1.有限状态机是:将对象的状态(攻击、闲置、晕眩)的实现代码,提取出来,封装成状态。
/// 由状态机负责在各个状态之间调度。
// 2 .对象(AI对象)持有状态管理类(状态机)的引用,与具体的状态解耦
///
public class FSM
{
private Dictionary
//当前状态
private IState currentState;
private GameObject role; //关联一个游戏兑现(AI对象)
public GameObject Role
{
get { return role; }
}
public FSM(GameObject role)
{
this.role = role;
stateDic = new Dictionary
}
//注册状态
///
/// 只有注册过的状态才可以被切换
///
///
public void registerState(IState state)
{
IState s;
stateDic.TryGetValue(state.stateType, out s);
if (s == null)
{
state.fsm = this;
stateDic.Add(state.stateType, state);
}
else
{
Debug.Log("已经有" + state.stateType + "了,不可以重复注册");
}
}
///
///
///
///
public void removeState(StateType stateType)
{
if (currentState.stateType != stateType)
{
IState s;
stateDic.TryGetValue(stateType, out s);
if (s != null)
{
stateDic.Remove(stateType);
}
else
{
Debug.Log(stateType + "还没有注册,移除失败。");
}
}
else
{
Debug.Log(stateType + "是当前状态,移除失败。");
}
}
///
/// 切换状态
/// 1.退出之前状态
/// 2.进入要进入的状态
///
/// 要进入的状态的类型。
public void changeState(StateType type)
{
IState s;
stateDic.TryGetValue(type, out s);
if (s != null)
{
if (currentState != null)
currentState.ExitState();//退出之前的状态
s.EnterState(); ///进入状态,
currentState = s;///当前状态更改为已经进入的状态
}
else
{
Debug.Log(type + "还没有被注册进状态机");
}
}
//更新当前状态
public void Update(float deltaTime)
{
if (currentState != null)
{
currentState.StateUpdate(deltaTime);
}
}
public void LateUpdate(float deltaTime)
{
if (currentState != null)
{
currentState.StateLateUpdate(deltaTime);
}
}
}
***************************************************************************************************
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonsterController : MonoBehaviour
{
//此怪物的的状态机
private FSM fsm;
[SerializeField]
private GameObject fxPrefab;
private void Awake()
{
fsm = new FSM(this.gameObject);
fsm.registerState(new FollowState());
fsm.registerState(new AttackState());
fsm.registerState(new PartrolState());
fsm.registerState(new DeathState());
fsm.changeState(StateType.Partrol);
}
void Start()
{
}
// Update is called once per frame
void Update()
{
///更新状态机
if (fsm != null)
{
fsm.Update(Time.deltaTime);
}
}
private void LateUpdate()
{
if(fsm!=null)
{
fsm.LateUpdate(Time.deltaTime);
}
}
///
/// 死亡后调用此方法。
///
public void OnDeath()
{
GameObject fx = GameObject.Instantiate(fxPrefab);
fx.transform.position = this.transform.position + new Vector3(0, 0.6f, 0);
this.fsm.changeState(StateType.Death);
}
public void OnDefeat()
{
this.GetComponent
GameObject fx = GameObject.Instantiate(fxPrefab);
fx.transform.position = this.transform.position+new Vector3(0,0.6f,0);
}
}
*******************************************************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
public class DeathState : IState
{
public FSM fsm
{
get;set;
}
public StateType stateType
{
get { return StateType.Death; }
}
public void EnterState()
{
this.fsm.Role.GetComponent
}
public void ExitState()
{
}
public void StateLateUpdate(float deltaTime)
{
}
public void StateUpdate(float deltaTime)
{
AnimatorStateInfo stateinfo = this.fsm.Role.GetComponent
if(stateinfo.IsName("Death")&&stateinfo.normalizedTime%1>0.95f)
{
GameObject.Destroy(this.fsm.Role);
SpawnEnemy.Instance.EnemyList.Remove(this.fsm.Role);
}
}
}
**********************************************************************************************************************************
using UnityEngine;
using UnityEngine.AI;
public class FollowState : IState
{
private GameObject targetObj; //玩家
/// =========实现的接口中方法======
public FSM fsm
{
get;set;
}
public StateType stateType
{
get
{
return StateType.Follow;
}
}
//状态进入,初始化
public void EnterState()
{
targetObj = GameObject.FindGameObjectWithTag("Player");
this.fsm.Role.GetComponent
this.fsm.Role.GetComponent
}
///
///
///
public void ExitState()
{
this.fsm.Role.GetComponent
}
public void StateUpdate(float deltaTime)
{
//向玩家移动
this.fsm.Role.GetComponent
AnimatorStateInfo stateinfo = this.fsm.Role.GetComponent
if(stateinfo.IsName("Run"))
{
this.fsm.Role.GetComponent
}
else
{
this.fsm.Role.GetComponent
}
}
///
/// 做一些向其他状态切换的条件判断,及切换。
///
///
public void StateLateUpdate(float deltaTime)
{
float dis = Vector3.Distance(this.fsm.Role.transform.position, targetObj.transform.position);
if (dis < 1)
{
this.fsm.changeState(StateType.Attack);
}
else if (dis > 6)
{
this.fsm.changeState(StateType.Partrol);
}
}
}
**************************************************************************************************************************
using UnityEngine;
using UnityEngine.AI;
public class PartrolState : IState
{
private GameObject targetObj;
private Vector3 v;
private float timeCount;
public FSM fsm
{
get; set;
}
public StateType stateType
{
get { return StateType.Partrol; }
}
public void EnterState()
{
timeCount = 0;
targetObj = GameObject.FindGameObjectWithTag("Player");
this.fsm.Role.GetComponent
}
public void ExitState()
{
this.fsm.Role.GetComponent
}
public void StateLateUpdate(float deltaTime)
{
float dis = Vector3.Distance(this.fsm.Role.transform.position, targetObj.transform.position);
if (dis < 6)
{
this.fsm.changeState(StateType.Follow);
}
else if (dis < 1)
{
this.fsm.changeState(StateType.Attack);
}
}
public void StateUpdate(float deltaTime)
{
//随机走。
if(timeCount>3)
{
timeCount = 0; //归零
Vector2 vec = UnityEngine.Random.insideUnitCircle;
Vector2 randomPos = vec * 2 + vec.normalized * 2; //2---10米的随机向量
v = this.fsm.Role.transform.position + new Vector3(randomPos.x, 0, randomPos.y);
this.fsm.Role.GetComponent
}
else
{
timeCount += deltaTime;
}
}
}