- FSM主要用来配合animator实现NPC,AI或是UI的状态切换,如果状态比较少的话直接用switch或者只用animator也可以,不过为了可扩展性和学习的考虑还是写一下比较好,可惜自己太菜不会写,学习一波大佬的代码
- 先定义了一个抽象类BaseState
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class BaseState
{
protected FsmManager _fsmManager;
//构造函数
public BaseState(FsmManager fsmManager)
{
_fsmManager = fsmManager;
}
//进入状态
public abstract void EnterState();
//离开状态
public abstract void ExitState();
//更新状态
public abstract void UpdateState();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FsmManager
{
private BaseState currentState;//当前状态
private Dictionary<string, BaseState> playerStateDic = new Dictionary<string, BaseState>();//储存状态的字典
public FsmManager() { }
//状态注册
public void Region(string statename, BaseState state)
{
if (!playerStateDic.ContainsKey(statename))
{
playerStateDic.Add(statename, state);
}
}
//设置默认状态
public void SetDefaultState(string statename)
{
if (playerStateDic.ContainsKey(statename))
{
currentState = playerStateDic[statename];
currentState.EnterState();
}
}
//改变状态
public void ChangeState(string statename)
{
if (playerStateDic.ContainsKey(statename))
{
if (currentState != null)
{
if (!(currentState == playerStateDic[statename]))
{
currentState.ExitState();
currentState = playerStateDic[statename];
currentState.EnterState();
}
}
}
}
//更新状态
public void UpdateState()
{
if (currentState != null)
{
currentState.UpdateState();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerWalkState : BaseState
{
//当一个子类继承父类的时候,子类构造函数默认调用父类的无参数构造函数,如果父类没有无参数的构造函数则报错.
//构造函数是不能继承的,只能子类指定调用父类的构造函数,即:base()
public PlayerWalkState(FsmManager fsmManager) : base(fsmManager) { }
public override void EnterState()
{
}
public override void ExitState()
{
}
public override void UpdateState()
{
//例如当满足条件A的时候状态从走变成跑
if (A){
_fsmManager.ChangeState("run");
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FSM: MonoBehaviour
{
// Use this for initialization
public FsmManager fsmManager;
void Start()
{
fsmManager = new FsmManager();
//注册状态
fsmManager.Region("walk", new PlayerWalkState(fsmManager, playerAnim));
fsmManager.Region("run", new PlayerRunState(fsmManager, playerAnim));
fsmManager.Region("jump", new PlayerJumpState(fsmManager, playerAnim));
//设置默认状态
fsmManager.SetDefaultState("walk");
}
// Update is called once per frame
void Update()
{
//更新状态
fsmManager.UpdateState();
}
}