使用代码关联unity有限状态机
注:参考来自b站up主 Joker_Unity 的教程视频,完整视频链接: unity中文课堂
在战斗系统中通常使用有限状态机对角色的各个状态(移动、攻击等)进行管理。为了应对复杂的状态转化,我们可以使用C#代码自定义状态机或行为树的节点。
先创建所需的基类:
- 状态基类
- 有限状态机基类(后续角色的基类)
在unity中创建 StateBase 、FSMController 脚本,如下:
创建状态基类
在该基类中应具有以下成员:
- 当前的状态(枚举值)
- 持有该状态对象的控制器
- 初始化函数
- 进入、停留、离开该状态时的函数
在定义枚举值时,由于后续需求的枚举类型是未知的,因此我们使用宽泛的Enum类型:
public Enum stateType;
完整代码如下:
using System;
public abstract class StateBase
{
public Enum stateType;
public FSMController controller;
public virtual void Init(FSMController controller, Enum stateType)
{
this.controller = controller;
this.stateType = stateType;
}
public abstract void OnEnter();
public abstract void OnUpdate();
public abstract void OnExit();
}
创建有限状态机基类
在该基类中应具有以下成员:
- 该状态机当前所处于的状态(枚举值)
- 当前所持有的状态对象
- 修改为指定状态的函数
完整代码为:
using UnityEngine;
using System;
using System.Collections.Generic;
public abstract class FSMController : MonoBehaviour
{
public abstract Enum CurretState { get; set; }
protected StateBase CurrStateObj;
private List<StateBase> stateList;
public void ChangeState(Enum newState, bool reCurrState = false)
{
if (newState == CurretState && !reCurrState) return;
if(CurrStateObj!=null) CurrStateObj.OnExit();
CurrStateObj = GetStateObj(newState);
CurrStateObj.OnEnter();
}
private StateBase GetStateObj(Enum stateType)
{
for (int i = 0; i < stateList.Count; i++)
{
if (stateList[i].stateType == stateType) return stateList[i];
}
StateBase state=Activator.CreateInstance(Type.GetType(stateType.ToString())) as StateBase;
state.Init(this,stateType);
stateList.Add(state);
return state;
}
protected virtual void Update()
{
if(CurrStateObj!=null) CurrStateObj.OnUpdate();
}
}
|