FSM有限状态机

本文介绍了使用C#在Unity中实现的一个状态机系统,包括状态的管理(添加、删除和执行转换)、状态类的抽象定义,以及NPC的行为和触发因素处理。
摘要由CSDN通过智能技术生成

系统类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 状态机系统
/// </summary>
public class FSMSystem  {
	private Dictionary<StateID, FSMState> states = new Dictionary<StateID, FSMState>();//Key:状态  Value:状态的具体类  管理所有状态

    private StateID currentStateID;//当前状态
	private FSMState currentState;//当前状态的具体类

	/// <summary>
	/// 某个实体的执行行为和触发因素
	/// </summary>
	/// <param name="npc"></param>
	public void Update(GameObject npc)
	{
		currentState.Act(npc);
		currentState.Reason(npc);
	}
	/// <summary>
	/// 添加状态
	/// </summary>
	/// <param name="s"></param>
	public void AddState(FSMState s)
	{
		if (s == null)//空不能添加
		{
			Debug.LogError("FSMState不能为空");return;
		}
		if (currentState == null)//如果当前状态ID和状态为空 给他们赋值
		{
			currentState = s;
			currentStateID = s.ID;
		}
		if (states.ContainsKey(s.ID))//存在无法添加
		{
			Debug.LogError("状态" + s.ID + "已经存在,无法重复添加");return;
		}
		states.Add(s.ID, s);//合格添加
	}
	/// <summary>
	/// 移除状态
	/// </summary>
	/// <param name="id"></param>
	public void DeleteState(StateID id)
	{
		if (id == StateID.NullStateID)//无法删除空状态
        {
			Debug.LogError("无法删除空状态");return;
		}
		if (states.ContainsKey(id) == false)//字典不存在移除不了
		{
			Debug.LogError("无法删除不存在的状态:" + id);return;
		}
		states.Remove(id);//合格移除
	}
	/// <summary>
	/// 执行状态
	/// </summary>
	/// <param name="trans"></param>
	public void PerformTransition(Transition trans)
	{
		if (trans == Transition.NullTransition)//无法执行空的转换条件
        {
			Debug.LogError("无法执行空的转换条件");return;
		}
		StateID id= currentState.GetOutputState(trans);//拿当前状态获取状态的ID  传参位转换条件
		if (id == StateID.NullStateID)//状态ID等于NullStateID的话,就无法通过转换条件转换状态
        {
			Debug.LogWarning("当前状态" + currentStateID + "无法根据转换条件" + trans + "发生转换");return;
		}
		if (states.ContainsKey(id) == false)//在状态机里面不存在状态
        {
			Debug.LogError("在状态机里面不存在状态" + id + ",无法进行状态转换!");return;
		}
		//达成转换条件
		FSMState state = states[id];//根据ID拿出这个状态
		currentState.DoAfterLeaving();
		currentState = state;//当前状态发生变化
		currentStateID = id;//当前状态ID发生变化
        currentState.DoBeforeEntering();
	}
} 

基类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 过渡(转换条件)
/// </summary>
public enum Transition
{
    NullTransition = 0,
    SeePlayer,//看到角色
    LostPlayer//没看到角色
}
/// <summary>
/// 状态ID
/// </summary>
public enum StateID
{
    NullStateID = 0,
    Patrol,//巡逻
    Chase//追逐
}

/// <summary>
/// 添加状态和移除状态和获取状态的抽象类
/// </summary>
public abstract class FSMState
{

    protected StateID stateID;//类的状态ID
    public StateID ID { get { return stateID; } }//可以被获取
    protected Dictionary<Transition, StateID> map = new Dictionary<Transition, StateID>();//Key:转换条件 Value:状态ID
    protected FSMSystem fsm;//持有状态机系统 可以根据实现的子类调用状态机系统的方法(添加、移除、执行)

    public FSMState(FSMSystem fsm)//构造传状态机系统
    {
        this.fsm = fsm;
    }

    /// <summary>
    /// 添加装换条件和状态ID
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="id"></param>
    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("添加转换条件的时候," + trans + "已经存在于map中"); return;
        }
        map.Add(trans, id);
    }
    /// <summary>
    /// 删除装换条件和状态ID
    /// </summary>
    /// <param name="trans"></param>
    public void DeleteTransition(Transition trans)
    {
        if (trans == Transition.NullTransition)
        {
            Debug.LogError("不允许NullTransition"); return;
        }
        if (map.ContainsKey(trans) == false)
        {
            Debug.LogError("删除转换条件的时候," + trans + "不存在于map中"); return;
        }
        map.Remove(trans);
    }
    /// <summary>
    /// 根据转换条件获取状态ID的方法(返回状态ID)
    /// </summary>
    /// <param name="trans"></param>
    /// <returns></returns>
    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);//触发因素
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值