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 · 訪問量 9158
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章