1. 概述
在游戏中存在各种的“状态”,不仅是角色的行为状态,还有例如场景的开始、加载、游戏中等状态,此次采用一个小案例实现有限状态机——一个NPC一个角色player,当角色player不在NPC视野内时NPC在固定的四个点之间巡逻,当player在NPC视野内时,NPC会追逐player,丢失跟踪后继续巡逻,player的移动采用在scene中手动移动。
2. FSMState.cs
FSMState为定义状态的基类,但也将状态转换条件和状态ID枚举定义放在了此类中,Transition中存了所有的状态转换条件,StateID中定义了所有的状态。状态定了一些状态的基本信息,有状态ID以及储存转换条件和状态ID的字典,持有一个状态管理的对象..........
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 状态转换的条件
/// </summary>
public enum Transition
{
NullTransition=0,
SawPlayer,//看到主角
LostPlayer//看不到主角
}
/// <summary>
/// 状态ID,每个状态唯一表示,不重复,用于区分不同状态
/// </summary>
public enum StateID
{
NullStateID=0,
Patrol,//巡逻
Chase//追逐主角
}
public abstract class FSMState{
protected StateID stateID;
public StateID ID
{
get { return stateID; }
}
protected Dictionary<Transition, StateID> map = new Dictionary<Transition, StateID>();
public FSMSystem fsm;
public void AddTransition(Transition tran,StateID id)
{
if(tran==Transition.NullTransition||id==StateID.NullStateID)
{
Debug.LogError("添加的状态转换条件或状态Id不能为空!");
return;
}
if(map.ContainsKey(tran))
{
Debug.LogError("状态转换条件 " + id + " 已经存在" + tran);
return;
}
map.Add(tran, id);
}
public void DeleteTransition(Transition tran)
{
if(map.ContainsKey(tran)==false)
{
Debug.LogWarning("想要删除的状态转换条件 " + tran + " 不存在!");
return;
}
map.Remove(tran);