一、状态机的概述
状态机由三部分构成
- 状态:持有条件和状态的映射map。进入状态,持续状态和退出状态的实质方法。
- 条件:持有一个判定判定条件,返回true或者false。
- 机制:持有所有状态的实例,对状态进行执行。
二、示例代码
1、状态
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace net.realmoon
{
public abstract class FSMState
{
public string stateID;
/// <summary>
/// key conditionID
/// value StateID
/// </summary>
public Dictionary<string, string> conditionAndStateMap;
public List<FSMCondition> fsmConditions;
public FSMState()
{
conditionAndStateMap = new Dictionary<string, string>();
fsmConditions = new List<FSMCondition>();
Init();
}
/// <summary>
/// ID赋值
/// </summary>
public abstract void Init();
/// <summary>
/// 增加一个条件状态转换
/// </summary>
/// <param name="conditionID"></param>
/// <param name="stateID"></param>
public void AddConditioAndState(string conditionID, string stateID)
{
conditionAndStateMap.Add(conditionID, stateID);
CreateCondittion(conditionID);
}
/// <summary>
/// 获取条件
/// </summary>
/// <param name="conditionID"></param>
public FSMCondition GetCondition(string conditionID)
{
return fsmConditions.Find((obj) => obj.conditionID == conditionID);
}
/// <summary>
/// 增加一个条件
/// </summary>
/// <param name="conditionID"></param>
public void CreateCondittion(string conditionID)
{
Type conditionType = Type.GetType(conditionID + "Condition");
FSMCondition condition = Activator.CreateInstance(conditionType) as FSMCondition;
fsmConditions.Add(condition);
}
/// <summary>
/// 检查是否条件切换
/// </summary>
/// <param name="fsmBase"></param>
public void Reason(FSMBase fsmBase)
{
for (int i = 0; i < fsmConditions.Count; i++)
{
if (fsmConditions[i].CheckCondition(fsmBase))
{
fsmBase.ChanegActiveState(conditionAndStateMap[fsmConditions[i].conditionID]);
return;
}
}
}
/// <summary>
/// 进入条件
/// </summary>
public virtual void StateEnter(FSMBase fsm) { }
/// <summary>
/// 保持条件
/// </summary>
public virtual void StateStay(FSMBase fsm) { }
/// <summary>
/// 退出条件s
/// </summary>
public virtual void StateExit(FSMBase fsm) { }
}
public class FSMStateID
{
public const string Default = "";
}
}
2、条件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace net.realmoon
{
public abstract class FSMCondition
{
public string conditionID;
public FSMCondition()
{
Init();
}
/// <summary>
/// ID赋值
/// </summary>
public abstract void Init();
/// <summary>
/// 检查条件
/// </summary>
/// <returns></returns>
public abstract bool CheckCondition(FSMBase fsm);
}
public enum FSMConditionID
{
}
}
3、状态机
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace net.realmoon
{
public class FSMBase : MonoBehaviour
{
[HideInInspector]
/// <summary>
/// 默认状态ID
/// </summary>
public string defaultFSMStateID;
public List<FSMState> fsmStates;
[HideInInspector]
public FSMState currentFSMState;
private FSMState defaultFSMState;
public virtual void Start()
{
ConfigFSM();
InitComponent();
InitDefaultState();
}
/// <summary>
/// 初始化状态机
/// </summary>
public virtual void ConfigFSM()
{
fsmStates = new List<FSMState>();
}
/// <summary>
/// 初始化获取组件
/// </summary>
public virtual void InitComponent()
{
}
// Update is called once per frame
public virtual void Update()
{
if (currentFSMState == null)
{
return;
}
currentFSMState.Reason(this);
currentFSMState.StateStay(this);
}
/// <summary>
/// 设置初始状态
/// </summary>
private void InitDefaultState()
{
defaultFSMState = fsmStates.Find((obj) =>
{
return obj.stateID == defaultFSMStateID;
});
currentFSMState = defaultFSMState;
if (currentFSMState == null)
{
return;
}
currentFSMState.StateEnter(this);
}
/// <summary>
/// 切换状态机的状态
/// </summary>
/// <param name="stateID"></param>
public void ChanegActiveState(string stateID)
{
currentFSMState.StateExit(this);
if (stateID == FSMStateID.Default)
{
currentFSMState = defaultFSMState;
}
else
{
currentFSMState = fsmStates.Find((obj) => obj.stateID == stateID);
}
currentFSMState.StateEnter(this);
}
}
}
留言