Unity 从零开始的框架搭建1-7 FSM有限状态机与其应用示例
本文小白可能看不懂,所以引路:【最用心 の Unity百宝箱】4. 有限状态机_哔哩哔哩_bilibili
当然,我不是按照小棋这么写的,但是思想都是一样的
另外说句题外话,配合动画状态机的函数用代码去控制逻辑才是真理,大量连线会导致项目无法维护,比如unity商店某Poly FPS PACKAGE里面的动画状态机
目录
1.单例基类
2.Mono代理
3.状态基类
4.状态机类
5.应用
1.单例基类
不懂单例模式?
C# & Unity 设计模式 之 单例模式_unity 使用单例做变量初始化-CSDN博客
using UnityEngine;
public class SingltonMono<T> : MonoBehaviour where T : SingltonMono<T>
{
public static T Instance;
protected virtual void Awake()
{
if (Instance == null)
{
Instance = this as T;
}
}
}
2.Mono代理
看不懂Mono代理?
一言蔽之:让没有继承MonoBehaviour的类之中使用 MonoBehaviour 的 生命周期方法等
using System;
public class MonoManager : SingltonMono<MonoManager>
{
private Action UpdateAction;
private Action LaterUpdateAction;
private Action FixedUpdateAction;
public void AddUpdate(Action action)
{
UpdateAction += action;
}
public void AddLaterUpdate(Action action)
{
LaterUpdateAction += action;
}
public void AddFixedUpdate(Action action)
{
FixedUpdateAction += action;
}
public void RemoveUpdate(Action action)
{
UpdateAction -= action;
}
public void RemoveLaterUpdate(Action action)
{
LaterUpdateAction -= action;
}
public void RemoveFixedUpdate(Action action)
{
FixedUpdateAction -= action;
}
private void Update()
{
UpdateAction?.Invoke();
}
private void LateUpdate()
{
LaterUpdateAction?.Invoke();
}
private void FixedUpdate()
{
FixedUpdateAction?.Invoke();
}
}
3.状态基类
看不懂状态基类?
我不信你看不懂,这都看不懂就滚去学oop!
C# & Unity 面向对象补全计划 之 初识继承方法与多态(干货)_unity 继承-CSDN博客
public abstract class StateBase
{
public virtual void Init(IStateMachineOwner owner) { }
public virtual void UnInit() { }
public virtual void Enter() { }
public virtual void Exit() { }
public virtual void Update() { }
public virtual void LateUpdate() { }
public virtual void FixedUpdate()
{
}
}
4.状态机类
IStateMachineOwner接口利用了里氏替换
C# & Unity 面向对象补全计划 七大原则 之 里氏替换(LSP) 难度:☆☆☆ 总结:子类可以当父类用,牛马是马,骡马也是马-CSDN博客
以及类似控制反转的方式(看下文高级使用实例)
C# & Unity 面向对象补全计划 之 接口_unity c# 接口-CSDN博客
using System;
using System.Collections.Generic;
public interface IStateMachineOwner
{
}
public class StateMechine
{
private IStateMachineOwner owner; //Any Class can be onwner only inherit this interface
private Dictionary<Type, StateBase> statesDic = new Dictionary<Type, StateBase>();
public StateBase currentStateBase;
public Type CurrentStateType => currentStateBase?.GetType();
public bool HasState => currentStateBase != null;
//初始化状态机
public void Init(IStateMachineOwner owner)
{
this.owner = owner;
}
//切换状态
public bool ChangeState<T>(bool needRewState = false) where T : StateBase, new()
{
//check state is consistent
if (HasState && CurrentStateType == typeof(T) && !needRewState) return false;
//exit
if (currentStateBase != null)
{
currentStateBase.Exit();
MonoManager.Instance.RemoveFixedUpdate(currentStateBase.Update);
MonoManager.Instance.RemoveLaterUpdate(currentStateBase.LateUpdate);
MonoManager.Instance.RemoveUpdate(currentStateBase.Update);
}
currentStateBase = GetState<T>();
currentStateBase.Enter();
MonoManager.Instance.AddUpdate(currentStateBase.Update);
MonoManager.Instance.AddLaterUpdate(currentStateBase.LateUpdate);
MonoManager.Instance.AddFixedUpdate(currentStateBase.FixedUpdate);
return false;
}
//获取状态
public StateBase GetState<T>() where T : StateBase, new()
{
if (!statesDic.TryGetValue(typeof(T), out StateBase TryState))
{
T t = new T();
t.Init(owner);
statesDic.Add(typeof(T), t);
TryState = t;
}
return TryState;
}
//停止状态机
public void Stop()
{
currentStateBase.Exit();
MonoManager.Instance.RemoveUpdate(currentStateBase.Update);
MonoManager.Instance.RemoveLaterUpdate(currentStateBase.LateUpdate);
MonoManager.Instance.RemoveFixedUpdate(currentStateBase.FixedUpdate);
currentStateBase = null;
foreach (var item in statesDic.Values)
{
item.UnInit();
}
statesDic.Clear();
}
}
5.应用
所示工程文件链接如下,因为我比较菜 所以填了一些坑 花了一下午才写这么点功能实在惭愧:
通过网盘分享的文件:Assets.7z链接: https://pan.baidu.com/s/1yqALCXDFgDnb7Trs2181EQ?pwd=1234 提取码: 1234
视频请看这个
状态机应用
我b站好像也发了
分享一下最近的想法_哔哩哔哩_bilibili