简单的状态机

简单的状态机

提示:本篇写的是基于对有限状态机的理解自己写的一个简单的状态机,简单清晰明了
FSMSystem脚本 状态

using System.Collections.Generic;
using UnityEngine;

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

    private StateID CurrentID;

    private FSMState CurrentState;

    public void Update(GameObject npc)
    {
        CurrentState.Act(npc);
        CurrentState.Reason(npc);
    }
    //添加状态
    public void AddState(FSMState state)
    {
        if (state == null)
        {
            Debug.LogError("当前状态为空");
            return;
        }
        if (CurrentState == null)
        {
            CurrentState = state;
            CurrentID = state.ID;
        }
        if (states.ContainsKey(state.ID))
        {
            Debug.LogError("不能重复添加状态" + state);
            return;
        }
        states.Add(state.ID,state);
        Debug.Log(state.ID);
    }
    //删除状态
    public void DeleteState(StateID id)
    {
        if (id == StateID.NullStateID)
        {
            Debug.LogError("ID为空");
            return;
        }
        if (!states.ContainsKey(id))
        {
            Debug.LogError("id不存在");
            return;
        }
        states.Remove(id);
    }
    //通过条件,跳转状态
    public void PerformTransition(Transition trans)
    {
        if(trans==Transition.NullTransition)
        {
            Debug.LogError("条件为空");
            return;
        }
        StateID id = CurrentState.GetOutputState(trans);
        if (id == StateID.NullStateID)
        {
            Debug.LogWarning("ID为空,无法转换");
            return;
        }
        if (!states.ContainsKey(id))
        {
            Debug.LogError("状态机不包含当前状态");
            return;
        }
        FSMState state = states[id];
        Debug.Log("state" + states[id]);
        CurrentState.DoAfterLeaving();
        CurrentState = state;
        CurrentID = id;
        CurrentState.DoBeforeEntering();
    }
}

FSMState 状态机脚本

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

public enum Transition//状态条件
{
    NullTransition=0,
    Work,//工作条件
    Free,//空闲条件
}
public enum StateID//状态ID
{
    NullStateID = 0,
    Free,//空闲
    Working,//工作状态
}
public abstract class FSMState 
{
    protected StateID stateID;

    public StateID ID
    {
        get { return stateID; }
    }
    protected FSMSystem fsm;
    public FSMState( FSMSystem fsm)
    {
        this.fsm = fsm;
    }
    存放当前转换条件 与ID
    protected static Dictionary<Transition, StateID> map = new Dictionary<Transition, StateID>();

    //添加状态字典内容
    public void AddTransition(Transition trans,StateID id)
    {
        if (trans == Transition.NullTransition)
        {
            Debug.LogError("不允许添加NullTransition");
            return;
        }
        if (id == StateID.NullStateID)
        {
            Debug.LogError("不允许添加NullStateID");
            return;
        }
        if (map.ContainsKey(trans))
        {
            Debug.LogError("添加的条件已经存在");
            return;
        }
        map.Add(trans, id);

        foreach (Transition t in map.Keys)
        {
            Debug.Log("map" + t);
        }
    }
    //删除状态字典内容
    public void DeleteTransition(Transition trans)
    {
        if (trans == Transition.NullTransition)
        {
            Debug.LogError("不能删除状态NullTransition");
            return;
        }
        if (!map.ContainsKey(trans))
        {
            Debug.LogError("删除状态不存在");
            return;
        }
        map.Remove(trans);
    }
    //根据输入条件返回要跳转的状态
    public StateID GetOutputState(Transition trans)
    {
        
        if (map.ContainsKey(trans))
        {
            return map[trans];
        }
        return StateID.NullStateID;
    }
    //进入当前状态前执行函数
    public virtual void DoBeforeEntering()
    {

    }
    //离开当前状态前执行函数
    public virtual void DoAfterLeaving()
    {

    }
    //在这个状态的时候要做什么事情 一直执行
    public abstract void Act(GameObject npc);
    //达到某种条件 判断当前状态的离开条件 一直执行
    public abstract void Reason(GameObject npc);
}

每一种状态都需要继承FSMState类,并在调用脚本添加更新自己的update,添加自己的生命周期
添加自己的生命周期
初始化自己的所有状态,并添加到自己存储状态的字典之中
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值