我们一般游戏中都是这样使用状态机的
enum State_Type
{
GameMenu,
GameLoading,
GameLogic,
GameOver,
}
void Update()
{
switch(currentstate)
{
case State_Type. GameMenu:
if( 按了开始按钮 )
{
currentstate=State_Type. GameLoading;
}
if( 按了成就 )
{
currentstate=State_Type……..;
}
if(按了高分榜)
{
currentstate=State_Type……..;
}
break;
case State_Type. GameLoading:
if( 加载游戏完成 )
{
currentstate=State_Type. GameLogic;
}
break;
case State_Type. GameLogic:
if( 死了 )
{
currentstate=State_Type. GameOver;
}
break;
case State_Type. GameOver:
currentstate=State_Type. GameMenu;
break;
}
}
这样写没有什么问题。不过当状态多的时候确实很头疼。
有一种方法可以解决这样的问题(有限状态机FSM)
下面是一个例子
两个实体
ActorOne
ActorTwo
第一个实体ActorOne
using UnityEngine;
using System.Collections;
public class ActorOne : BaseGameEntity {
//有限状态机
StateMachine m_pStateMachine;
void Start () {
//设置实体的id必须唯一
SetID((int)EntityID.m_ActorOne);
//注册
m_pStateMachine = new StateMachine(this);
/*
一个状态分为三个阶段
Enter() //进入
Execute() //执行
Exit() //离开
当m_pStateMachine.SetCurrentState(ActorOne_StateOne .Instance());
会先执行ActorOne_StateOne 的Enter()方法,
然后执行ActorOne_StateOne 的Execute()方法, Execute方法会一直执行直到切换状态
当在ActorOne_StateOne(Enter(), Execute())中调用Entity.GetFSM().ChangeState(ActorOne_StateTwo.Instance());
会先执行ActorOne_StateOne 的Exit();
然后执行ActorOne_StateTwo的Enter()方法,
然后执行ActorOne_StateTwo的Execute()方法,
*/
//设置当前的状态为ActorOne_StateOne
m_pStateMachine.SetCurrentState(ActorOne_StateOne .Instance());
//设置全局的状态
m_pStateMachine.SetGlobalStateState(ActorOne_GloballState .Instance());
//实体注册到实体管理器中
EntityManager.Instance().RegisterEntity(this);
}
void Update ()
{
//状态机update
m_pStateMachine.SMUpdate();
}
public StateMachine GetFSM ()
{
//获得状态机
return m_pStateMachine;
}
public override bool HandleMessage (Telegram telegram)
{
//解析消息
return m_pStateMachine.HandleMessage(telegram);
}
}
using UnityEngine;
using System.Collections;
public class ActorTwo : BaseGameEntity {
StateMachine m_pStateMachine;
public Transform TwoTransform;
// Use this for initialization
void Start () {
// set id
SetID((int)EntityID.m_ActorTwo);
m_pStateMachine = new StateMachine(this);
m_pStateMachine.SetCurrentState(ActorTwo_StateOne.Instance());
m_pStateMachine.SetGlobalStateState(ActorTwo_GloballState.Instance());
EntityManager.Instance().RegisterEntity(this);
}
void Update ()
{
m_pStateMachine.SMUpdate();
}
public StateMachine GetFSM ()
{
return m_pStateMachine;
}
public override bool HandleMessage (Telegram telegram)
{
return m_pStateMachine.HandleMessage(telegram);
}
}
using UnityEngine;
using System.Collections;
/*
状态分为两种
1全局状态 一般情况下会一直执行 可以负责调度
2普通状态 也就是上面的GameMenu,GameLoading,GameLogic,GameOver,
*/
//全局状态
public class ActorOne_GloballState :State
{
private static ActorOne_GloballState instance;
public static ActorOne_GloballState Instance ()
{
if (instance == null)
instance = new ActorOne_GloballState ();
return instance;
}
//当状态被调用是执行一次
public override void Enter (ActorOne Entity)
{
//base.Enter (Entity);
}
//相当于update方法
public override void Execute (ActorOne Entity)
{
//base.Execute (Entity);
}
//状态退出是被调用
public override void Exit (ActorOne Entity)
{
//base.Exit (Entity);
}
//接收消息
public override bool OnMessage (ActorOne Entity, Telegram telegram)
{
return false;
}
}
public class ActorOne_StateOne : State
{
private static ActorOne_StateOne instance;
public static ActorOne_StateOne Instance ()
{
if (instance == null)
instance = new ActorOne_StateOne ();
return instance;
}
public override void Enter (ActorOne Entity)
{
//base.Enter (Entity);
}
public override void Execute (ActorOne Entity)
{
/*
调用实体的GetFSM()获得状态机器
在调用状态机的ChangeState(ActorOne_StateTwo.Instance())
改变状态
这里是从当前状态ActorOne_StateOne切换到ActorOne_StateTwo状态;
*/
Entity.GetFSM().ChangeState(ActorOne_StateTwo.Instance());
//base.Execute (Entity);
}
public override void Exit (ActorOne Entity)
{
//base.Exit (Entity);
}
public override bool OnMessage (ActorOne Entity, Telegram telegram)
{
return false;
}
}
public class ActorOne_StateTwo : State
{
private static ActorOne_StateTwo instance;
public static ActorOne_StateTwo Instance ()
{
if (instance == null)
instance = new ActorOne_StateTwo ();
return instance;
}
public override void Enter (ActorOne Entity)
{
/*
MessageDispatcher.Instance().DispatchMessage();用于在实体间传送消息
下面代码的意思就是
发送消息给ActorTwo,延迟5秒发送,消息的类型msg_oneMessage
*/
MessageDispatcher.Instance().DispatchMessage(
5f, // delay 消息的延迟时间
Entity.ID(), // sender 发送者
(int)EntityID.m_ActorTwo, // receiver 接收者
(int)message_type.msg_oneMessage, //message
Entity); //附加信息
//base.Enter (Entity);
}
public override void Execute (ActorOne Entity)
{
//base.Execute (Entity);
}
public override void Exit (ActorOne Entity)
{
//base.Exit (Entity);
}
public override bool OnMessage (ActorOne Entity, Telegram telegram)
{
/*
接收ActorTwo发送过来的消息(message_type.msg_twoMessage)
*/
if(telegram.Msg == (int)message_type.msg_twoMessage)
{
/*
接收成功
*/
return true;
}
return false;
}
}
using UnityEngine;
using System.Collections;
public class ActorTwo_GloballState : State
{
private static ActorTwo_GloballState instance;
public static ActorTwo_GloballState Instance ()
{
if (instance == null)
instance = new ActorTwo_GloballState ();
return instance;
}
public override void Enter (ActorTwo Entity)
{
//base.Enter (Entity);
}
public override void Execute (ActorTwo Entity)
{
//base.Execute (Entity);
}
public override void Exit (ActorTwo Entity)
{
//base.Exit (Entity);
}
//消息处理
public override bool OnMessage (ActorTwo Entity, Telegram telegram)
{
/*
接收ActorOne发送来的消息(message_type.msg_oneMessage)
*/
if (telegram.Msg == (int)message_type.msg_oneMessage) {
/*
接收成功处理消息从当前状态切换到ActorTwo_StateTwo状态;
*/
Entity.GetFSM ().ChangeState (ActorTwo_StateTwo.Instance ());
return true;
}
return false;
}
}
public class ActorTwo_StateOne : State
{
private static ActorTwo_StateOne instance;
public static ActorTwo_StateOne Instance ()
{
if (instance == null)
instance = new ActorTwo_StateOne ();
return instance;
}
public override void Enter (ActorTwo Entity)
{
//base.Enter (Entity);
}
public override void Execute (ActorTwo Entity)
{
//base.Execute (Entity);
}
public override void Exit (ActorTwo Entity)
{
//base.Exit (Entity);
}
public override bool OnMessage (ActorTwo Entity, Telegram telegram)
{
return false;
}
}
public class ActorTwo_StateTwo : State
{
private static ActorTwo_StateTwo instance;
public static ActorTwo_StateTwo Instance ()
{
if (instance == null)
instance = new ActorTwo_StateTwo ();
return instance;
}
public override void Enter (ActorTwo Entity)
{
/*
发送消息给ActorOne,延迟1秒,消息类型msg_twoMessage
*/
MessageDispatcher.Instance ().DispatchMessage(
1f,
Entity.ID (),
(int)EntityID.m_ActorOne,
(int)message_type.msg_twoMessage,
Entity);
//base.Enter (Entity);
}
public override void Execute (ActorTwo pMiner)
{
//base.Execute (Entity);
}
public override void Exit (ActorTwo Entity)
{
//base.Exit (Entity);
}
public override bool OnMessage (ActorTwo Entity, Telegram telegram)
{
return false;
}
}
在使用的时候最好写一个状态表
实体一 当前状态 条件 目标状态/实体 睡觉 被打醒了 狂暴 狂暴 无条件 投降 推荐一本书 游戏人工智能编程案例精粹 代码还有例子包里有 |
描述:有限状态机
附件: FSM.unitypackage (26 K) 下载次数:243 |