Unity 有限状态机(Finite State Machine)的理解 与 实现简单的可插拔(Pluggable)AI脚本对象。

3 篇文章 0 订阅
2 篇文章 0 订阅

#Unity 有限状态机(Finite State Machine)的理解 与 实现简单的可插拔AI脚本对象。

参考官方教程:Pluggable AI With Scriptable Objects
Github完整项目:TanksPluggableAI
大神Blog:【游戏设计模式】之三 状态模式、有限状态机 & Unity版本实现

  一般的游戏AI都是使用状态机的设计模式来实现的。发现官方有教程,就跟了一遍,这里就总结一下。
  先简单说一下状态模式。就是根据当前状态和对应条件,选则需要转换的下一个状态。例如本文的例子,坦克默认状态是巡逻(状态),在发现有敌人时(条件),转换成追杀(状态),在敌人逃脱或死掉了之后(条件),又变成巡逻(状态)。

  游戏场景:绿色标签为巡逻点。蓝色标签为玩家出生点。红色为AI出生点。(如图玩家被两个AI追杀。)


AI对象结构

  每个AI对象都有一个状态控制器(StateController)脚本组件,包含一个当前状态(State),且状态包含需要执行动作(Action),还有状态转换的条件(Transition)。

  Unity中文件分类层级如下。其中DefaultEnemyStats是默认AI的一些配置。包括攻击距离,移动速度,旋转速度等等。


State (状态)

using UnityEngine;

[CreateAssetMenu (menuName = "PluggableAI/State")]
public class State : ScriptableObject 
{
    public Action[] actions;                        //动作
    public Transition[] transitions;                //通过决定,选择下一种动作决定
    public Color sceneGizmoColor = Color.gray;      //拿来渲染eyes的Gizmos颜色

    //每一帧更新状态,在StateController的OnUpdate中调用。
    public void UpdateState(StateController controller)
    {
        DoActions(controller);                      //执行动作
        CheckTransition(controller);                //检测转换状态
    }

    //顺序执行动作列表的动作。
    private void DoActions(StateController controller)
    {
        for (int i = 0; i < actions.Length; i++)
            actions[i].Act(controller);
    }

    //检查所有转换状态,并改变状态。
    private void CheckTransition(StateController controller)
    {
        for (int i = 0; i < transitions.Length; i++)
        {
            //这里条件转换只有两个,所以直接用Bool类型来判断。当然也可以有多种条件转换。
            bool decisionSucceeded = transitions[i].decision.Decide(controller);

            if (decisionSucceeded)
                controller.TransitionToState(transitions[i].trueState);
            else
                controller.TransitionToState(transitions[i].falseState);
        }
    }

}
状态名说明配置
Remain State保持原来状态。不包含任何属性。略。
PatrolChaser巡逻者状态。在巡逻点之间巡逻,如果检测到敌人,转为追杀状态。
ChaseChaser追杀者状态。导航到目标一定距离并持续攻击,直到目标死掉,转回巡逻者模式。
PatrolScanner同Patrol Chaser。巡逻到敌人,转为追杀。
ChaseChaser同Chase Chaser 。追杀敌人,但到目标死掉,转换成警觉模式。
AlertScanner警觉模式。其实就是旋转扫描敌人,直到扫描到目标或超过了一定时间。

  通过上表其实可以发现有两个非常相似的动作,只是为了演示Alert Scanner 的。其实是可以优化的,就是修改Transition的结构,不再是只有两种状态选择,而是多种,这样就可以更好的重用状态。


Action(动作)

using UnityEngine;

public abstract class Action : ScriptableObject 
{
    //State直接调用这个方法来执行动作。
    public abstract void Act(StateController controller);
}
动作名说明原理
PatrolAction巡逻动作。从StateController搞来巡逻点列表。在这些巡逻点之间巡逻移动。设置巡逻点为导航目标点,到达后设置下一个巡逻点为导航点。
ChaseAction追随动作。最短距离到达目标。设置目标为导航目标点,导航过去就是了。
AttackAction攻击动作。攻击目标。射出检测射线(红色的),检测到目标就发炮攻击。

Decision(决定)

using UnityEngine;

public abstract class Decision : ScriptableObject 
{
    //通过这个方法的返回值来判断决定的选择。
    public abstract bool Decide(StateController controller);
}
决定名说明原理
LookDecision检测决定。检测到目标就设置为追踪目标,并且返回True。射出检测球体射线(绿色的)来检测。
ActiveStateDecision活动状态决定。就是判断追踪的目标是否active(激活状态)。直接返回追踪目标的active的bool值。
ScanDecision扫描决定。说是扫描其实并没有扫描,只是在转圈而已。一直转到外部条件改变状态,或者超过了扫描限定的时间。停止导航。配合Time.deltaTime旋转自己。返回是否超过扫描限定时间。

Transitions(状态转换)

//状态转换。通过决定的返回值,选则两种状态中其中一个
[System.Serializable]
public class Transition 
{
    public Decision decision;
    public State trueState;
    public State falseState;
}

测试结果


第一种,巡逻->发现目标->追杀->目标死亡->巡逻。(颜色配合下图样例使用。)

这里写图片描述

1. 起始 Patrol Chase 状态,巡逻点之间移动,还没有检测到目标,眼里射出的是清澈的绿色。

2. 发现了目标,转为Chase Chaser 状态,射出了充满愤怒的红色射线,并且一直攻击目标。

3. 当目标化为灰烬,转回 Patrol Chase 状态。


第二种,巡逻->发现目标->追杀->目标死亡->旋转扫描目标->{两种情况:1. 发现目标,回到第二步。2. 超过扫描时间,回到第一步(巡逻)。(颜色配合下图样例使用。)

这里写图片描述

1. 起始 Patrol Scanner 状态,巡逻,眼里射出的是原谅的绿色。

2. 发现刚刚杀了蓝孩子的小红,转为 Chase Scanner 状态,追杀之。

3. 杀掉小红之后,转为 Alert Scanner 状态。旋转扫描周围是否有敌人。

4. 没有扫到,回到 Patrol Scanner 状态。


  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Unity有限状态机(Finite State Machine,FSM)是一种行为控制模式,用于管理游戏对象或系统的不同状态和转换之间的关系。在Unity中,我们可以使用Unity提供的有限状态机类图(StateMachineBehaviour)来实现这个模式。 有限状态机类图是一个基于状态转换的图形表示,其中包含了状态(State)、转换(Transition)和事件(Event)等元素。状态表示游戏对象或系统可能处于的不同状态,转换表示从一个状态到另一个状态的条件,事件表示触发状态转换的事件。 在Unity中,我们可以通过创建一个继承自StateMachineBehaviour的脚本,并将其附加到游戏对象的Animator组件上,来实现有限状态机。在这个脚本中,我们可以定义不同的状态和转换,并实现相应的行为逻辑。 例如,我们可以定义游戏角色的不同状态,如待机状态、行走状态和攻击状态等。我们可以定义转换条件,比如当角色受到攻击时,会从待机状态转换到攻击状态。然后,我们可以实现相应的行为逻辑,比如在攻击状态下执行攻击动作。 使用有限状态机类图可以帮助我们更好地管理复杂的游戏逻辑和行为,并使代码更加清晰和可维护。它允许我们根据不同的状态和条件来组织和执行行为,从而实现更灵活和可扩展的游戏逻辑。 ### 回答2: Unity有限状态机(Finite State Machine,简称FSM)类图是描述Unity游戏中的状态机行为的图示。有限状态机是一种用来描述对象或者系统状态转换的模型。 在Unity中,有限状态机常常用于控制游戏中的角色行为、敌人AI、游戏流程等。FSM类图主要包括状态(State)、转换(Transition)和行为(Action)三个主要元素。 状态(State)表示对象或系统可能处于的一种情况,比如游戏中的"待机"、"移动"、"攻击"等状态。每个状态都有对应的行为和相应的转换条件。 转换(Transition)表示状态之间的切换条件,它决定了对象或系统从一个状态切换到另一个状态的时机。转换通常基于一些触发条件,比如玩家的输入、特定事件的发生等。 行为(Action)表示在每个状态下对象或者系统执行的具体操作。行为可以是移动、攻击、播放动画等。每个状态都有对应的行为,这些行为会随着状态的切换而改变。 FSM类图中可以看到每个状态(State)被表示为一个矩形框,框内包含了状态名称和该状态下的行为(Action)。不同状态之间的转换(Transition)用箭头表示,箭头上标注着触发条件。 通过使用FSM类图,开发人员可以更清晰地描述游戏中的状态转换逻辑,方便编写对应的代码实现。同时,FSM类图也可以作为开发文档的一部分,方便团队成员之间的沟通和理解。 总之,Unity有限状态机类图是一种用来描述游戏对象或系统状态转换逻辑的图示,通过状态、转换和行为的关系,可以清晰地表示游戏中的角色行为、敌人AI等复杂逻辑。 ### 回答3: Unity有限状态机(Finite State Machine)是Unity游戏引擎中的一种常用设计模式,用于管理游戏对象的各种状态和状态转换。下面是一个示例的Unity有限状态机类图。 在该类图中,有三个主要的类:状态机(StateMachine)、状态(State)和转换(Transition)。状态机是有限状态机的核心,它包含了状态的集合和状态之间的转换关系。 状态是实际执行的动作,例如待机、行走、攻击等。每个状态都继承自状态基类,并实现了状态所需的行为。在状态机中,每个状态都有一个唯一的标识符。 转换是状态之间的切换条件。例如,当玩家按下某个按钮时,从待机状态切换到行走状态。转换条件是由转换类实现的,每个转换类都包含了触发转换的条件和转换的目标状态。 状态机中的状态和转换通过字典保存,并通过标识符进行访问和切换。状态机还有一个当前状态变量,用于表示当前游戏对象的当前状态。 实际使用时,可以根据具体游戏的需求,扩展状态机和状态。例如,可以添加更多的状态和转换,并在状态之间设置复杂的转换条件和逻辑。通过有限状态机的设计,可以使游戏对象的状态切换更加清晰、灵活和简单。 总之,Unity有限状态机类图展示了状态机、状态和转换之间的关系和组织方式,通过使用该类图,可以更好地管理游戏对象的各种状态和状态之间的转换。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值