Unity —有限状态机FSM系统(一)

什么是FSM状态机

总的来说,有限状态机系统,是指不同的阶段呈现出不同的运行状态系统,这些状态是有限的,不重叠,这样的系统在某一时刻一定会处于其所有状态中的一个状态,此时他接受一部分允许的输入,产生一部分可能的响应,并且迁移到一部分可能的状态。

五大要素

  1. 状态
  2. 事件
  3. 条件
  4. 动作
  5. 迁移

游戏运用在这里插入图片描述

案例演示

在这里插入图片描述
说明:Enemy 是游戏中的一个敌人脚本类,持有FSMSystem(状态管理类),通过改变敌人的状态(FSMState)来实现敌人在不同状态市因执行什么样的操作。 StateID (状态ID),Transiton (状态类型)。

功能

敌人在三个点之间巡逻(巡逻状态),当主角靠近时,敌人切换到跟随状态,(跟随状态),当主角离远时,敌人切换到巡逻状态。

FSMState 状态父级类

定义状态父级类,之后的每个状态子类都继承于FSMState类。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum Transiton
{
    NullTransiton = 0,
    SeePlayer = 1,
    LostPlayer = 2,
}

public enum StateID                 //状态id
{
    NullStateID = 0,
    patrol = 1,
    Chase = 2,
}

/// <summary>
/// 状态机框架
/// </summary>
public abstract class FSMState
{
    protected StateID stateID;
    public StateID ID { get { return stateID; } }
    protected Dictionary<Transiton, StateID> map = new Dictionary<Transiton, StateID>();
    protected FSMSystem fsm;
    public FSMState(FSMSystem _fsm)
    {
        fsm = _fsm;
    }

    //添加转换条件
    public void AddTransition(Transiton trans, StateID id)
    {
        if (trans == Transiton.NullTransiton)
        {
            Debug.LogError("..................");
            return;
        }
        if (id == StateID.NullStateID)
        {
            Debug.LogError("=================");
            return;
        }
        map[trans] = id;
    }

    public void DeleteTransition(Transiton trans)
    {
        if (trans == Transiton.NullTransiton)
        {
            return;
        }
        if (map.ContainsKey(trans) == false)
        {
            return;
        }
        map.Remove(trans);
    }

    /// <summary>
    /// 获取状态
    /// </summary>
    /// <param name="trans"></param>
    /// <returns></returns>
    public StateID GetQutputState(Transiton trans)
    {
        if (map.ContainsKey(trans))
        {
            return map[trans];
        }
        return StateID.NullStateID;
    }

    //状态的生命周期
    public virtual void DobeforEntering() { }           //进入状态
    public virtual void DoAfterLeaving() { }            //俩开状态

    public abstract void Act(GameObject npc);                          //当前状态要做的事情

    public abstract void Reason(GameObject npc);                       //判断转换条件

}

FSMSystem 状态管理类

FSMSystem持有FSMState对象,通过管理FSMState对象进行状态的切换,达到控制敌人在什么情况执行什么样的状态。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 状态机框架 管理类
/// </summary>
public class FSMSystem
{
    private Dictionary<StateID, FSMState> states = new Dictionary<StateID, FSMState>();
    //当前状态
    private StateID currentStateID;
    private FSMState currentState;          //状态对象

    public void Update(GameObject go)
    {
        currentState.Act(go);
        currentState.Reason(go);
    }

    //状态添加
    public void AddSatte(FSMState state)
    {
        if (state == null)
        {
            return;
        }
        if (currentState == null)
        {
            currentState = state;
            currentStateID = state.ID;
        }

        if (states.ContainsKey(state.ID))
        {
            return;
        }
        states.Add(state.ID, state);
    }

    public void DeleteSatte(StateID id)
    {
        if (id == StateID.NullStateID)
        {
            return;
        }

        if (states.ContainsKey(id))
        {
            return;
        }
        states.Remove(id);
    }

    //状态切换
    public void PerformTransition(Transiton trans)
    {
        if (trans == Transiton.NullTransiton)
        {
            return;
        }
        StateID id = currentState.GetQutputState(trans);   //判断是否需要转换
        if (id == StateID.NullStateID)
        {
            return;
        }

        //可以转换
        if (states.ContainsKey(id) == false)
        {
            //不存在
            return;
        }
        FSMState state = states[id];
        currentState.DoAfterLeaving();
        currentState = state;
        currentStateID = id;
        currentState.DobeforEntering();
    }
}

发布了37 篇原创文章 · 获赞 11 · 访问量 6300

猜你喜欢

转载自blog.csdn.net/weixin_42422809/article/details/88412002