• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Unity学习之FSM有限状态机

c# 搞代码 4年前 (2022-01-09) 15次浏览 已收录 0个评论

前言:一个游戏里的一个人物会存在多种状态,那么就需要有一个专门管理这些状态的类。不然会显得杂乱无章,不易于后面状态的增加或者减少。
思路:既然要方便管理,那么首先肯定得有个系统类(专门用来存放所有的状态、状态的增删等功能);然后就是需要把所有的状态都单独写一个类(已达到修改某个状态的时候,其他状态不会受到影响)。

状态管理类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FSMSystem 
{
    private Dictionary<StateID, FSMState> states = new Dictionary<StateID, FSMState>();

    private StateID currentStateID;
    private FSMState currentFSMState;

    public void Update(GameObject npc)
    {
        currentFSMState.Act(npc);
        currentFSMState.Reason(npc);
    }

    /// <summary>
    /// 添加状态
    /// </summary>
    /// <param name="fSMState"></param>
    public void AddState(FSMState fSMState)
    {
        if (fSMState == null) return;

        //if (currentFSMState == null)
        //{
            currentStateID = fSMState.ID;
            currentFSMState = fSMState;
        //}
        if (states.ContainsKey(currentStateID)) return;
        states.Add(currentStateID, currentFSMState);
    }
    /// <summary>
    /// 删除状态
    /// </summary>
    /// <param name="stateID"></param>
    public void DeleteState(StateID stateID)
    {
        if (stateID == StateID.Null) return;
        if (!states.ContainsKey(stateID)) return;

        states.Remove(stateID);
    }
    

    /// <summary>
    /// 执行状态条件转换
    /// </summary>
    /// <param name="transition"></param>
    public void PerformTransition(Transition transition)
    {
        if (transition == Transition.NullTransition) return;

        StateID stateID = currentFSMState.GetStateID(transition);
        if (stateID == StateID.Null) return;
        if (!states.ContainsKey(stateID)) return;

        FSMState fSMState = states[stateID];
        currentFSMState.StateExit();
        currentFSMState = fSMState;
        currentStateID = fSMState.ID;
        currentFSMState.StateEnter();
    }
}

状态基类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum Transition
{
    NullTransition,
    SeePlayer,//发现玩家
    LostPlayer,//玩家脱离视野范围
    AttackPlayer,//攻击玩家
}
public enum StateID
{
    Null,
    Chase,//追逐
    Patrol,//巡逻
    Attack,//攻击
}
public abstract class FSMState
{
    protected Transition transition;

    protected StateID stateID;
    protected FSMSystem fSM;
    public StateID ID
    {
        get { return stateID; }
    }

    protected Dictionary<Transition, StateID> dic = new Dictionary<Transition, StateID>();

    public FSMState(FSMSystem fSM)
    {
        this.fSM = fSM;
    }

    /// <summary>
    /// 增加状态
    /// </summary>
    /// <param name="transition"></param>
    /// <param name="stateID"></param>
    public void AddTransition(Transition transition, StateID stateID)
    {
        if (transition == Transition.NullTransition) return;
        if (stateID == StateID.Null) return;
        if (dic.ContainsKey(transition)) return;

        dic.Add(transition, stateID);
    }
    /// <summary>
    /// 删除状态
    /// </summary>
    /// <param name="transition"></param>
    public void DeleteTransition(Transition transition)
    {
        if (transition == Transition.NullTransition) return;
        if (!dic.ContainsKey(transition)) return;

        dic.Remove(transition);
    }
    /// <summary>
    /// 获取状态
    /// </summary>
    /// <param name="transition"></param>
    /// <returns></returns>
    public StateID GetStateID(Transition transition)
    {
        if (transition == Transition.NullTransition) return StateID.Null;
        if (!dic.ContainsKey(transition)) return StateID.Null;
        return dic[transition];
    }

    /// <summary>
    /// 进入状态
    /// </summary>
    public virtual void StateEnter() { }
    /// <summary>
    /// 退出状态
    /// </summary>
    public virtual void StateExit() { }

    /// <summary>
    /// 状态持续中,,,
    /// </summary>
    /// <param name="npc"></param>
    public abstract void Act(GameObject npc);
    /// <summary>
    /// 状态退出前,,,
    /// </summary>
    /// <param name="npc"></param>
    publ<strong style="color:transparent">本文来源gaodai#ma#com搞@@代~&码*网/</strong>ic abstract void Reason(GameObject npc);
}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Unity学习之FSM有限状态机
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址