LimboAI 文档
LimboAI 是一个面向 Godot Engine 4 的开源 C++ 模块,将行为树与状态机结合在一起,用于打造你游戏的 AI。它自带行为树编辑器、内置文档、可视化调试器等!虽然它是用 C++ 实现的,但完全支持用 GDScript 来创建你自己的任务和状态。完整功能列表见 LimboAI GitHub 页面。
行为树是一种强大的层次结构,用于建模和控制游戏中智能体(例如角色、敌人、实体)的行为。它旨在让你更轻松地为游戏创建复杂且高度模块化的行为。想进一步了解行为树,请参阅行为树简介。
分层状态机是一种有限状态机,允许任意状态拥有自己的子状态机。这样你就可以把一个庞大的状态机拆解为多个较小的状态机,从而应对 AI 在状态与状态转换上的复杂度。
获取 LimboAI
LimboAI 既可以作为 C++ 模块使用,也可以作为 GDExtension 共享库使用。两者之间存在一些差异。简而言之,GDExtension 版本使用起来更方便,但功能上略有受限。模块版本提供更好的编辑器体验,性能也稍好一些,但需要使用包含导出模板的自定义引擎构建。无论你选择哪种方式,你的项目都能同时兼容两者,随时可以互相切换。
选择你想使用的版本。如果拿不定主意,就从 GDExtension 版本开始。你随时可以改变决定 —— 两个版本完全兼容。
获取 GDExtension 版本
官方 LimboAI GitHub 页面以及资源库(Asset Library)中都提供了预编译版本。
GDExtension 是使用 LimboAI 插件最便捷的方式,但它有一些限制:
不提供文档提示(tooltip)。
由于依赖 Godot API 中不存在的引擎类,扩展版本中无法使用便捷的 BBParam 属性编辑器。
🛈 另见:什么是 GDExtension?
安装步骤:
确认你正在使用最新稳定版的 Godot 编辑器。
为你的 LimboAI 实验创建一个新项目。
在 Godot 中点击屏幕顶部的 AssetLib 标签,搜索 LimboAI 并下载。LimboAI 插件会连同示例项目文件一起下载。此时打印出的错误可以忽略,那是因为扩展库尚未加载。
用 Project -> Reload project 重新加载项目。现在应该不会再打印任何错误了。
在项目文件中找到名为 showcase.tscn 的场景文件并运行它。它是示例的入口点。
获取模块版本
官方 LimboAI GitHub 页面提供预编译版本。
安装步骤:
在 GitHub releases 中,下载适用于你平台的最新预编译发行版。
从同一个发行版中下载示例项目压缩包。
解压预编译编辑器与示例项目文件。
启动预编译的编辑器可执行文件,导入并打开示例项目。
运行项目。
重要:使用模块版 LimboAI 导出游戏时,请务必使用同一个 GitHub 发行版构建中附带的预编译导出模板。
在 C# 中使用 LimboAI
下面介绍如何使用模块版本配合 C# 编写你的任务和状态。
找到 LimboAI 的 NuGet 包文件。
每个提供的构建都带有 GodotSharp 文件夹,其中的包位于 “GodotSharp/Tools/nupkgs/” 下。记下该目录路径,下一步会用到。
使用以下命令添加一个本地 NuGet 包源:
dotnet nuget add source path/to/limboai/nupkgs --name LimboNugetSource
你的 C# 项目应该就能看到 LimboAI 的类并成功编译。
关于 GDExtension,目前我只能确认模块版本与 C# 可以正常工作。遗憾的是,我在 GDExtension 版本上还没有成功过。如果你用 GDExtension 成功了,请通过 Discord 或邮件告诉我。
参与贡献
在 Godot 发布第三个 beta 或候选版本之前,我们以 Godot 引擎的最新稳定版作为开发目标。如果你想为本项目做贡献,请确保使用对应的 Godot 版本。
我们遵循 Godot 代码风格指南。请使用 clang-format 来保持风格一致。你可以用 pre-commit install 为 Git 安装 pre-commit 钩子,把这一过程自动化。
提交拉取请求(Pull Request)时,请保持次版本向后兼容。
我们支持把 LimboAI 构建为 Godot 引擎的模块,也支持构建为 GDExtension 库。请确保你的贡献在两种方式下都兼容。我们的 CI 工作流会验证你的改动能否在两种配置下都编译通过。
作为 Godot 引擎模块编译
克隆 Godot 引擎仓库。
切换到最新的稳定版 tag。
把 LimboAI 仓库克隆到
modules/limboai目录中。
git clone https://github.com/godotengine/godot.git
git checkout 4.3-stable # Replace "4.3-stable" with the latest stable tag
git clone https://github.com/limbonaut/limboai modules/limboai
详细的引擎构建说明请参考 Godot 引擎文档。
使用 tests=yes 构建选项可以编译单元测试。要运行它们,请带上 --test --tc="*[LimboAI]*" 命令行选项运行编译好的 Godot 可执行文件。
构建 C# 包
如果你希望从源码构建时启用 LimboAI 的 C# 支持,请按照 Godot 关于带 C# 支持从源码构建的说明操作:使用 .NET 编译。LimboAI 的类会包含在该构建流程的输出中。
作为 GDExtension 库编译
你需要 SCons 构建工具和一个 C++ 编译器。另见编译。运行 scons target=editor 即可为你当前的平台构建插件库。
如果
limboai/godot-cpp目录中还没有godot-cpp仓库,SCons 会自动克隆它。默认情况下,构建产物会被放到示例项目中:
demo/addons/limboai/bin/。
其他选项与目标请查看 scons -h。
为文档做贡献
在线文档使用 Sphinx 生成。源文件以 RST 格式放在 doc/source 目录中,可以在本地用 sphinx-build 构建。更多细节请参阅 Sphinx 文档。
类文档存放在 doc_classes/ 目录下的 XML 文件中。如果你新建了类或修改了已有类,可以在 Godot 源码根目录下用 --doctool 选项运行编译好的 Godot 可执行文件,用来生成缺失的 XML 文件或类文档中对应文件的缺失片段。编辑完 XML 文件后,请再次用 --doctool 选项运行编译好的编辑器可执行文件,以更新并整理这些 XML 文件。
类文档的 Sphinx RST 文件由 XML 文件经 Godot 脚本 make_rst.py 生成,并保存在 doc/source/classes 目录中。该过程由我们自己的脚本 scripts/update_rst.sh 完成。doc/source/classes 中的 RST 文件不应手动编辑。
行为树简介
🛈 注意:示例项目中包含一个教程,通过直观的示例带你入门行为树。
行为树(BT)是一种层次结构,用于建模和控制游戏中智能体(例如角色、敌人、实体)的行为。它旨在让你更轻松地为游戏创建复杂且高度模块化的行为。
行为树由若干任务组成,这些任务代表具体的动作或决策规则。任务大致可分为两大类:控制任务和叶任务。控制任务决定树内的执行流程,包括 Sequence、Selector 和 Invert。叶任务代表要执行的具体动作(例如移动或攻击),或是需要检查的条件。BTTask 类为行为树的各种积木块提供了基础。这类任务可以通过 Blackboard 共享数据。
行为树通常每一帧都会处理一次。它自上而下遍历,由控制任务决定控制流。每个任务都有一个 _tick 方法,负责执行任务的工作并返回表示进度的状态:SUCCESS、FAILURE 或 RUNNING。SUCCESS 和 FAILURE 表示已完成工作的结果,而当一个任务需要不止一个 tick 才能完成时,就会返回 RUNNING 状态。这些状态决定树的推进方式,其中 RUNNING 状态通常意味着树会在下一帧继续执行。
任务共有四种类型:
动作(Actions)是执行实际工作的叶任务。
例如:PlayAnimation、Wait。
条件(Conditions)是执行各种检查的叶任务。
组合任务(Composites)可以拥有一个或多个子任务,并决定子任务的执行流程。
装饰器(Decorators)只能拥有一个子任务,用于改变其子任务的运行方式。
Sequence 是核心组合任务之一。它按顺序从第一个到最后一个执行子任务,直到其中一个返回 FAILURE,或者全部返回 SUCCESS。换句话说,只要有任一子任务返回 FAILURE,Sequence 的执行就会被中止,并且 Sequence 自身会返回 FAILURE。
Selector 是另一个必不可少的组合任务。它按顺序从第一个到最后一个执行子任务,直到其中一个返回 SUCCESS 或全部返回 FAILURE。换句话说,当某个子任务返回 FAILURE 时,它就继续尝试下一个,直到找到那个返回 SUCCESS 的子任务。一旦某个子任务返回 SUCCESS,Selector 就会停止,并同样返回 SUCCESS。Selector 的目的就是找出一个能够成功的子任务。
行为树通过条件任务来处理条件逻辑。这些任务检查特定条件,并根据智能体或其环境的状态返回 SUCCESS 或 FAILURE(例如 “IsLowOnHealth”、“IsTargetInSight”)。条件可以与 Sequence 和 Selector 搭配使用,构建你的决策逻辑。
🛈 注意:要创建你自己的条件,请继承 BTCondition 类。
请查阅 BTTask 类的文档,它为行为树的各种积木块提供了基础。
创建行为树
本章介绍如何创建和调试行为树。
为智能体添加行为树
按照以下步骤,为新建或已有的智能体添加行为树:
调试行为树
在 Godot 引擎中,依次打开 “Bottom Panel > Debugger > LimboAI” 标签页。借助 LimboAI 调试器,你可以查看运行中的项目里任何当前处于活动状态的行为树。调试器可以从主编辑器窗口中分离出来,如果你使用 HiDPI 显示器或第二块屏幕,这会特别有用。
查看任务属性与黑板
当你在 LimboAI 调试器中点击某个任务时,它的属性会显示在远程检视面板(Remote Inspector)中,其中包含 Blackboard 引用。点击 Blackboard 可以打开它,查看整条作用域链上的所有变量,并按作用域分组。你还可以实时修改变量值,这对测试和调试游戏 AI 很有帮助。
创建自定义任务
默认情况下,用户任务应放在 res://ai/tasks 目录中。你可以在 Project Settings → Limbo AI 中为用户任务设置其他位置(要看到这些选项,需要在项目设置中启用 Advanced Settings)。
用户任务目录下的每个子目录都会被当作一个分类。因此,如果你创建了一个名为 “motion_and_physics” 的子目录,其中的自定义任务会自动归类到 “Motion And Physics” 下。
创建自定义任务时,请继承以下基类之一:BTAction、BTCondition、BTDecorator、BTComposite。关于任务类型的更多内容,可阅读行为树简介。
🛈 注意:为了帮助你编写新任务,你可以通过 “Misc → Create script template” 菜单项向项目中添加脚本模板。
Blackboard 的使用方法见在任务中访问黑板。
任务的结构
@tool
extends BTAction
# 任务参数。
@export var parameter1: float
@export var parameter2: Vector2
## 注意:每个方法声明都是可选的。
## 至少只需要定义 "_tick" 方法。
# 调用它来为任务生成显示名称(需要 @tool)。
func _generate_name() -> String:
return "MyTask"
# 调用它来初始化任务。
func _setup() -> void:
pass
# 当任务被进入时调用。
func _enter() -> void:
pass
# 当任务被退出时调用。
func _exit() -> void:
pass
# 每次该任务被 tick(即被执行)时调用。
func _tick(delta: float) -> Status:
return SUCCESS
# 此方法返回的字符串会作为警告显示在编辑器中。
func _get_configuration_warnings() -> PackedStringArray:
var warnings := PackedStringArray()
return warnings
示例 1:一个简单的动作
@tool
extends BTAction
## 显示或隐藏一个节点并返回 SUCCESS。
## 如果找不到该节点,返回 FAILURE。
# 任务参数。
@export var node_path: NodePath
@export var visible := true
# 调用它来为任务生成显示名称(需要 @tool)。
func _generate_name() -> String:
return "SetVisible %s node_path: \"%s\"" % [visible, node_path]
# 每次该任务被 tick(即被执行)时调用。
func _tick(p_delta: float) -> Status:
var n: CanvasItem = scene_root.get_node_or_null(node_path)
if is_instance_valid(n):
n.visible = visible
return SUCCESS
return FAILURE
示例 2:InRange 条件
@tool
extends BTCondition
## InRange 条件检查智能体是否处于目标的某个范围内,
## 该范围由 distance_min 和 distance_max 定义。
## 如果智能体处于定义的范围内,返回 SUCCESS;
## 否则返回 FAILURE。
@export var distance_min: float
@export var distance_max: float
@export var target_var: StringName = &"target"
var _min_distance_squared: float
var _max_distance_squared: float
# 调用它来为任务生成显示名称。
func _generate_name() -> String:
return "InRange (%d, %d) of %s" % [distance_min, distance_max,
LimboUtility.decorate_var(target_var)]
# 调用它来初始化任务。
func _setup() -> void:
_min_distance_squared = distance_min * distance_min
_max_distance_squared = distance_max * distance_max
# 当任务被执行时调用。
func _tick(_delta: float) -> Status:
var target: Node2D = blackboard.get_var(target_var, null)
if not is_instance_valid(target):
return FAILURE
var dist_sq: float = agent.global_position.distance_squared_to(target.global_position)
if dist_sq >= _min_distance_squared and dist_sq <= _max_distance_squared:
return SUCCESS
else:
return FAILURE
用 C# 创建任务
自定义任务可以使用以下脚本模板:
using Godot;
using System;
[Tool]
public partial class _CLASS_ : _BASE_
{
public override string _GenerateName()
{
return "_CLASS_";
}
public override void _Setup()
{
}
public override void _Enter()
{
}
public override void _Exit()
{
}
public override Status _Tick(double delta)
{
return Status.Success;
}
public override string[] _GetConfigurationWarnings()
{
return Array.Empty<string>();
}
}
访问场景树中的节点
有几种方式可以从 BTTask 中访问智能体场景树里的节点。
🛈 注意:智能体场景树的根节点可以通过 scene_root 属性访问。
使用 BBNode 属性
@export var cast_param: BBNode
func _tick(delta) -> Status:
var node: ShapeCast3D = cast_param.get_value(scene_root, blackboard)
使用 NodePath 属性
@export var cast_path: NodePath
func _tick(delta) -> Status:
var node: ShapeCast3D = scene_root.get_node(cast_path)
使用黑板计划
你可以在编辑器中创建一个黑板变量,类型为 NodePath,并让它在 BTPlayer 的黑板计划中指向合适的节点。默认情况下,当运行时实例化黑板时,任何 NodePath 变量都会被替换为对应的节点实例(见 BlackboardPlan.prefetch_nodepath_vars)。
extends BTCondition
@export var shape_var: StringName = &"shape_cast"
func _tick(delta) -> Status:
var shape_cast: ShapeCast3D = blackboard.get_var(shape_var)
BTPlayer.prefetch_nodepath_vars 属性应设置为 true。
创建状态机
本指南将展示如何使用 LimboHSM 搭建并使用状态机。
初始化
要使用 LimboHSM 状态机,你首先需要在代码中初始化它。这通常是在脚本的 _ready 函数中完成。下面是一个示例:
@onready var hsm: LimboHSM = $LimboHSM
@onready var idle_state: LimboState = $LimboHSM/IdleState
@onready var move_state: LimboState = $LimboHSM/MoveState
func _ready() -> void:
_init_state_machine()
func _init_state_machine() -> void:
hsm.add_transition(idle_state, move_state, idle_state.EVENT_FINISHED)
hsm.add_transition(move_state, idle_state, move_state.EVENT_FINISHED)
hsm.initialize(self)
hsm.set_active(true)
在这个示例中,我们首先声明状态机以及要使用的各个状态。然后在 _init_state_machine 函数中为各状态添加转换。最后初始化状态机,并将其设为活动状态。
状态示例
你可以在脚本中定义状态的行为,并把该脚本挂到状态节点上。下面是一个状态示例,它会在 AnimationPlayer 上播放动画并等待动画播放完毕:
extends LimboState
## PlayAnimation:在 AnimationPlayer 上播放动画,并等待其播放完毕。
@export var animation_player: AnimationPlayer
@export var animation_name: StringName
func _enter() -> void:
animation_player.play(animation_name)
func _update(_delta: float) -> void:
if not animation_player.is_playing() \
or animation_player.assigned_animation != animation_name:
dispatch(EVENT_FINISHED)
在这个示例中,_enter 方法会在进入该状态时被调用,并播放指定的动画。_update 方法每帧都会被调用,用来检查动画是否播放完毕。如果已播放完毕,它就派发 EVENT_FINISHED 事件,从而可能转换到下一个状态。
事件与转换
LimboHSM 自带一套事件系统,有助于把状态转换与状态实现解耦。一个转换与特定的事件、起始状态和目标状态相关联,当该事件被派发时,转换会自动执行。
要注册一个转换并把它与特定事件关联,可以使用 LimboHSM.add_transition 方法:
hsm.add_transition(idle_state, move_state, &"movement_started")
在这个示例中,我们注册了一个从 idle_state 到 move_state 的转换,它在 movement_started 事件被派发时发生。
转换也可以不与任何特定的起始状态关联:
hsm.add_transition(hsm.ANYSTATE, move_state, &"movement_started")
事件通过 LimboState.dispatch 方法派发。需要注意的是,该方法可以从状态机层级中的任何位置调用,也可以在状态机之外调用。事件会从叶状态向根状态传播。这意味着,如果某个事件被某个状态消费掉,它就不会再传播到其父状态。
状态还可以定义事件处理器,即对特定事件做出反应的方法。这些事件处理器通常不会导致状态转换;它们只是状态对特定事件做出反应的一种机制。你可以用 LimboState.add_event_handler 方法在状态中注册事件处理器:
extends LimboState
func _setup() -> void:
add_event_handler("movement_started", _on_movement_started)
func _on_movement_started(cargo = null) -> bool:
# 在这里处理 "movement_started" 事件。
# 调用 `dispatch()` 时可以随事件一起传入 `cargo`。
# 当你需要向事件处理器传递一些数据时,这非常方便。
return true
如果事件处理器返回 true,该事件将被视为已被消费,不会再继续传播,也不会导致状态转换。
状态的结构
extends LimboState
## 状态初始化时调用一次。
func _setup() -> void:
pass
## 当状态被进入时调用。
func _enter() -> void:
pass
## 当状态被退出时调用。
func _exit() -> void:
pass
## 当该状态处于活动状态时每帧调用。
func _update(delta: float) -> void:
pass
把行为树与状态机结合使用
BTState 是 LimboHSM 中一种特殊的状态节点,它可以承载一个行为树。当 BTState 处于活动状态时,它每帧都会执行所承载的行为树,实际上就是把该行为树当作它的实现。
这样你就可以把行为树的强大能力与状态机的结构与控制结合起来。行为树非常适合定义复杂的层次化行为,而状态机则擅长管理不同行为之间的流转与转换。
创建好 LimboHSM 之后,就可以为给定的 LimboHSM 创建一个 BTState:
extends CharacterBody2D
var hsm: LimboHSM
@export var behavior_tree: BehaviorTree
func _ready():
hsm = LimboHSM.new()
add_child(hsm)
var bt_state := BTState().new()
bt_state.named("Supplied BT")
# 设置行为树,或使用 load("res://ai/trees/...") 调用
bt_state.behavior_tree = behavior_tree
bt_state.set_scene_root_hint(self)
hsm.add_child(bt_state)
hsm.initial_state = bt_state
hsm.initialize(self)
hsm.set_active(true)
单文件状态机配置
在某些情况下,例如做原型或参加 Game Jam 时,把状态机代码放在单个文件里更实用。针对这类情况,LimboHSM 支持委托(delegation),并提供链式方法以便更轻松地完成配置。下面用一个实际的代码示例来说明:
extends CharacterBody2D
var hsm: LimboHSM
@onready var animation_player: AnimationPlayer = $AnimationPlayer
func _ready() -> void:
_init_state_machine()
func _init_state_machine() -> void:
hsm = LimboHSM.new()
add_child(hsm)
# 使用链式方法与委托来配置状态:
var idle_state := LimboState.new().named("Idle") \
.call_on_enter(func(): animation_player.play("idle")) \
.call_on_update(_idle_update)
var move_state := LimboState.new().named("Move") \
.call_on_enter(func(): animation_player.play("walk")) \
.call_on_update(_move_update)
hsm.add_child(idle_state)
hsm.add_child(move_state)
hsm.add_transition(idle_state, move_state, &"movement_started")
hsm.add_transition(move_state, idle_state, &"movement_ended")
hsm.initialize(self)
hsm.set_active(true)
func _idle_update(delta: float) -> void:
var dir: Vector2 = Input.get_vector(
&"ui_left", &"ui_right", &"ui_up", &"ui_down")
if not dir.is_zero_approx():
hsm.dispatch(&"movement_started")
func _move_update(delta: float) -> void:
var dir: Vector2 = Input.get_vector(
&"ui_left", &"ui_right", &"ui_up", &"ui_down")
var desired_velocity: Vector2 = dir * 200.0
velocity = desired_velocity
move_and_slide()
if desired_velocity.is_zero_approx():
hsm.dispatch(&"movement_ended")
重要类
LimboAI 中引入了很多类。下面列出你应该了解的最重要的那些:
BTTask
继承:BT
被继承:BTAction、BTComment、BTComposite、BTCondition、BTDecorator
所有 BehaviorTree 任务的基类。
说明
所有 BehaviorTree 任务的基类。任务是 BehaviorTree 中的基本积木块,代表某个具体行为或控制流。通过按层次组合和嵌套任务,可以构建出复杂的行为。
任务可以是以下类型之一:动作、条件、组合或装饰器。每种任务类型都有对应的子类:BTAction、BTCondition、BTDecorator、BTComposite。
任务通过 _tick 方法执行工作并返回状态。状态值定义在 Status 中。任务可以用 _setup 方法初始化。另见 _enter 与 _exit。
注意:不要直接继承 BTTask 来实现你自己的任务,而应继承上面提到的某个子类型。
属性
|
||
|
|
|
|
||
|
||
方法
void |
_enter() virtual |
void |
_exit() virtual |
|
_generate_name() virtual const |
|
_get_configuration_warnings() virtual const |
void |
_setup() virtual |
_tick(delta: |
|
void |
abort() |
void |
|
void |
add_child_at_index(task: BTTask, idx: |
clone() const |
|
execute(delta: |
|
get_child(idx: |
|
|
get_child_count() const |
|
|
|
get_index() const |
get_parent() const |
|
get_root() const |
|
|
|
|
|
void |
initialize(agent: |
|
is_descendant_of(task: BTTask) const |
|
is_root() const |
next_sibling() const |
|
void |
print_tree(initial_tabs: |
void |
remove_child(task: BTTask) |
void |
remove_child_at_index(idx: |
属性说明
Node agent 🔗
void set_agent(value:
Node)Nodeget_agent()
agent 是 BehaviorTree 实例的上下文对象。通常它是使用 BehaviorTree 资源的 BTPlayer 节点的父节点。
Blackboard blackboard 🔗
Blackboard get_blackboard()
提供对 Blackboard 的访问。黑板用于在同一 BehaviorTree 的各任务之间共享数据。
更多信息见 Blackboard。
String custom_name = "" 🔗
void set_custom_name(value:
String)Stringget_custom_name()
用户为任务提供的名称。如果不为空,编辑器会用它来表示该任务。见 get_task_name。
float elapsed_time 🔗
floatget_elapsed_time()
自任务被“进入”以来所经过的时间。见 _enter。
当任务不处于 RUNNING 状态时返回 0。
Node scene_root 🔗
Nodeget_scene_root()
行为树所在场景的根节点(例如 BTPlayer 节点的拥有者)。可用于获取 NodePath 引用。
示例:
extends BTAction
@export var node_path: NodePath
func _setup():
var node: Node = scene_root.get_node(node_path)
Status get_status()
方法说明
void _enter() virtual 🔗
当任务被“进入”时调用,即任务在不具有 RUNNING status 的情况下被执行时。
在执行顺序上,它先于 _tick 被调用。当主要工作开始前需要做准备时使用此方法,通常是在任务需要不止一个 tick 才能完成时。另见 execute。
void _exit() virtual 🔗
当任务被“退出”时调用,即在 _tick 返回 SUCCESS 或 FAILURE 状态之后。另见 execute。
String _generate_name() virtual const 🔗
在未设置 custom_name 时,调用它来为任务生成显示名称。见 get_task_name。
PackedStringArray _get_configuration_warnings() virtual const 🔗
此方法返回的字符串会作为警告消息显示在行为树编辑器中。任何重写了此方法的任务脚本都必须在文件顶部包含 @tool 注解。
void _setup() virtual 🔗
在初始化阶段调用,用于初始化任务。它只会在任务第一次执行 tick 之前被调用一次。借助这个方法,你可以在任务开始执行之前为它设置所需的状态或配置。
Status _tick(delta: float) virtual 🔗
当任务被“tick”时调用,也就是在更新过程中由 BTPlayer 或 BTState 执行它时。
返回定义在 Status 中的执行状态。
注意:任务通过实现这个方法来执行其主要功能。
void abort() 🔗
递归地重置该任务及其子任务。如果任务处于 RUNNING 状态,它会被退出,并且其状态被重置为 FRESH。
void add_child(task: BTTask) 🔗
添加一个子任务。task 会被放到子任务列表的末尾。
void add_child_at_index(task: BTTask, idx: int) 🔗
添加一个子任务。task 会被放到子任务列表中的 idx 位置。
复制该任务及其子任务,并复制导出的成员。出于效率考虑,子资源是共享的,但 BBParam 的子类型例外,它们总是会被复制。编辑器用它来实例化 BehaviorTree,以及复制粘贴任务。
BehaviorTree editor_get_behavior_tree() 🔗
返回拥有此任务的行为树。仅在编辑器中可用。
Status execute(delta: float) 🔗
执行该任务。执行遵循特定的顺序:
BTTask get_child(idx: int) const 🔗
通过指定索引返回一个子任务。
int get_child_count() const 🔗
返回子任务的数量。
int get_child_count_excluding_comments() const 🔗
返回子任务的数量,不把 BTComment 任务计算在内。
int get_index() const 🔗
返回该任务在行为树分支中的位置。如果该任务不属于任务树(也就是没有父任务),则返回 -1。
返回该任务的父任务。
返回行为树的根任务。
String get_task_name() 🔗
此方法返回的字符串用于在编辑器中表示该任务。
除非设置了 custom_name,否则会调用 _generate_name 方法为任务生成显示名称。
bool has_child(task: BTTask) const 🔗
如果 task 是此任务的子任务,则返回 true。
void initialize(agent: Node, blackboard: Blackboard, scene_root: Node) 🔗
初始化该任务。为它赋值 agent 和 blackboard,并对该任务及其子任务调用 _setup。
该方法会对每个子任务递归调用。scene_root 应当是行为树所在场景的根节点(例如包含该行为树的节点的拥有者)。
bool is_descendant_of(task: BTTask) const 🔗
如果此任务是 task 的后代,则返回 true。换句话说,此任务必须是 task 的子任务,或者是它的子任务、孙任务之一。
bool is_root() const 🔗
如果此任务是其行为树的根任务,则返回 true。一棵行为树只能有一个根任务。
返回父任务子任务列表中紧接在此任务之后的任务。
如果此任务没有父任务,或者它是父任务子任务列表中的最后一个子任务,则返回 null。
void print_tree(initial_tabs: int = 0) 🔗
把以此任务为起点的子树打印到控制台。
void remove_child(task: BTTask) 🔗
从子任务中移除 task。
void remove_child_at_index(idx: int) 🔗
从子任务中移除指定索引处的子任务。
BTPlayer
继承:
BehaviorTree 资源的播放器。
说明
BTPlayer 节点用于在运行时实例化和播放 BehaviorTree 资源。初始化期间,行为树实例会获得对智能体、blackboard 以及当前场景根节点的引用。智能体可以通过 agent_node 属性指定(默认是 BTPlayer 的父节点)。
行为树的入门介绍见 BehaviorTree。
属性
|
|
|
|
|
|
|
|
|
|
方法
void |
restart() |
void |
set_bt_instance(bt_instance: BTInstance) |
void |
set_scene_root_hint(scene_root: |
void |
update(delta: |
信号
behavior_tree_finished(status: int) 🔗
已废弃:请改用 updated 信号。
当行为树执行完毕并返回 SUCCESS 或 FAILURE 时发出。
参数 status 保存行为树返回的状态。见 Status。
updated(status: int) 🔗
当 BTPlayer 完成行为树更新时发出。
参数 status 保存行为树返回的状态。见 Status。
枚举
enum UpdateMode: 🔗
UpdateMode IDLE = 0
在空闲(idle)处理期间执行行为树。
UpdateMode PHYSICS = 1
在物理(physics)处理期间执行行为树。
UpdateMode MANUAL = 2
通过调用 update 手动执行行为树。
属性说明
bool active = true 🔗
void set_active(value:
bool)boolget_active()
如果为 true,行为树将在更新期间被执行。
NodePath agent_node = NodePath("..") 🔗
void set_agent_node(value:
NodePath)NodePathget_agent_node()
用作智能体的节点路径。在实例化之后再设置它不会生效。
BehaviorTree behavior_tree 🔗
void set_behavior_tree(value: BehaviorTree)
BehaviorTree get_behavior_tree()
要在运行时实例化并执行的 BehaviorTree 资源。
Blackboard blackboard 🔗
void set_blackboard(value: Blackboard)
Blackboard get_blackboard()
保存行为树各任务共享的数据。见 Blackboard。
BlackboardPlan blackboard_plan 🔗
void set_blackboard_plan(value: BlackboardPlan)
BlackboardPlan get_blackboard_plan()
存储并管理用于构建新的 Blackboard 实例的变量。
bool monitor_performance = false 🔗
void set_monitor_performance(value:
bool)boolget_monitor_performance()
如果为 true,会为此 BTPlayer 节点的每个实例在 “Debugger->Monitors” 中添加一个性能监视器。
UpdateMode update_mode = 1 🔗
void set_update_mode(value: UpdateMode)
UpdateMode get_update_mode()
决定行为树何时执行。见 UpdateMode。
方法说明
BTInstance get_bt_instance() 🔗
返回行为树实例。
void restart() 🔗
重置行为树的执行。所有正在运行的任务都会被中止,下一次树执行会从头开始。此方法不会重置 Blackboard。
void set_bt_instance(bt_instance: BTInstance) 🔗
设置要播放的 BTInstance。当你想在运行时切换到另一个行为树实例时,这个方法很有用。另见 BehaviorTree.instantiate。
void set_scene_root_hint(scene_root: Node) 🔗
设置新实例化的行为树要使用的场景根节点 Node。应当在 BTPlayer 被加入场景树之前调用(即 NOTIFICATION_READY 之前)。当你需要用代码动态创建 BTPlayer 节点时,这通常很有用。
void update(delta: float) 🔗
如果 active 为 true,则执行行为树实例的根任务。当 update_mode 设为 MANUAL 时调用此方法。当 update_mode 不是 MANUAL 时,会自动调用 update。见 UpdateMode。
Blackboard
继承:
用于在 LimboHSM 状态与 BehaviorTree 任务之间共享数据的键值存储。
说明
Blackboard 是 LimboHSM 系统中的状态与 BehaviorTree 中的任务之间存储和共享数据的地方。BehaviorTree 中的每个状态和任务都能访问这个 Blackboard,从而可以读取和写入数据。这让不同动作与行为之间共享信息变得非常简单。
Blackboard 也可以充当另一个 Blackboard 的父作用域。如果在当前作用域中找不到某个变量,它就会到父级 Blackboard 中查找。父级 Blackboard 本身也可以拥有自己的父作用域,从而形成我们所说的“黑板作用域链”。重要的是,这条链中 Blackboard 的数量没有上限,而且 Blackboard 不会修改父作用域中的值。
可以用 BTNewScope 和 BTSubtree 装饰器创建新作用域。此外,对于任何定义了非空 Blackboard 数据的 LimboState,或任何根层级的 LimboHSM 节点,都会自动创建一个新作用域。
方法
void |
bind_var_to_property(var_name: |
void |
clear() |
void |
erase_var(var_name: |
get_parent() const |
|
|
get_var(var_name: |
|
get_vars_as_dict() const |
|
has_var(var_name: |
void |
link_var(var_name: |
Array[ |
list_vars() const |
void |
populate_from_dict(dictionary: |
void |
print_state() const |
void |
set_parent(blackboard: Blackboard) |
void |
set_var(var_name: |
top() const |
|
void |
unbind_var(var_name: |
方法说明
void bind_var_to_property(var_name: StringName, object: Object, property: StringName, create: bool = false) 🔗
在变量与由 property 和 object 指定的对象属性之间建立绑定。变量发生变化会更新该属性,反之亦然。如果 create 为 true,则变量不存在时会被创建。
void clear() 🔗
从 Blackboard 中移除所有变量。父作用域不受影响。
void erase_var(var_name: StringName) 🔗
按名称移除一个变量。
Blackboard get_parent() const 🔗
返回作为此实例父作用域的 Blackboard。
Variant get_var(var_name: StringName, default: Variant = null, complain: bool = true) const 🔗
返回变量值;如果变量不存在则返回 default。如果 complain 为 true,变量不存在时会打印错误。如果该变量在当前 Blackboard 作用域中不存在,它会在父作用域 Blackboard 中查找。
Dictionary get_vars_as_dict() const 🔗
以字典形式返回 Blackboard 中的所有变量。键是变量名,值是变量值。不包含父作用域。
bool has_var(var_name: StringName) const 🔗
如果 Blackboard 包含 var_name 变量(含父作用域),则返回 true。
void link_var(var_name: StringName, target_blackboard: Blackboard, target_var: StringName, create: bool = false) 🔗
把一个变量链接到另一个 Blackboard 变量。如果一个变量被链接到另一个变量,它们的状态将始终一致,任何一方发生变化都会反映到另一方。如果 create 为 true,则变量不存在时会被创建。
你可以用这个方法把当前作用域中的变量链接到另一个作用域或另一个 Blackboard 实例中的变量。一个变量只能链接到另一个变量。再次调用此方法会覆盖之前的链接。不过,同一个变量可以被多个不同的变量链接。
Array[StringName] list_vars() const 🔗
返回 Blackboard 中所有变量的名称。不包含父作用域。
void populate_from_dict(dictionary: Dictionary) 🔗
用字典中的多个变量填充 Blackboard。字典的键必须是变量名,字典的值必须是变量值。键必须是 StringName 或 String。
void print_state() const 🔗
打印每个作用域中所有变量的值。
void set_parent(blackboard: Blackboard) 🔗
赋值父作用域。如果某个值不在当前 Blackboard 作用域中,它会在父作用域 Blackboard 中查找。
void set_var(var_name: StringName, value: Variant) 🔗
为当前 Blackboard 作用域中的变量赋值。如果变量不存在,它会被创建。如果该变量已存在于父作用域中,父作用域的值不会被修改。
Blackboard top() const 🔗
返回作用域链中最顶层的 Blackboard。
void unbind_var(var_name: StringName) 🔗
移除变量的绑定。
BBParam
继承:
被继承:BBAabb、BBArray、BBBasis、BBBool、BBByteArray、BBColor、BBColorArray、BBDictionary、BBFloat、BBFloat32Array、BBFloat64Array、BBInt、BBInt32Array、BBInt64Array、BBNode、BBPlane、BBProjection、BBQuaternion、BBRect2、BBRect2i、BBString、BBStringArray、BBStringName、BBTransform2D、BBTransform3D、BBVariant、BBVector2、BBVector2Array、BBVector2i、BBVector3、BBVector3Array、BBVector3i、BBVector4、BBVector4i
LimboAI 类型化参数的基类。
说明
LimboAI 类型化参数的基类,既可以引用 Blackboard 变量,也可以直接保存某个 Variant.Type 类型的原始值。
注意:不要直接实例化,请改用具体的子类型。
属性
|
|
|
|
||
|
方法
Variant.Type |
get_type() const |
|
get_value(scene_root: |
枚举
enum ValueSource: 🔗
ValueSource SAVED_VALUE = 0
值直接存储在 BBParam 资源中。
ValueSource BLACKBOARD_VAR = 1
值通过变量名引用,并从 Blackboard 中获取。变量名存储在 BBParam 资源中。
属性说明
Variant saved_value = null 🔗
void set_saved_value(value:
Variant)Variantget_saved_value()
当 value_source 设为 SAVED_VALUE 时,用于存储参数值。值的类型由 get_type 决定。
ValueSource value_source = 0 🔗
void set_value_source(value: ValueSource)
ValueSource get_value_source()
指定 BBParam 取值的来源。见 ValueSource。
StringName variable 🔗
void set_variable(value:
StringName)StringNameget_variable()
当 value_source 设为 BLACKBOARD_VAR 时,存储 Blackboard 变量的名称。
方法说明
Variant.Type get_type() const 🔗
返回该参数预期的数据类型。
Variant get_value(scene_root: Node, blackboard: Blackboard, default: Variant = null) 🔗
返回该参数的值。
LimboState
继承:
用于分层状态机(HSM)的状态节点。
说明
LimboAI 中用于分层状态机(HSM)的状态节点。
你可以通过继承这个类来编写自己的状态行为。要实现状态逻辑,可以重写 _enter、_exit、_setup 和 _update。或者,你也可以用 call_on_* 方法把状态实现委托给外部方法。
关于状态机的更多细节,请参阅 LimboHSM。
属性
|
|
|
|
方法
void |
_enter() virtual |
void |
_exit() virtual |
void |
_setup() virtual |
void |
_update(delta: |
void |
add_event_handler(event: |
call_on_enter(callable: |
|
call_on_exit(callable: |
|
call_on_update(callable: |
|
void |
|
|
dispatch(event: |
get_root() const |
|
|
is_active() const |
named(name: |
|
void |
set_guard(guard_callable: |
信号
entered() 🔗
当状态被进入时发出。
exited() 🔗
当状态被退出时发出。
setup() 🔗
当状态被初始化时发出。
updated(delta: float) 🔗
当状态被更新时发出。
属性说明
StringName EVENT_FINISHED 🔗
StringNameevent_finished()
一个常用事件,表示状态已经完成其工作。
Node agent 🔗
void set_agent(value:
Node)Nodeget_agent()
与该状态关联的智能体,在初始化时赋值。
Blackboard blackboard 🔗
Blackboard get_blackboard()
该状态所属状态机中各状态共享的键值数据存储。
BlackboardPlan blackboard_plan 🔗
void set_blackboard_plan(value: BlackboardPlan)
BlackboardPlan get_blackboard_plan()
存储并管理用于构建新的 Blackboard 实例的变量。
方法说明
void _enter() virtual 🔗
当状态被进入时调用。
void _exit() virtual 🔗
当状态被退出时调用。这会在转换到另一个状态时发生,也会在状态机从场景树中被移除时发生(例如节点被 Node.queue_free 释放或场景切换)。由于实现细节,_exit 不会在调用 Object.free 时被执行!
void _setup() virtual 🔗
在初始化期间被调用一次。用这个方法初始化你的状态。
void _update(delta: float) virtual 🔗
在更新期间调用。用这个方法实现你状态的行为。
void add_event_handler(event: StringName, handler: Callable) 🔗
注册一个 handler,在 event 被派发时调用。处理函数应具有以下签名:
func my_event_handler(cargo=null) -> bool:
如果处理函数返回 true,事件将被消费。Cargo 是可选参数,可以传给处理函数。另见 dispatch。
LimboState call_on_enter(callable: Callable) 🔗
链式方法,把 entered 信号连接到一个 callable。
LimboState call_on_exit(callable: Callable) 🔗
链式方法,把 exited 信号连接到一个 callable。
LimboState call_on_update(callable: Callable) 🔗
链式方法,把 updated 信号连接到一个 callable。
void clear_guard() 🔗
清除守卫函数,移除之前由 set_guard 设置的 Callable。
bool dispatch(event: StringName, cargo: Variant = null) 🔗
递归派发一个名为 event 的状态机事件,可选参数为 cargo。如果事件被消费则返回 true。
事件会从叶状态向根状态传播,一旦某个状态消费了该事件,传播就会停止。如果状态有相关的转换或事件处理器,它就会消费该事件。关于事件处理器的更多信息,见 add_event_handler。
LimboState get_root() const 🔗
返回根 LimboState。
bool is_active() const 🔗
如果当前处于活动状态(即它是父级 LimboHSM 的活动子状态),则返回 true。
LimboState named(name: String) 🔗
用于设置此状态名称的链式方法。
void set_guard(guard_callable: Callable) 🔗
设置守卫(guard)函数,每当考虑转换到该状态时都会调用它。如果该函数返回 false,该转换将被禁止。
LimboHSM
继承:LimboState
基于事件的分层状态机(HSM)。
说明
基于事件的分层状态机(HSM),用于管理 LimboState 实例并处理它们之间的转换。LimboHSM 本身就是一个 LimboState,也可以作为另一个 LimboHSM 节点的子节点。
属性
|
方法
void |
add_transition(from_state: LimboState, to_state: LimboState, event: |
void |
change_active_state(state: LimboState) |
get_active_state() const |
|
get_leaf_state() const |
|
get_previous_active_state() const |
|
|
has_transition(from_state: LimboState, event: |
void |
initialize(agent: |
void |
remove_transition(from_state: LimboState, event: |
void |
set_active(active: |
void |
update(delta: |
信号
active_state_changed(current: LimboState, previous: LimboState) 🔗
当当前活动的子状态切换到另一个子状态时发出。
枚举
enum UpdateMode: 🔗
UpdateMode IDLE = 0
在空闲处理期间更新状态机。
UpdateMode PHYSICS = 1
在物理处理期间更新状态机。
UpdateMode MANUAL = 2
通过在脚本中调用 update 来手动更新状态机。
属性说明
LimboState ANYSTATE 🔗
LimboState anystate()
用于定义“从任意状态出发”的转换。
LimboState initial_state 🔗
void set_initial_state(value: LimboState)
LimboState get_initial_state()
使用 set_active 方法激活状态机时会变为活动的子状态。如果没有显式设置,LimboHSM 的第一个子节点将被视为初始状态。
UpdateMode update_mode = 1 🔗
void set_update_mode(value: UpdateMode)
UpdateMode get_update_mode()
指定状态机应在何时更新。见 UpdateMode。
方法说明
void add_transition(from_state: LimboState, to_state: LimboState, event: StringName, guard: Callable = Callable()) 🔗
建立从一个状态到另一个状态的转换,在 event 被派发时触发。from_state 和 to_state 都必须是此 LimboHSM 的直接子节点。
可选地,可以指定一个 guard 函数,它必须返回布尔值。如果守卫函数返回 false,则不会发生转换。守卫函数会在考虑该转换之前立即被调用。关于状态级别的守卫函数,请查看 LimboState.set_guard。
func my_guard() -> bool:
return is_some_condition_met()
void change_active_state(state: LimboState) 🔗
把当前活动的子状态切换为 state。如果 state 已经处于活动状态,它会被退出并重新进入。
state 必须是此 LimboHSM 的子节点。
LimboState get_active_state() const 🔗
返回当前活动的子状态。
LimboState get_leaf_state() const 🔗
返回状态机中当前活动的叶状态。
LimboState get_previous_active_state() const 🔗
返回上一个活动的子状态。
bool has_transition(from_state: LimboState, event: StringName) const 🔗
如果存在从 from_state 出发、针对给定 event 的转换,则返回 true。
void initialize(agent: Node, parent_scope: Blackboard = null) 🔗
初始化该状态,并为它自身及所有子状态调用 LimboState._setup。
void remove_transition(from_state: LimboState, event: StringName) 🔗
移除某个状态上与特定 event 关联的转换。
void set_active(active: bool) 🔗
设为 true 时,会把状态切换到 initial_state,并根据 update_mode 激活状态处理。
void update(delta: float) 🔗
对它自身和活动子状态调用 LimboState._update,调用会逐级向下传递到叶状态。如果 update_mode 未设为 MANUAL,此方法会自动触发。
BTState
继承:LimboState
用于 LimboHSM、承载 BehaviorTree 的状态节点。
说明
BTState 是一种 LimboState 节点,它通过管理 BehaviorTree 来为该状态提供行为逻辑。它会实例化并运行 BehaviorTree 资源,并在 SUCCESS 或 FAILURE 时派发状态机事件。事件名称可以通过 success_event 和 failure_event 自定义。关于状态机事件的更多细节,见 LimboState.dispatch。
属性
|
|
|
|
|
|
|
|
方法
get_bt_instance() const |
|
void |
set_scene_root_hint(scene_root: |
属性说明
BehaviorTree behavior_tree 🔗
void set_behavior_tree(value: BehaviorTree)
BehaviorTree get_behavior_tree()
定义状态行为的 BehaviorTree 资源。
StringName failure_event = &"failure" 🔗
void set_failure_event(value:
StringName)StringNameget_failure_event()
当行为树结果为 FAILURE 时将被派发的 HSM 事件。见 LimboState.dispatch。
bool monitor_performance = false 🔗
void set_monitor_performance(value:
bool)boolget_monitor_performance()
如果为 true,会为此 BTState 节点的每个实例在 “Debugger->Monitors” 中添加一个性能监视器。
StringName success_event = &"success" 🔗
void set_success_event(value:
StringName)StringNameget_success_event()
当行为树结果为 SUCCESS 时将被派发的 HSM 事件。见 LimboState.dispatch。
方法说明
BTInstance get_bt_instance() const 🔗
返回行为树实例。
void set_scene_root_hint(scene_root: Node) 🔗
设置新实例化的行为树要使用的场景根节点 Node。应当在状态机初始化之前调用。当你需要用代码动态创建 BTState 节点时,这通常很有用。
完整的类参考可以在侧边栏中找到。
BBAabb
继承:BBParam
用于 BehaviorTree 任务的 AABB 类型参数。见 BBParam。
BBArray
继承:BBParam
用于 BehaviorTree 任务的 Array 类型参数。见 BBParam。
BBBasis
继承:BBParam
用于 BehaviorTree 任务的 Basis 类型参数。见 BBParam。
BBBool
继承:BBParam
用于 BehaviorTree 任务的 Bool 类型参数。见 BBParam。
BBByteArray
继承:BBParam
用于 BehaviorTree 任务的 ByteArray 类型参数。见 BBParam。
BBColor
继承:BBParam
用于 BehaviorTree 任务的 Color 类型参数。见 BBParam。
BBColorArray
继承:BBParam
用于 BehaviorTree 任务的 ColorArray 类型参数。见 BBParam。
BBDictionary
继承:BBParam
用于 BehaviorTree 任务的 Dictionary 类型参数。见 BBParam。
BBFloat
继承:BBParam
用于 BehaviorTree 任务的 Float 类型参数。见 BBParam。
BBFloat32Array
继承:BBParam
用于 BehaviorTree 任务的 PackedFloat32Array 类型参数。见 BBParam。
BBFloat64Array
继承:BBParam
用于 BehaviorTree 任务的 PackedFloat64Array 类型参数。见 BBParam。
BBInt
继承:BBParam
用于 BehaviorTree 任务的 Integer 类型参数。见 BBParam。
BBInt32Array
继承:BBParam
用于 BehaviorTree 任务的 PackedInt32Array 类型参数。见 BBParam。
BBInt64Array
继承:BBParam
用于 BehaviorTree 任务的 PackedInt64Array 类型参数。见 BBParam。
BBNode
继承:BBParam
用于 BehaviorTree 任务的 Node 类型参数。见 BBParam。
说明
面向 BehaviorTree 任务使用的 Node 类型参数。见 BBParam。
如果来源是黑板变量,则允许任何继承自 Object 的类型。
BBPlane
继承:BBParam
用于 BehaviorTree 任务的 Plane 类型参数。见 BBParam。
BBProjection
继承:BBParam
用于 BehaviorTree 任务的 Projection 类型参数。见 BBParam。
BBQuaternion
继承:BBParam
用于 BehaviorTree 任务的 Quaternion 类型参数。见 BBParam。
BBRect2
继承:BBParam
用于 BehaviorTree 任务的 Rect2 类型参数。见 BBParam。
BBRect2i
继承:BBParam
用于 BehaviorTree 任务的 Rect2i 类型参数。见 BBParam。
BBString
继承:BBParam
用于 BehaviorTree 任务的 String 类型参数。见 BBParam。
BBStringArray
继承:BBParam
用于 BehaviorTree 任务的 StringArray 类型参数。见 BBParam。
BBStringName
继承:BBParam
用于 BehaviorTree 任务的 StringName 类型参数。见 BBParam。
BBTransform2D
继承:BBParam
用于 BehaviorTree 任务的 Transform2D 类型参数。见 BBParam。
BBTransform3D
继承:BBParam
用于 BehaviorTree 任务的 Transform3D 类型参数。见 BBParam。
BBVariant
继承:BBParam
用于 BehaviorTree 任务的 Variant 类型参数。见 BBParam。
说明
面向 BehaviorTree 任务使用的 Variant 类型参数。见 BBParam。
数据类型由 type 指定。
属性
Variant.Type |
|
属性说明
Variant.Type type = 0 🔗
void set_type(value: Variant.Type)
Variant.Type get_type()
为该参数值指定的 Variant.Type。
BBVector2
继承:BBParam
用于 BehaviorTree 任务的 Vector2 类型参数。见 BBParam。
BBVector2Array
继承:BBParam
用于 BehaviorTree 任务的 Vector2Array 类型参数。见 BBParam。
BBVector2i
继承:BBParam
用于 BehaviorTree 任务的 Vector2i 类型参数。见 BBParam。
BBVector3
继承:BBParam
用于 BehaviorTree 任务的 Vector3 类型参数。见 BBParam。
BBVector3Array
继承:BBParam
用于 BehaviorTree 任务的 Vector3Array 类型参数。见 BBParam。
BBVector3i
继承:BBParam
用于 BehaviorTree 任务的 Vector3i 类型参数。见 BBParam。
BBVector4
继承:BBParam
用于 BehaviorTree 任务的 Vector4 类型参数。见 BBParam。
BBVector4i
继承:BBParam
用于 BehaviorTree 任务的 Vector4i 类型参数。见 BBParam。
BehaviorTree
继承:
包含行为树数据。
说明
行为树是一种层次结构,用于建模和控制游戏中智能体(例如角色、敌人、实体)的行为。它旨在让你更轻松地为游戏创建复杂且高度模块化的行为。
行为树由若干任务组成,这些任务代表具体的动作或决策规则。任务大致可分为两大类:控制任务和叶任务。控制任务决定树内的执行流程,包括 BTSequence、BTSelector 和 BTInvert。叶任务代表要执行的具体动作(例如移动或攻击),或是需要检查的条件。BTTask 类为行为树的各种积木块提供了基础。BT 任务可以借助 Blackboard 共享数据。见 BTTask.blackboard 和 Blackboard。
注意:要创建你自己的动作,请继承 BTAction 类。
BehaviorTree 从根任务开始执行,遵循控制任务规定的规则,一路向下直到叶任务 —— 叶任务代表智能体应当执行的实际动作,或应当检查的条件。每个任务在执行时都会返回一个状态,可能是 SUCCESS、RUNNING 或 FAILURE。这些状态决定树的推进方式,它们定义在 Status 中。
行为树通过条件任务处理条件逻辑。这些任务检查特定条件,并根据智能体或其环境的状态返回 SUCCESS 或 FAILURE(例如 “IsLowOnHealth”、“IsTargetInSight”)。条件可以与 BTSequence 和 BTSelector 搭配使用,构建你的决策逻辑。
注意:要创建你自己的条件,请继承 BTCondition 类。
请查阅 BTTask 类,它为行为树的各种积木块提供了基础。
属性
|
|
方法
clone() const |
|
void |
copy_other(other: BehaviorTree) |
get_root_task() const |
|
instantiate(agent: |
|
void |
set_root_task(task: BTTask) |
信号
plan_changed() 🔗
当 BlackboardPlan 发生变化时发出。
属性说明
BlackboardPlan blackboard_plan 🔗
void set_blackboard_plan(value: BlackboardPlan)
BlackboardPlan get_blackboard_plan()
存储并管理用于构建新的 Blackboard 实例的变量。
String description = "" 🔗
void set_description(value:
String)Stringget_description()
用户为 BehaviorTree 提供的描述。
方法说明
BehaviorTree clone() const 🔗
复制一份 BehaviorTree 资源。
void copy_other(other: BehaviorTree) 🔗
变成另一棵行为树的副本。
BTTask get_root_task() const 🔗
返回 BehaviorTree 资源的根任务。
BTInstance instantiate(agent: Node, blackboard: Blackboard, instance_owner: Node, custom_scene_root: Node = null) const 🔗
实例化行为树并返回 BTInstance。instance_owner 应当是拥有该行为树实例的场景节点,通常是 BTPlayer、BTState,或是负责控制行为树执行的自定义播放器节点。请确保传入的 Blackboard 已从 blackboard_plan 填充了值。另见 BlackboardPlan.populate_blackboard 与 BlackboardPlan.create_blackboard。
如果 custom_scene_root 不是 null,它将被用作新实例化的行为树的场景根节点;否则场景根节点会被设为 instance_owner.owner。场景根节点对于 BBNode 实例正常工作至关重要。
void set_root_task(task: BTTask) 🔗
为 BehaviorTree 资源指定一个新的根任务。
BehaviorTreeData
继承:
表示 BehaviorTree 实例的当前状态。
说明
该类被 LimboAI 调试器用于 BehaviorTree 实例数据的序列化与反序列化。
此外,它还可以配合 BehaviorTreeView 可视化 BehaviorTree 实例的当前状态。它的设计用途是在自定义的运行时工具中使用。
方法
create_from_bt_instance(bt_instance: BTInstance) static |
方法说明
BehaviorTreeData create_from_bt_instance(bt_instance: BTInstance) static 🔗
返回编码为 BehaviorTreeData 的 bt_instance 当前状态,适合与 BehaviorTreeView 一起使用。
行为树实例可以通过 BTPlayer.get_bt_instance 获取。
BehaviorTreeView
继承:
可视化 BehaviorTree 实例的当前状态。
说明
可视化 BehaviorTree 实例的当前状态。另见 BehaviorTreeData。
属性
|
|
方法
void |
clear() |
void |
update_tree(behavior_tree_data: BehaviorTreeData) |
信号
task_selected(type_name: String, script_path: String) 🔗
在 BehaviorTreeView 中选中某个任务项时发出。
属性说明
int update_interval_msec = 0 🔗
void set_update_interval_msec(value:
int)intget_update_interval_msec()
两次更新之间的最小延迟(毫秒)。设为更大的值可以降低 CPU 负载。
方法说明
void clear() 🔗
清除树视图。
void update_tree(behavior_tree_data: BehaviorTreeData) 🔗
更新 BehaviorTree 实例的显示。另见 BehaviorTreeData。
BlackboardPlan
继承:
存储并管理用于构建新的 Blackboard 实例的变量。
属性
|
|
方法
create_blackboard(prefetch_root: |
|
get_base_plan() const |
|
|
get_parent_scope_plan_provider() const |
|
is_derived() const |
void |
populate_blackboard(blackboard: Blackboard, overwrite: |
void |
set_base_plan(blackboard_plan: BlackboardPlan) |
void |
set_parent_scope_plan_provider(callable: |
void |
属性说明
bool prefetch_nodepath_vars = true 🔗
void set_prefetch_nodepath_vars(value:
bool)boolis_prefetching_nodepath_vars()
启用或禁用 NodePath 变量预取。如果为 true,在创建 Blackboard 时,NodePath 值会被替换为对应的节点实例。
方法说明
Blackboard create_blackboard(prefetch_root: Node, parent_scope: Blackboard = null, prefetch_root_for_base_plan: Node = null) 🔗
使用该计划构建一个新的 Blackboard 实例。如果启用了 NodePath 预取,将用 prefetch_root 为 NodePath 变量获取节点实例并替换其值。
BlackboardPlan get_base_plan() const 🔗
返回基础计划。见 is_derived。
Callable get_parent_scope_plan_provider() const 🔗
返回父作用域计划提供者 —— 一个返回 BlackboardPlan 的可调用对象。
bool is_derived() const 🔗
如果此计划派生自另一个计划(即基础计划不为 null),则返回 true。派生计划只能包含基础计划中已有的变量,并且只有变量值可以不同。
void populate_blackboard(blackboard: Blackboard, overwrite: bool, prefetch_root: Node, prefetch_root_for_base_plan: Node = null) 🔗
用该计划中的变量填充 blackboard。如果 overwrite 为 true,同名变量将被覆盖。如果启用了 NodePath 预取,将用 prefetch_root 为 NodePath 变量获取节点实例并替换其值。
void set_base_plan(blackboard_plan: BlackboardPlan) 🔗
设置基础计划。一旦指定,该计划将从基础计划派生。
请谨慎使用,它会移除基础计划中不存在的变量。仅用于自定义工具开发。
void set_parent_scope_plan_provider(callable: Callable) 🔗
设置父作用域计划提供者 —— 一个返回 BlackboardPlan 的可调用对象。用于在检视面板中提供提示。设置之后即可使用映射功能。
void sync_with_base_plan() 🔗
将此计划与基础计划同步:移除基础计划中不存在的变量,并更新类型信息。仅用于自定义工具开发。
BT
继承:
被继承:BTTask
BTTask 的基类。
枚举
enum Status: 🔗
Status FRESH = 0
任务尚未执行,或者已被中止并重置。
Status RUNNING = 1
任务正在执行,尚未完成。
Status FAILURE = 2
任务以失败结束。
Status SUCCESS = 3
任务以成功结束。
BTAction
被继承:BTAwaitAnimation、BTCallMethod、BTConsolePrint、BTEvaluateExpression、BTFail、BTPauseAnimation、BTPlayAnimation、BTRandomWait、BTSetAgentProperty、BTSetVar、BTStopAnimation、BTWait、BTWaitTicks
所有 BehaviorTree 动作的基类。
说明
BehaviorTree 中所有动作的基类。你可以通过继承 BTAction 类来创建自己的动作。
表示 BehaviorTree 中智能体应当执行的某个具体行为或动作。动作是 BehaviorTree 层次结构的最底层,负责执行达成目标所需的实际工作。动作没有子任务。
单个动作可以在一个或多个 tick 内完成任务。如果完成任务需要不止一个 tick,该动作应返回 RUNNING 状态。任务完成时,动作返回 SUCCESS 或 FAILURE 来表示结果。
BTAlwaysFail
继承:BTDecorator < BTTask < BT
把 SUCCESS 转换为 FAILURE 的 BT 装饰器。
BTAlwaysSucceed
继承:BTDecorator < BTTask < BT
把 FAILURE 转换为 SUCCESS 的 BT 装饰器。
BTAwaitAnimation
等待动画播放完毕的 BT 动作。
说明
BTAwaitAnimation 动作会等待指定 AnimationPlayer 节点上的动画播放完毕,然后返回 SUCCESS。
如果指定动画已播放完毕,或者指定动画当前未在播放,则返回 SUCCESS。
如果指定动画不存在,或者该动作获取 AnimationPlayer 节点失败,则返回 FAILURE。
属性
|
|
|
|
|
属性说明
StringName animation_name = &"" 🔗
void set_animation_name(value:
StringName)StringNameget_animation_name()
动画在 AnimationPlayer 节点中的键名。
指定 AnimationPlayer 节点的参数。
float max_time = 1.0 🔗
void set_max_time(value:
float)floatget_max_time()
等待动画完成的最长时长(秒)。如果动画在此时间内没有播放完毕,BTAwaitAnimation 会停止等待并返回 SUCCESS。
BTCallMethod
在指定的 Node 或 Object 上调用方法的 BT 动作。
说明
BTCallMethod 动作会在指定的 Node 或 Object 实例上调用 method,然后返回 SUCCESS。
如果该动作在方法执行期间遇到问题,则返回 FAILURE。
属性
Array[BBVariant] |
|
|
|
|
|
|
|
|
|
|
属性说明
调用方法时要传入的实参。
bool args_include_delta = false 🔗
void set_include_delta(value:
bool)boolis_delta_included()
把 delta 作为第一个参数包含进来,并相应地后移其余参数的位置(如果有的话)。
StringName method = &"" 🔗
void set_method(value:
StringName)StringNameget_method()
要调用的方法名。
指定包含要调用方法的 Node 或 Object 实例。
StringName result_var = &"" 🔗
void set_result_var(value:
StringName)StringNameget_result_var()
如果不为空,则把方法调用的结果赋给该属性指定的黑板变量。
BTCheckAgentProperty
继承:BTCondition < BTTask < BT
检查智能体属性值的 BT 条件。
说明
BTCheckAgentProperty 会检查智能体的属性值,并将其与 value 进行比较。
根据 check_type 返回 SUCCESS 或 FAILURE。
属性
|
||
|
|
|
属性说明
要执行的检查类型。
StringName property = &"" 🔗
void set_property(value:
StringName)StringNameget_property()
指定要比较的智能体属性的参数。
指定智能体属性将与之比较的值的参数。
BTCheckTrigger
继承:BTCondition < BTTask < BT
检查触发器(一个布尔变量)的 BT 条件。
说明
BTCheckTrigger 检查 variable 是否被设为 true。如果是,它会把该变量切换为 false 并返回 SUCCESS;否则返回 FAILURE。
BTCheckTrigger 可以在 BTSequence 中充当“门闩”:当触发器变量被设为 true 时,它允许执行后续任务,随后把该变量改为 false。
属性
|
|
属性说明
StringName variable = &"" 🔗
void set_variable(value:
StringName)StringNameget_variable()
黑板上用作触发器的布尔变量。另见 BTTask.blackboard。
如果变量的值为 true,BTCheckTrigger 会把它切换为 false 并返回 SUCCESS。
如果变量的值为 false,BTCheckTrigger 会返回 FAILURE。
BTCheckVar
继承:BTCondition < BTTask < BT
检查黑板上变量的 BT 条件。
说明
BTCheckVar 会把 variable 与 value 进行比较,并根据 check_type 返回 SUCCESS 或 FAILURE。
属性
|
||
|
|
属性说明
要执行的检查类型。
指定 variable 将与之比较的值的参数。
StringName variable = &"" 🔗
void set_variable(value:
StringName)StringNameget_variable()
要检查其值的变量名。
BTComment
BTComment 为 BehaviorTree 添加注解或说明性文字。
说明
BTComment 用于为 BehaviorTree 添加注解或说明性备注。
注释不会作为树的一部分被执行,并且在 BehaviorTree 的运行时实例中会被移除。
BTComposite
被继承:BTDynamicSelector、BTDynamicSequence、BTParallel、BTProbabilitySelector、BTRandomSelector、BTRandomSequence、BTSelector、BTSequence
BT 组合任务的基类。
说明
所有 BehaviorTree 组合任务的基类。你可以通过继承 BTComposite 类来创建自己的组合任务。
组合任务(Composite)是 BehaviorTree 中的一种控制任务,包含一个或多个子任务。它通过规定子任务的执行方式,定义 BehaviorTree 的结构与流程。组合任务可以把相关任务归组为一个单元,让 BehaviorTree 更易管理和维护。BehaviorTree 组合任务的例子包括 BTSelector、BTSequence 和 BTParallel。
BTCondition
被继承:BTCheckAgentProperty、BTCheckTrigger、BTCheckVar
BT 条件的基类。
说明
所有 BehaviorTree 条件的基类。你可以通过继承 BTCondition 类来创建自己的条件。
条件(Condition)是 BehaviorTree 中的一种任务,它在执行后续任务之前检查特定条件。条件常用于组合任务内部以控制执行流程,用来验证环境状态、检查敌人是否存在,或评估智能体的生命值状态。在 BehaviorTree 中使用条件任务可以提高系统效率并避免不必要的动作。不过,它们可能不适合复杂的决策过程,而且条件任务过多会让 BehaviorTree 难以阅读。
条件通常不需要多个 tick 就能完成,会立即返回 SUCCESS 或 FAILURE。
BTConsolePrint
向控制台输出文本的 BT 动作任务。
说明
BTConsolePrint 动作会向控制台输出文本并返回 SUCCESS。它可以包含类似于 GDScript % 运算符的格式化参数占位符。
属性
|
|
|
|
|
属性说明
PackedStringArray bb_format_parameters = PackedStringArray() 🔗
void set_bb_format_parameters(value:
PackedStringArray)PackedStringArrayget_bb_format_parameters()
格式化参数的值会作为将要打印文本的格式化实参。
注意:返回的数组是副本,对它的任何修改都不会更新原始属性值。更多细节见 PackedStringArray。
String text = "" 🔗
void set_text(value:
String)Stringget_text()
要打印的文本,可以包含多个占位符,用于替换为格式化实参。这些占位符遵循与 GDScript % 运算符相同的格式,通常以 ‘%’ 开头并后接格式说明符。例如:%s 表示字符串,%d 表示整数,%f 表示实数。
BTCooldown
继承:BTDecorator < BTTask < BT
只有距上次执行已过去 duration 时间时,才执行其子任务的 BT 装饰器。
说明
只有距上次子任务成功执行已过去 duration 时间时,BTCooldown 才运行其子任务。除非把 trigger_on_failure 设为 true,否则它只考虑成功的执行。
如果子任务结果为 RUNNING,返回 RUNNING。
如果子任务结果为 SUCCESS,返回 SUCCESS,并触发冷却计时器。
如果子任务结果为 FAILURE,或者距上次执行尚未过去 duration 时间,返回 FAILURE。
属性
|
|
|
|
|
|
|
|
|
|
|
|
|
|
属性说明
StringName cooldown_state_var = &"" 🔗
void set_cooldown_state_var(value:
StringName)StringNameget_cooldown_state_var()
用于在 Blackboard 中存储冷却状态的布尔变量。如果留空,该变量会被自动生成并赋值。
如果该变量的值被设为 true,表示冷却已激活。此特性可用于从树的其他部分检查冷却状态,或在 BehaviorTree 的不同部分之间共享它。
float duration = 10.0 🔗
void set_duration(value:
float)floatget_duration()
允许下一次执行子任务之前需要等待的时间。
bool process_pause = false 🔗
void set_process_pause(value:
bool)boolget_process_pause()
如果为 true,则在 SceneTree 暂停时也处理冷却。
bool start_cooled = false 🔗
void set_start_cooled(value:
bool)boolget_start_cooled()
如果为 true,则像子任务在第一次 BT tick 之前已执行过一样开始冷却。
bool trigger_on_failure = false 🔗
void set_trigger_on_failure(value:
bool)boolget_trigger_on_failure()
如果为 true,当子任务结果为 FAILURE 时也会激活冷却。否则,只有子任务结果为 SUCCESS 时才会触发冷却。
BTDecorator
被继承:BTAlwaysFail、BTAlwaysSucceed、BTCooldown、BTDelay、BTForEach、BTInvert、BTNewScope、BTProbability、BTRepeat、BTRepeatUntilFailure、BTRepeatUntilSuccess、BTRunLimit、BTTimeLimit
BT 装饰器的基类。
说明
所有 BehaviorTree 装饰器的基类。你可以通过继承 BTDecorator 类来创建自己的装饰器。
装饰器是 BehaviorTree 中用于改变其子任务行为的一种任务。装饰器只能拥有一个子任务。
装饰器可以为任务的执行添加条件、限制或其他约束。BehaviorTree 装饰器的例子包括 BTInvert、BTRepeat 和 BTCooldown。使用 BehaviorTree 装饰器可以为现有任务添加额外逻辑,从而简化复杂行为的设计与实现。
BTDelay
继承:BTDecorator < BTTask < BT
在执行其子任务之前引入延迟的 BT 装饰器。
说明
BTDelay 在执行其子任务之前引入 seconds 的延迟。在延迟期间返回 RUNNING。
属性
|
|
属性说明
float seconds = 1.0 🔗
void set_seconds(value:
float)floatget_seconds()
延迟时长(秒)。
BTDynamicSelector
继承:BTComposite < BTTask < BT
每个 tick 都从头执行任务、直到出现第一个 SUCCESS 的 BT 组合任务。
说明
BTDynamicSelector 按顺序从第一个到最后一个执行子任务,直到任一子任务返回 SUCCESS。与 BTSelector 不同,它每个 tick 都会从头开始执行任务,重新评估它们的状态。当你希望每个 tick 都重试更高优先级的行为时,它非常有用。
如果某个子任务结果为 RUNNING,返回 RUNNING。BTDynamicSelector 会记住最后一个 RUNNING 的子任务,但与 BTSequence 不同,在下一个执行 tick 中它会重新执行之前的任务并重新评估它们的返回状态。如果之前的任一任务没有返回 FAILURE,它会中止所记住的那个 RUNNING 任务。
如果所有子任务结果都为 FAILURE,返回 FAILURE。
如果某个子任务结果为 SUCCESS,返回 SUCCESS。
BTDynamicSequence
继承:BTComposite < BTTask < BT
每个 tick 都从头执行任务、只要它们返回 SUCCESS 就继续的 BT 组合任务。
说明
BTDynamicSequence 按顺序从第一个到最后一个执行子任务,只要它们返回 SUCCESS 就继续。与 BTSequence 不同,它每个 tick 都会从头开始执行任务,重新评估它们的状态。当你希望在每个 tick 都重新检查某个长时间运行动作之前的条件,并在任一条件结果为 FAILURE 时中止那个 RUNNING 动作时,它非常有用。
如果某个子任务结果为 RUNNING,返回 RUNNING。BTDynamicSequence 会记住最后一个 RUNNING 的子任务,但与 BTSequence 不同,在下一个执行 tick 中它会重新执行之前的任务并重新评估它们的返回状态。如果之前的任一任务没有返回 SUCCESS,它会中止所记住的那个 RUNNING 任务。
如果某个子任务结果为 FAILURE,返回 FAILURE。
如果所有子任务结果都为 SUCCESS,返回 SUCCESS。
BTEvaluateExpression
在指定的 Node 或 Object 上求值 Expression 的 BT 动作。
说明
BTEvaluateExpression 动作会在指定的 Node 或 Object 实例上求值 expression_string,当 Expression 执行成功时返回 SUCCESS。
如果该动作在 Expression 解析或执行期间遇到问题,则返回 FAILURE。
属性
|
|
|
|
|
|
|
|
|
Array[BBVariant] |
|
|
|
|
方法
Error |
parse() |
属性说明
String expression_string = "" 🔗
void set_expression_string(value:
String)Stringget_expression_string()
要解析并执行的表达式字符串。
警告:更新 expression_string 后请调用 parse 来更新内部的 Expression,因为它不会自动更新。
bool input_include_delta = false 🔗
void set_input_include_delta(value:
bool)boolis_input_delta_included()
如果启用,输入变量 delta 会被加入 input_names 和 input_values。
警告:切换 input_include_delta 后请调用 parse 来更新内部的 Expression,因为它不会自动更新。
PackedStringArray input_names = PackedStringArray() 🔗
void set_input_names(value:
PackedStringArray)PackedStringArrayget_input_names()
expression_string 中的变量名列表,用户将通过 input_values 为这些变量提供值。
警告:更新 input_names 后请调用 parse 来更新内部的 Expression,因为它不会自动更新。
注意:返回的数组是副本,对它的任何修改都不会更新原始属性值。更多细节见 PackedStringArray。
Array[BBVariant] input_values = [] 🔗
input_names 中指定变量对应的值列表。这些值通过数组索引与变量一一对应。
指定包含要调用方法的 Node 或 Object 实例。
StringName result_var = &"" 🔗
void set_result_var(value:
StringName)StringNameget_result_var()
如果不为空,则把方法调用的结果赋给该属性指定的黑板变量。
方法说明
Error parse() 🔗
在考虑 input_include_delta 和 input_names 的前提下调用 Expression.parse,并返回其错误码。
BTFail
总是返回 FAILURE 的 BT 动作。
BTForEach
继承:BTDecorator < BTTask < BT
针对 Array 的每个元素执行其子任务的 BT 装饰器。
说明
BTForEach 针对 Array 的每个元素执行其子任务。在每次迭代中,当前元素会被存入指定的 Blackboard 变量中。
如果子任务结果为 RUNNING,或者子任务在非最后一次迭代中结果为 SUCCESS,则返回 RUNNING。
如果子任务结果为 FAILURE,返回 FAILURE。
如果子任务在最后一次迭代中结果为 SUCCESS,返回 SUCCESS。
属性
|
|
|
|
|
属性说明
StringName array_var = &"" 🔗
void set_array_var(value:
StringName)StringNameget_array_var()
Blackboard 中存放 Array 的变量,用于迭代过程。
StringName save_var = &"" 🔗
void set_save_var(value:
StringName)StringNameget_save_var()
用于存储 array_var 所引用数组中某个元素的 Blackboard 变量。
BTInstance
继承:
表示 BehaviorTree 资源的运行时实例。
说明
可以使用 BehaviorTree.instantiate 方法创建。
属性
|
|
方法
|
get_agent() const |
get_blackboard() const |
|
get_last_status() const |
|
|
get_owner_node() const |
get_root_task() const |
|
|
get_source_bt_path() const |
|
is_instance_valid() const |
void |
|
void |
|
update(delta: |
信号
freed() 🔗
当行为树实例被释放时发出。调试器用它来注销实例。
updated(status: int) 🔗
当行为树实例完成更新时发出。
属性说明
bool monitor_performance = false 🔗
void set_monitor_performance(value:
bool)boolget_monitor_performance()
如果为 true,会在编辑器的 “Debugger->Monitors” 中为此实例添加一个性能监视器。
方法说明
Node get_agent() const 🔗
返回行为树实例的智能体。
Blackboard get_blackboard() const 🔗
返回行为树实例的黑板。
Status get_last_status() const 🔗
返回上一次更新的执行状态。
Node get_owner_node() const 🔗
返回拥有此行为树实例的场景 Node。
BTTask get_root_task() const 🔗
返回行为树实例的根任务。
String get_source_bt_path() const 🔗
返回用于创建此实例的行为树资源的文件路径。
bool is_instance_valid() const 🔗
如果行为树实例已正确初始化并可以使用,则返回 true。
void register_with_debugger() 🔗
向调试器注册该行为树实例。
void unregister_with_debugger() 🔗
从调试器注销该行为树实例。通常不需要这样做,因为实例被释放时调试器会自动注销它。
对行为树实例执行一次 tick 并返回其状态。
BTInvert
继承:BTDecorator < BTTask < BT
把 FAILURE 转换为 SUCCESS、把 SUCCESS 转换为 FAILURE 的 BT 装饰器。
说明
BTInvert 把 FAILURE 转换为 SUCCESS、把 SUCCESS 转换为 FAILURE。
BTNewScope
继承:BTDecorator < BTTask < BT
被继承:BTSubtree
创建新 Blackboard 作用域的 BT 装饰器。
说明
BTNewScope 在初始化期间创建一个新的 Blackboard 作用域并向其中填充数据。见 Blackboard。
返回子任务的执行状态。
属性
属性说明
BlackboardPlan blackboard_plan 🔗
void set_blackboard_plan(value: BlackboardPlan)
BlackboardPlan get_blackboard_plan()
存储并管理用于构建新的 Blackboard 实例的变量。
BTParallel
继承:BTComposite < BTTask < BT
同时执行所有子任务的 BT 组合任务。
说明
BTParallel 同时执行其所有子任务。注意 BTParallel 并不涉及多线程:它在同一个 tick 内按顺序从第一个到最后一个处理每个任务,然后返回结果。如果满足任一中止条件,所有当前处于 RUNNING 的任务都会被终止,结果将是 FAILURE 或 SUCCESS 之一。num_failures_required 决定 BTParallel 何时失败,num_successes_required 决定它何时成功。当两者都满足时,它优先考虑 num_failures_required。
如果设为 repeat,每个 tick 都会重新执行所有子任务,无论它们之前的结果是 SUCCESS 还是 FAILURE。
当所需数量的子任务结果为 FAILURE 时返回 FAILURE。当 repeat 设为 false 时,如果没有满足任何条件,且所有子任务的结果都是 SUCCESS 或 FAILURE,BTParallel 将返回 FAILURE。
当所需数量的子任务结果为 SUCCESS 时返回 SUCCESS。
如果没有任何条件被满足,并且 repeat 设为 true 或某个子任务结果为 RUNNING,则返回 RUNNING。
属性
|
|
|
|
|
|
|
|
属性说明
int num_failures_required = 1 🔗
void set_num_failures_required(value:
int)intget_num_failures_required()
如果有指定数量的子任务返回 FAILURE,BTParallel 也会返回 FAILURE。
int num_successes_required = 1 🔗
void set_num_successes_required(value:
int)intget_num_successes_required()
如果有指定数量的子任务返回 SUCCESS,BTParallel 也会返回 SUCCESS。
bool repeat = false 🔗
void set_repeat(value:
bool)boolget_repeat()
为 true 时,子任务会被再次执行,无论它们之前的结果是 SUCCESS 还是 FAILURE。
为 false 时,如果没有满足任何条件,且所有子任务的结果都是 SUCCESS 或 FAILURE,BTParallel 将返回 FAILURE。
BTPauseAnimation
暂停指定 AnimationPlayer 节点上动画播放的 BT 动作。
说明
BTPauseAnimation 动作会暂停指定 AnimationPlayer 节点上的动画播放并返回 SUCCESS。
如果该动作获取 AnimationPlayer 节点失败,则返回 FAILURE。
属性
属性说明
指定 AnimationPlayer 节点的参数。
BTPlayAnimation
在指定 AnimationPlayer 节点上播放动画的 BT 动作。
说明
BTPlayAnimation 动作会在指定的 AnimationPlayer 节点上播放动画。如果 await_completion 大于 0,该动作会等待动画完成,最长等待时间等于 await_completion。
如果动画播放完毕,或者经过的时间超过 await_completion,则返回 SUCCESS。当 await_completion 设为 0 时,BTPlayAnimation 不会等待动画结束,而是立即返回 SUCCESS。
如果动画仍在播放且经过的时间小于 await_completion,则返回 RUNNING。
如果该动作播放所请求的动画失败,则返回 FAILURE。
属性
|
|
|
|
|
|
|
|
|
|
|
|
|
|
属性说明
StringName animation_name = &"" 🔗
void set_animation_name(value:
StringName)StringNameget_animation_name()
动画在 AnimationPlayer 节点中的键名。如果为空,并且 AnimationPlayer 之前被暂停过,BTPlayAnimation 会继续播放上一次播放的动画。
指定 AnimationPlayer 节点的参数。
float await_completion = 0.0 🔗
void set_await_completion(value:
float)floatget_await_completion()
等待动画完成的最长时长(秒)。如果动画在此时间内没有播放完毕,BTPlayAnimation 会停止等待并返回 SUCCESS。
float blend = -1.0 🔗
void set_blend(value:
float)floatget_blend()
自定义混合时间(秒)。见 AnimationPlayer.play。
bool from_end = false 🔗
void set_from_end(value:
bool)boolget_from_end()
从末尾开始播放动画。配合负的 speed 可反向播放动画。见 AnimationPlayer.play。
float speed = 1.0 🔗
void set_speed(value:
float)floatget_speed()
自定义播放速度缩放比例。见 AnimationPlayer.play。
BTProbability
继承:BTDecorator < BTTask < BT
以给定概率执行其子任务的 BT 装饰器。
说明
BTProbability 以 run_chance 定义的给定概率执行其子任务。
如果子任务被执行,返回其结果;否则返回 FAILURE。
属性
|
|
属性说明
float run_chance = 0.5 🔗
void set_run_chance(value:
float)floatget_run_chance()
定义子任务被执行的可能性的概率。
BTProbabilitySelector
继承:BTComposite < BTTask < BT
根据所附加的概率选择要执行的子任务的 BT 组合任务。
说明
BTProbabilitySelector 根据所附加的概率选择要执行的子任务,通常用于决策。概率分布根据分配给每个子任务的权重计算得出。
当某个子任务结果为 SUCCESS 时返回 SUCCESS。
当某个子任务结果为 RUNNING 时返回 RUNNING。
当某个子任务结果为 FAILURE 时,BTProbabilitySelector 的行为取决于 abort_on_failure 的值:
如果 abort_on_failure 为
false,当某个子任务结果为FAILURE时,BTProbabilitySelector 会在剩余子任务上重新归一化概率分布,并选择一个新的子任务来执行。如果所有子任务都失败,该组合任务将返回FAILURE。如果 abort_on_failure 为
true,当某个子任务结果为FAILURE时,BTProbabilitySelector 不会再选择其他子任务执行,而是立即返回FAILURE。
属性
|
|
方法
|
get_probability(child_idx: |
|
get_total_weight() const |
|
get_weight(child_idx: |
|
has_probability(child_idx: |
void |
set_probability(child_idx: |
void |
set_weight(child_idx: |
属性说明
bool abort_on_failure = false 🔗
void set_abort_on_failure(value:
bool)boolget_abort_on_failure()
如果为 true,当某个子任务结果为 FAILURE 时,BTProbabilitySelector 不会再选择其他子任务执行,而是返回 FAILURE。
方法说明
float get_probability(child_idx: int) const 🔗
返回该子任务被选中的概率。
float get_total_weight() const 🔗
返回所有子任务的权重总和。
float get_weight(child_idx: int) const 🔗
返回该子任务在加权概率选择算法中的权重。
bool has_probability(child_idx: int) const 🔗
返回索引为 child_idx 的子任务是否参与加权概率选择算法并分配了概率。对于 BTComment 任务返回 false。
void set_probability(child_idx: int, probability: float) 🔗
根据期望的概率来设置该子任务的权重。
void set_weight(child_idx: int, weight: float) 🔗
为加权概率选择算法设置该子任务的权重。
BTRandomSelector
继承:BTComposite < BTTask < BT
以随机顺序执行任务、直到出现第一个 SUCCESS 的 BT 组合任务。
说明
BTRandomSelector 以随机顺序执行其子任务,直到任一子任务返回 SUCCESS。如果某个子任务结果为 FAILURE,BTRandomSelector 会立即执行另一个子任务,直到其中一个返回 SUCCESS,或者全部结果为 FAILURE。
如果某个子任务结果为 RUNNING,返回 RUNNING。BTRandomSelector 会记住执行顺序以及最后一个返回 RUNNING 的子任务,确保在下一个 tick 从该位置继续。
如果所有子任务结果都为 FAILURE,返回 FAILURE。
如果某个子任务结果为 SUCCESS,返回 SUCCESS。
BTRandomSequence
继承:BTComposite < BTTask < BT
以随机顺序执行任务、只要它们返回 SUCCESS 就继续的 BT 组合任务。
说明
BTRandomSequence 以随机顺序执行其子任务,只要它们返回 SUCCESS 就继续。如果某个子任务结果为 SUCCESS,BTRandomSequence 会立即执行下一个子任务,直到其中一个返回 FAILURE,或者全部结果为 SUCCESS。
如果某个子任务结果为 RUNNING,返回 RUNNING。BTRandomSequence 会记住执行顺序以及最后一个返回 RUNNING 的子任务,确保在下一个 tick 从该位置继续。
如果某个子任务结果为 FAILURE,返回 FAILURE。
如果所有子任务结果都为 SUCCESS,返回 SUCCESS。
BTRandomWait
等待一段随机时长后返回 SUCCESS 的 BT 动作。
说明
BTRandomWait 动作会等待一段随机时长,然后返回 SUCCESS。该时长在指定的范围内随机取值,范围由 min_duration 和 max_duration 定义。
属性
|
|
|
|
|
属性说明
float max_duration = 2.0 🔗
void set_max_duration(value:
float)floatget_max_duration()
等待的最长时长。
float min_duration = 1.0 🔗
void set_min_duration(value:
float)floatget_min_duration()
等待的最短时长。
BTRepeat
继承:BTDecorator < BTTask < BT
把其子任务重复指定 times 次的 BT 装饰器。
说明
BTRepeat 会按 times 定义的次数迭代其子任务。如果 forever 为 true,子任务的执行会无限重复。
如果子任务结果为 RUNNING,返回 RUNNING。如果 forever 为 true,BTRepeat 总是返回 RUNNING。
如果达到指定的成功执行次数,返回 SUCCESS。如果 abort_on_failure 为 false,子任务返回的 FAILURE 状态也被视为一次成功执行。
如果子任务结果为 FAILURE 且 abort_on_failure 为 true,则返回 FAILURE。
属性
|
|
|
|
|
|
|
|
属性说明
bool abort_on_failure = false 🔗
void set_abort_on_failure(value:
bool)boolget_abort_on_failure()
如果为 false,子任务返回的 FAILURE 状态也被视为一次成功执行。
bool forever = false 🔗
void set_forever(value:
bool)boolget_forever()
如果为 true,子任务的执行会无限重复,并总是返回 RUNNING。
int times = 1 🔗
void set_times(value:
int)intget_times()
重复执行子任务的次数。
BTRepeatUntilFailure
继承:BTDecorator < BTTask < BT
重复其子任务直到 FAILURE 的 BT 装饰器。
说明
BTRepeatUntilFailure 重复其子任务,直到结果为 FAILURE。
如果子任务结果为 RUNNING 或 SUCCESS,返回 RUNNING。
如果子任务结果为 FAILURE,返回 SUCCESS。
BTRepeatUntilSuccess
继承:BTDecorator < BTTask < BT
重复其子任务直到 SUCCESS 的 BT 装饰器。
说明
BTRepeatUntilSuccess 重复其子任务,直到结果为 SUCCESS。
如果子任务结果为 RUNNING 或 FAILURE,返回 RUNNING。
如果子任务结果为 SUCCESS,返回 SUCCESS。
BTRunLimit
继承:BTDecorator < BTTask < BT
限制其子任务执行次数的 BT 装饰器。
说明
BTRunLimit 把子任务的执行次数限制在 run_limit 定义的最大次数以内。
如果执行次数超出限制,返回 FAILURE;否则返回子任务的状态。
属性
|
||
|
|
枚举
enum CountPolicy: 🔗
CountPolicy COUNT_SUCCESSFUL = 0
只把成功的运行计入限制。
CountPolicy COUNT_FAILED = 1
只把失败的运行计入限制。
CountPolicy COUNT_ALL = 2
把成功和失败的运行都计入限制。
属性说明
CountPolicy count_policy = 0 🔗
void set_count_policy(value: CountPolicy)
CountPolicy get_count_policy()
哪些运行应计入限制:成功的、失败的,还是全部?
int run_limit = 1 🔗
void set_run_limit(value:
int)intget_run_limit()
允许子任务执行的最大次数。
BTSelector
继承:BTComposite < BTTask < BT
顺序执行任务、直到出现第一个 SUCCESS 的 BT 组合任务。
说明
BTSelector 按顺序从第一个到最后一个执行子任务,直到任一子任务返回 SUCCESS。如果某个子任务结果为 FAILURE,BTSelector 会立即执行下一个子任务,直到其中一个返回 SUCCESS,或者全部返回 FAILURE。BTSelector 与 BTSequence 是行为树中最常见的两种积木块。本质上,BTSequence 类似布尔 AND 运算,而 BTSelector 类似布尔 OR 运算。选择器让行为树能够响应环境变化,并在各种后备行为之间触发转换。
如果某个子任务结果为 RUNNING,返回 RUNNING。BTSelector 会记住最后一个返回 RUNNING 的子任务,确保在下一个执行 tick 从该位置继续。
如果某个子任务结果为 SUCCESS,返回 SUCCESS。
如果所有子任务结果都为 FAILURE,返回 FAILURE。
BTSequence
继承:BTComposite < BTTask < BT
顺序执行任务、只要它们返回 SUCCESS 就继续的 BT 组合任务。
说明
BTSequence 按顺序从第一个到最后一个执行子任务,只要它们返回 SUCCESS 就继续。如果某个子任务结果为 SUCCESS,BTSequence 会立即执行下一个子任务,直到其中一个返回 FAILURE,或者全部返回 SUCCESS。BTSequence 与 BTSelector 是行为树中最常见的两种积木块。本质上,BTSelector 类似布尔 OR 运算,而 BTSequence 类似布尔 AND 运算。序列让行为树能够把一串更简单的任务组合成复杂行为。
如果任一子任务结果为 RUNNING,返回 RUNNING。BTSequence 会记住最后一个返回 RUNNING 的子任务,确保在下一个执行 tick 从该位置继续。
如果所有子任务结果都为 SUCCESS,返回 SUCCESS。
如果某个子任务结果为 FAILURE,返回 FAILURE。
BTSetAgentProperty
为指定的智能体属性赋值的 BT 动作。
说明
BTSetAgentProperty 把指定的 value 赋给由 property 标识的智能体属性并返回 SUCCESS。可选地,它可以在赋值之前执行特定的 operation。
如果设置该属性失败,则返回 FAILURE。
属性
|
||
|
|
|
属性说明
指定赋值之前要执行的操作。操作的执行方式如下:
property = property OPERATION value
StringName property = &"" 🔗
void set_property(value:
StringName)StringNameget_property()
指定智能体属性名的参数。
指定将要赋给智能体属性的值的参数。
BTSetVar
把 value 赋给 variable,然后返回 SUCCESS 的 BT 动作。
说明
BTSetVar 把 value 赋给 variable,然后返回 SUCCESS。可选地,它可以在赋值之前执行特定的 operation。
如果设置 variable 失败,则返回 FAILURE。
属性
|
||
|
|
属性说明
指定赋值之前要执行的操作。操作的执行方式如下:
variable = variable OPERATION value
指定将要赋给该变量的值的参数。
StringName variable = &"" 🔗
void set_variable(value:
StringName)StringNameget_variable()
将要被赋值的变量名。
BTStopAnimation
停止指定 AnimationPlayer 节点上动画播放的 BT 动作。
说明
BTStopAnimation 动作会停止指定 AnimationPlayer 节点上的动画播放并返回 SUCCESS。如果设置了 animation_name,则只有当指定动画正在播放时才会停止播放。
如果该动作获取 AnimationPlayer 节点失败,则返回 FAILURE。
属性
|
|
|
|
|
属性说明
StringName animation_name = &"" 🔗
void set_animation_name(value:
StringName)StringNameget_animation_name()
动画在 AnimationPlayer 节点中的键名。如果不为空,则只有当指定动画正在播放时 BTStopAnimation 才会停止播放。
指定 AnimationPlayer 节点的参数。
bool keep_state = false 🔗
void set_keep_state(value:
bool)boolget_keep_state()
如果为 true,动画状态不会在视觉上被更新。
BTSubtree
继承:BTNewScope < BTDecorator < BTTask < BT
在更大的树中实例化并运行子树的 BT 装饰器。
说明
BTSubtree 会实例化一个 BehaviorTree,在初始化期间把它的根任务作为子任务加入,同时创建一个新的 Blackboard 作用域。
返回子树执行的状态。
子树的黑板变量可以映射到主树黑板计划的变量。请查看检视面板中的映射(mapping)部分。
注意:BTSubTree 被设计为一个更简单的加载器,不支持在运行时更新 subtree。自定义的子树装饰器更适合这种需求:
extends BTDecorator
## MyCustomBranch
func _setup() -> void:
var bt: BehaviorTree = load("res://...")
var my_branch: BTTask = bt.get_root_task().clone()
my_branch.initialize(agent, blackboard)
add_child(my_branch)
func _tick(delta) -> Status:
var child: BTTask = get_child(0)
return child.execute(delta)
这样 BehaviorTree 就能从黑板中的某个变量或其他位置加载指定的行为树,并在运行时使用那棵新的行为树。
属性
属性说明
BehaviorTree subtree 🔗
void set_subtree(value: BehaviorTree)
BehaviorTree get_subtree()
将被实例化为子树的 BehaviorTree 资源。
BTTimeLimit
继承:BTDecorator < BTTask < BT
为其子任务执行设置时间限制的 BT 装饰器。
说明
BTTimeLimit 为子任务的执行分配有限的时间;如果超过 time_limit,它会中止子任务并返回 FAILURE。
如果超过 time_limit,返回 FAILURE;否则返回子任务的状态。
属性
|
|
属性说明
float time_limit = 5.0 🔗
void set_time_limit(value:
float)floatget_time_limit()
分配给子任务执行的时间。
BTWait
等待指定 duration 时间后返回 SUCCESS 的 BT 动作。
属性
|
|
属性说明
float duration = 1.0 🔗
void set_duration(value:
float)floatget_duration()
该属性目前还没有描述。欢迎贡献一份描述!
BTWaitTicks
等待指定数量的 tick 后返回 SUCCESS 的 BT 动作。
属性
|
|
属性说明
int num_ticks = 1 🔗
void set_num_ticks(value:
int)intget_num_ticks()
返回 SUCCESS 之前需要等待的 tick 数。
LimboUtility
继承:
LimboAI 的辅助函数。
方法
|
decorate_output_var(variable: |
|
decorate_var(variable: |
|
get_check_operator_string(check: CheckType) const |
|
get_operation_string(operation: Operation) const |
|
get_status_name(status: |
|
get_task_icon(class_or_script_path: |
|
perform_check(check: CheckType, a: |
|
perform_operation(operation: Operation, a: |
枚举
enum CheckType: 🔗
CheckType CHECK_EQUAL = 0
相等性检查。
CheckType CHECK_LESS_THAN = 1
小于检查。
CheckType CHECK_LESS_THAN_OR_EQUAL = 2
小于或等于检查。
CheckType CHECK_GREATER_THAN = 3
大于检查。
CheckType CHECK_GREATER_THAN_OR_EQUAL = 4
大于或等于检查。
CheckType CHECK_NOT_EQUAL = 5
不等性检查。
enum Operation: 🔗
Operation OPERATION_NONE = 0
无操作。
Operation OPERATION_ADDITION = 1
算术加法。
Operation OPERATION_SUBTRACTION = 2
算术减法。
Operation OPERATION_MULTIPLICATION = 3
算术乘法。
Operation OPERATION_DIVISION = 4
算术除法。
Operation OPERATION_MODULO = 5
取整数除法的余数。
Operation OPERATION_POWER = 6
把 a 自乘 b 次。
Operation OPERATION_BIT_SHIFT_LEFT = 7
按位左移。
Operation OPERATION_BIT_SHIFT_RIGHT = 8
按位右移。
Operation OPERATION_BIT_AND = 9
按位与。
Operation OPERATION_BIT_OR = 10
按位或。
Operation OPERATION_BIT_XOR = 11
按位异或。
方法说明
String decorate_output_var(variable: String) const 🔗
与 decorate_var 类似,生成一个经格式化、用于显示的 Blackboard 变量名字符串,并额外添加一个符号来表明该变量被用作输出。
String decorate_var(variable: String) const 🔗
生成一个经格式化、适合显示或控制台输出的 Blackboard 变量名字符串。
String get_check_operator_string(check: CheckType) const 🔗
返回 CheckType 枚举值对应的运算符字符串。例如,CHECK_EQUAL 返回 “==”。
String get_operation_string(operation: Operation) const 🔗
返回 Operation 枚举值的字符串表示。
String get_status_name(status: int) const 🔗
返回 BTTask 状态码的名称。
Texture2D get_task_icon(class_or_script_path: String) const 🔗
根据任务的类名或脚本资源路径,返回与之关联的图标纹理。
bool perform_check(check: CheckType, a: Variant, b: Variant) 🔗
对两个值 a 和 b 执行 check,如果检查通过则返回 true。
Variant perform_operation(operation: Operation, a: Variant, b: Variant) 🔗
对两个值 a 和 b 执行 operation,并返回结果。