Unity Game FrameWork—模块使用—有限状态机

官方说明: 提供创建、使用和销毁有限状态机的功能,一些适用于有限状态机机制的游戏逻辑,使用此模块将是一个不错的选择。
有限状态机并不是游戏中独有的,我们看一下其他的介绍:
有限状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。在计算机科学中,有限状态机被广泛用于建模应用行为、硬件电路系统设计、软件工程,编译器、网络协议、和计算与语言的研究。
[图片]
[图片]
图片来源:https://blog.csdn.net/DataAlchemist/article/details/98450010
参考上面两幅图,当玩家处于当前状态时,玩家会执行某些操作,当这些操作触发切换状态的条件时,则切换状态。如果用if else来判断则太过复杂不便于梳理流程,以及一堆条件变量控制,当状态改变或触发条件改变,整个流程的维护是很复杂的,我们不能专注当前状态要做的事,需要去看前后关联的触发条件是否会有问题,这些条件变量在其他状态是怎样的,会不会由于条件变量的改变导致其它问题,因此诞生了状态机。我们只需关注当前状态要干什么,干完你之后什么条件下会触发下一个状态。
前面有写过,流程是对状态机的封装,我们来理解一下流程的思路,首先进入游戏的初始状态完成版本构建、语言配置等工作即可触发Splash 动画流程展示,ProcedureSplash流程中选择资源加载模式,例如选择编辑器模式,则进入ProcedurePreload资源预加载流程。相关游戏资源加载完成后,则进入切换场景的流程ProcedureChangeScene。状态机所解决的问题与流程需要完成的事情是完全吻合的。
流程是对状态机做了一层封装,抽丝剥茧理解起来相对复杂,抓不住问题的本质,这里我们做一个简单地Demo来完成状态机学习。借用一下浅墨大哥写的设计模式和案例:(缅怀,人走了,知乎博客还在影响着我们)
【游戏设计模式】之三 状态模式、有限状态机 & Unity版本实现
状态机Demo:Behavioral Patterns-State Pattern-Exmaple4
接下来会参考这个案例用框架完成这个Demo的功能,Demo的流程图如下
[图片]
工作流:
ProcedureFSM:流程类
FSM_Hero:英雄逻辑类
State:FsmState<FSM_Hero>状态类
创建ProcedureFSM流程类,在流程类中创建英雄实体并添加逻辑类FSM_Hero,英雄逻辑类中创建四种状态类,随后在四个状态类中完成触发及状态切换等工作。(流程启动,实体创建及数据表配置请参考本专栏之前的内容)
下面贴上代码:
下蹲状态:

public class DuckingState : FsmState<FSM_Hero>
{
    
    
    public override void OnEnter(IFsm<FSM_Hero> fsm)
    {
    
    
        Debug.Log("------------------------Heroine in DuckingState~!(进入下蹲躲避状态!)");
    }
    public override void OnUpdate(IFsm<FSM_Hero> fsm, float elapseSeconds, float realElapseSeconds)
    {
    
    
        HandleInput(fsm);
    }

    public void HandleInput(IFsm<FSM_Hero> fsm)
    {
    
    
        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
    
    
            Debug.Log("已经在下蹲躲避状态中!");
            return;
        }
        if (Input.GetKeyUp(KeyCode.UpArrow))
        {
    
    
            Debug.Log("get GetKeyUp.UpArrow!");
            ChangeState<StandingState>(fsm);
        }
    }
}

站立状态:

public class StandingState : FsmState<FSM_Hero>
{
    
    
    public override void OnEnter(IFsm<FSM_Hero> fsm)
    {
    
    
        Debug.Log("------------------------Heroine in StandingState~!(进入站立状态!)");
    }
    public override void OnUpdate(IFsm<FSM_Hero> fsm, float elapseSeconds, float realElapseSeconds)
    {
    
    
        HandleInput(fsm);
    }

    public void HandleInput(IFsm<FSM_Hero> fsm)
    {
    
    
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
    
    
            Debug.Log("get KeyCode.UpArrow!");
            ChangeState<JumpingState>(fsm);
        }
        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
    
    
            Debug.Log("get KeyCode.DownArrow!");
            ChangeState<DuckingState>(fsm);
        }
    }
}

下斩状态:

public class DrivingState : FsmState<FSM_Hero>
{
    
    
    public override void OnEnter(IFsm<FSM_Hero> fsm)
    {
    
    
        Debug.Log("------------------------Heroine in DrivingState~!(进入下斩状态!)");
    }
    public override void OnUpdate(IFsm<FSM_Hero> fsm, float elapseSeconds, float realElapseSeconds)
    {
    
    
        HandleInput(fsm);
    }

    public void HandleInput(IFsm<FSM_Hero> fsm)
    {
    
    
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
    
    
            Debug.Log("get KeyCode.UpArrow!");
            ChangeState<StandingState>(fsm);
        }
    }
}

跳跃状态:

public class JumpingState : FsmState<FSM_Hero>
{
    
    
    public override void OnEnter(IFsm<FSM_Hero> fsm)
    {
    
    
        Debug.Log("------------------------Heroine in JumpingState~!(进入跳跃状态!)");
    }
    public override void OnUpdate(IFsm<FSM_Hero> fsm, float elapseSeconds, float realElapseSeconds)
    {
    
    
        HandleInput(fsm);
    }

    public void HandleInput(IFsm<FSM_Hero> fsm)
    {
    
    
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
    
    
            Debug.Log("get GetKeyDown.UpArrow! but already in Jumping! return!(已经在跳跃状态中!)");
            return;
        }
        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
    
    
            Debug.Log("get KeyCode.DownArrow!");
            ChangeState<DrivingState>(fsm);
        }
    }
}

英雄逻辑类

public class FSM_Hero : EntityLogic
{
    
    
    public override void OnInit(object userData)
    {
    
    
        base.OnInit(userData);

        FsmState<FSM_Hero>[] heroState =
        {
    
    
            new StandingState(),
            new DuckingState(),
            new JumpingState(),
            new DrivingState(),
        };
        var heroFsm = StarForce.GameEntry.Fsm.CreateFsm(this, heroState);
        heroFsm.Start<StandingState>();
    }

    public override void OnShow(object userData)
    {
    
    
        base.OnShow(userData);
    }

    public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
    {
    
    
        base.OnUpdate(elapseSeconds, realElapseSeconds);
    }
}

Demo流程启动:

public class ProcedureFSM : ProcedureBase
{
    
    
    public override bool UseNativeDialog
    {
    
    
        get
        {
    
    
            return true;
        }
    }
    public override void OnEnter(ProcedureOwner procedureOwner)
    {
    
    
        base.OnEnter(procedureOwner);
        GameEntry.Entity.ShowEntity<FSM_Hero>(99999, "Assets/GameMain/Entities/Hero.prefab", "Aircraft");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37619255/article/details/129958201
今日推荐