Unity SKFramework框架(三)、FSM 有限状态机

2022-08-29 17:04:21 浏览数 (1)

一、State 状态

1.核心属性

代码语言:javascript复制
/// <summary>
/// 状态名称
/// </summary>
public string Name { get; set; }

2.核心事件

OnInitialization 状态初始化事件

OnEnter 状态进入事件

OnStay 状态停留事件

OnExit 状态退出事件

OnTermination 状态终止事件

代码语言:javascript复制
public class ExampleState : State
{
    public override void OnInitialization()
    {
        Debug.Log(string.Format("{0}状态初始化", Name));
    }
    public override void OnEnter()
    {
        Debug.Log(string.Format("{0}状态进入", Name));
    }
    public override void OnStay()
    {
        Debug.Log(string.Format("{0}状态停留", Name));
    }
    public override void OnExit()
    {
        Debug.Log(string.Format("{0}状态退出", Name));
    }
    public override void OnTermination()
    {
        Debug.Log(string.Format("{0}状态终止", Name));
    }
}

二、StateMachine 状态机

1.核心属性

代码语言:javascript复制
/// <summary>
/// 状态机名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 当前状态
/// </summary>
public IState CurrentState { get; protected set; }

2.Create 创建状态机

代码语言:javascript复制
using UnityEngine;
using SK.Framework;

public class Example : MonoBehaviour
{
    private void Start()
    {
        var machine = StateMachine.Create("Example");
    }
}

传入string类型参数,表示状态机的命名,通过名称可以获取、销毁状态机。

3.Get 获取状态机

代码语言:javascript复制
using UnityEngine;
using SK.Framework;

public class Example : MonoBehaviour
{
    private void Start()
    {
        var machine = StateMachine.Get("Example");
    }
}

4.Destroy 销毁状态机

代码语言:javascript复制
private void OnDestroy()
{
    StateMachine.Destroy("Example");
}

5.核心行为

(1).添加状态

代码语言:javascript复制
/// <summary>
/// 添加状态
/// </summary>
/// <param name="state">状态</param>
/// <returns>添加成功返回true 否则返回false</returns>
public bool Add(IState state)
/// <summary>
/// 添加状态
/// </summary>
/// <typeparam name="T">状态类型</typeparam>
/// <param name="stateName">状态命名</param>
/// <returns>添加成功返回true 否则返回false</returns>
public bool Add<T>(string stateName = null) where T : IState, new()

除此之外,可以通过Build构建状态实现添加,用于链式编程:

代码语言:javascript复制
/// <summary>
/// 构建状态
/// </summary>
/// <typeparam name="T">状态类型</typeparam>
/// <param name="stateName">状态名称</param>
/// <returns>状态构建器</returns>
public StateBuilder<T> Build<T>(string stateName = null) where T : State, new()

(2).移除状态

代码语言:javascript复制
/// <summary>
/// 移除状态
/// </summary>
/// <param name="state">状态</param>
/// <returns>移除成功返回true 否则返回false</returns>
public bool Remove(IState state)
/// <summary>
/// 移除状态
/// </summary>
/// <param name="stateName">状态名称</param>
/// <returns>移除成功返回true 否则返回false</returns>
public bool Remove(string stateName)
/// <summary>
/// 移除状态
/// </summary>
/// <typeparam name="T">状态类型</typeparam>
/// <returns>移除成返回true 否则返回false</returns>
public bool Remove<T>() where T : IState

(3).切换状态

代码语言:javascript复制
/// <summary>
/// 切换状态
/// </summary>
/// <param name="state">状态</param>
/// <returns>切换成功返回true 否则返回false</returns>
public bool Switch(IState state)
/// <summary>
/// 切换状态
/// </summary>
/// <param name="stateName">状态名称</param>
/// <returns>切换成功返回true 否则返回false</returns>
public bool Switch(string stateName)
/// <summary>
/// 切换状态
/// </summary>
/// <typeparam name="T">状态类型</typeparam>
/// <returns>切换成返回true 否则返回false</returns>
public bool Switch<T>() where T : IState
/// <summary>
/// 切换至下一状态
/// </summary>
public void Switch2Next()
/// <summary>
/// 切换至上一状态
/// </summary>
public void Switch2Last()
/// <summary>
/// 切换至空状态(退出当前状态)
/// </summary>
public void Switch2Null()

(4).获取状态

代码语言:javascript复制
/// <summary>
/// 获取状态
/// </summary>
/// <typeparam name="T">状态类型</typeparam>
/// <param name="stateName">状态名称</param>
/// <returns>状态</returns>
public T GetState<T>(string stateName) where T : IState
/// <summary>
/// 获取状态
/// </summary>
/// <typeparam name="T">状态类型</typeparam>
/// <returns>状态</returns>
public T GetState<T>() where T : IState

(5).设置切换条件

代码语言:javascript复制
/// <summary>
/// 设置状态切换条件
/// </summary>
/// <param name="predicate">切换条件</param>
/// <param name="targetStateName">目标状态名称</param>
/// <returns>状态机</returns>
public StateMachine SwitchWhen(Func<bool> predicate, string targetStateName)
/// <summary>
/// 设置状态切换条件
/// </summary>
/// <param name="predicate">切换条件</param>
/// <param name="sourceStateName">源状态名称</param>
/// <param name="targetStateName">目标状态名称</param>
/// <returns></returns>
public StateMachine SwitchWhen(Func<bool> predicate, string sourceStateName, string targetStateName)
三、编码示例

1.Simple

代码语言:javascript复制
using UnityEngine;
using SK.Framework;

public class Example : MonoBehaviour
{
    public class ExampleState : State
    {
        public override void OnInitialization()
        {
            Debug.Log(string.Format("{0}状态初始化", Name));
        }
        public override void OnEnter()
        {
            Debug.Log(string.Format("{0}状态进入", Name));
        }
        public override void OnStay()
        {
            Debug.Log(string.Format("{0}状态停留", Name));
        }
        public override void OnExit()
        {
            Debug.Log(string.Format("{0}状态退出", Name));
        }
        public override void OnTermination()
        {
            Debug.Log(string.Format("{0}状态终止", Name));
        }
    }

    private void Start()
    {
        var machine = StateMachine.Create("示例状态机");
        machine.Add(new ExampleState() { Name = "State1" });
        machine.Add<State>("State2");
        machine.Add<State>("State3");
        machine.Switch("State2");
        machine.Switch2Next();
        machine.Switch2Last();
        machine.Switch2Null();
        machine.SwitchWhen(() => Input.GetKeyDown(KeyCode.Alpha1), "State1");
        machine.SwitchWhen(() => Input.GetKeyDown(KeyCode.Alpha2), "State2");
        machine.SwitchWhen(() => Input.GetKeyDown(KeyCode.Alpha3), "State3");
    }
}
代码语言:javascript复制
2.链式
代码语言:javascript复制
using UnityEngine;
using SK.Framework;
 
public class Example: MonoBehaviour
{
    public class TestState : State
    {
        public string stringValue;
    }
 
    private void Start()
    {
        //创建状态机
        var machine = StateMachine.Create("示例状态机")
            //构建状态一
            .Build<TestState>("状态一")
                //设置状态一初始化事件
                .OnInitialization(state => state.stringValue = "A")
                //设置状态一进入事件
                .OnEnter(state => Debug.Log("进入状态一"))
                //设置状态一停留事件
                .OnStay(state => Debug.Log("状态一"))
                //设置状态一推出事件
                .OnExit(state => Debug.Log("退出状态一"))
                //设置状态一销毁事件
                .OnTermination(state => state.stringValue = null)
            //状态一构建完成
            .Complete()
            //构建状态二
            .Build<State>("状态二")
                //设置状态二进入事件
                .OnEnter(state => Debug.Log("进入状态二"))
                //设置状态二停留事件
                .OnStay(state => Debug.Log("状态二"))
                //设置状态二退出事件
                .OnExit((state => Debug.Log("退出状态二")))
            //状态二构建完成
            .Complete()
            //构建状态三
            .Build<State>("状态三")
                //设置状态三进入事件
                .OnEnter(state => Debug.Log("进入状态三"))
                //设置状态三停留事件
                .OnStay(state => Debug.Log("状态三"))
                //设置状态三退出事件
                .OnExit((state => Debug.Log("退出状态三")))
            //状态三构建完成
            .Complete()
            //添加状态切换条件 当按下快捷键1时 切换至状态一
            .SwitchWhen(() => Input.GetKeyDown(KeyCode.Alpha1), "状态一")
            //添加状态切换条件 当按下快捷键2时 切换至状态二
            .SwitchWhen(() => Input.GetKeyDown(KeyCode.Alpha2), "状态二")
            //添加状态切换条件 当按下快捷键3时 切换至状态三
            .SwitchWhen(() => Input.GetKeyDown(KeyCode.Alpha3), "状态三")
            //为状态一至状态二添加切换条件:若当前状态为状态一时 按下快捷键4 切换至状态二
            .SwitchWhen(() => Input.GetKeyDown(KeyCode.Alpha4), "状态一", "状态二");
 
        //切换到指定状态
        machine.Switch("状态一");
        //切换到下一状态
        machine.Switch2Next();
        //切换到上一状态
        machine.Switch2Last();
    }
}

0 人点赞