Compare commits
No commits in common. "8b2770116d57d0bd570013937ea46c108c48a192" and "a2a62f636bce1d1a94ece34739ffc7db889f7c60" have entirely different histories.
8b2770116d
...
a2a62f636b
|
@ -25,7 +25,7 @@ void BBVariable::set_value(const Variant &p_value) {
|
||||||
data->value_changed = true;
|
data->value_changed = true;
|
||||||
|
|
||||||
if (is_bound()) {
|
if (is_bound()) {
|
||||||
Object *obj = OBJECT_DB_GET_INSTANCE(data->bound_object);
|
Object *obj = ObjectDB::get_instance(ObjectID(data->bound_object));
|
||||||
ERR_FAIL_COND_MSG(!obj, "Blackboard: Failed to get bound object.");
|
ERR_FAIL_COND_MSG(!obj, "Blackboard: Failed to get bound object.");
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
bool r_valid;
|
bool r_valid;
|
||||||
|
@ -39,7 +39,7 @@ void BBVariable::set_value(const Variant &p_value) {
|
||||||
|
|
||||||
Variant BBVariable::get_value() const {
|
Variant BBVariable::get_value() const {
|
||||||
if (is_bound()) {
|
if (is_bound()) {
|
||||||
Object *obj = OBJECT_DB_GET_INSTANCE(data->bound_object);
|
Object *obj = ObjectDB::get_instance(ObjectID(data->bound_object));
|
||||||
ERR_FAIL_COND_V_MSG(!obj, data->value, "Blackboard: Failed to get bound object.");
|
ERR_FAIL_COND_V_MSG(!obj, data->value, "Blackboard: Failed to get bound object.");
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
bool r_valid;
|
bool r_valid;
|
||||||
|
|
|
@ -77,16 +77,13 @@ void BehaviorTree::copy_other(const Ref<BehaviorTree> &p_other) {
|
||||||
root_task = p_other->get_root_task();
|
root_task = p_other->get_root_task();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BTInstance> BehaviorTree::instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_instance_owner) const {
|
Ref<BTTask> BehaviorTree::instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) const {
|
||||||
ERR_FAIL_COND_V_MSG(root_task == nullptr, nullptr, "BehaviorTree: Instantiation failed - BT has no valid root task.");
|
ERR_FAIL_COND_V_MSG(root_task == nullptr, memnew(BTTask), "Trying to instance a behavior tree with no valid root task.");
|
||||||
ERR_FAIL_NULL_V_MSG(p_agent, nullptr, "BehaviorTree: Instantiation failed - agent can't be null.");
|
ERR_FAIL_NULL_V_MSG(p_agent, memnew(BTTask), "Trying to instance a behavior tree with no valid agent.");
|
||||||
ERR_FAIL_NULL_V_MSG(p_instance_owner, nullptr, "BehaviorTree: Instantiation failed -- instance owner can't be null.");
|
ERR_FAIL_NULL_V_MSG(p_scene_root, memnew(BTTask), "Trying to instance a behavior tree with no valid scene root.");
|
||||||
ERR_FAIL_NULL_V_MSG(p_blackboard, nullptr, "BehaviorTree: Instantiation failed - blackboard can't be null.");
|
Ref<BTTask> inst = root_task->clone();
|
||||||
Node *scene_root = p_instance_owner->get_owner();
|
inst->initialize(p_agent, p_blackboard, p_scene_root);
|
||||||
ERR_FAIL_NULL_V_MSG(scene_root, nullptr, "BehaviorTree: Instantiation failed - can't get scene root, because instance_owner not owned by a scene node. Hint: Try my_player.set_owner(get_owner()).");
|
return inst;
|
||||||
Ref<BTTask> root_copy = root_task->clone();
|
|
||||||
root_copy->initialize(p_agent, p_blackboard, scene_root);
|
|
||||||
return BTInstance::create(root_copy, get_path(), p_instance_owner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BehaviorTree::_plan_changed() {
|
void BehaviorTree::_plan_changed() {
|
||||||
|
@ -119,7 +116,7 @@ void BehaviorTree::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_root_task"), &BehaviorTree::get_root_task);
|
ClassDB::bind_method(D_METHOD("get_root_task"), &BehaviorTree::get_root_task);
|
||||||
ClassDB::bind_method(D_METHOD("clone"), &BehaviorTree::clone);
|
ClassDB::bind_method(D_METHOD("clone"), &BehaviorTree::clone);
|
||||||
ClassDB::bind_method(D_METHOD("copy_other", "other"), &BehaviorTree::copy_other);
|
ClassDB::bind_method(D_METHOD("copy_other", "other"), &BehaviorTree::copy_other);
|
||||||
ClassDB::bind_method(D_METHOD("instantiate", "agent", "blackboard", "instance_owner"), &BehaviorTree::instantiate);
|
ClassDB::bind_method(D_METHOD("instantiate", "agent", "blackboard", "scene_root"), &BehaviorTree::instantiate);
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "description", PROPERTY_HINT_MULTILINE_TEXT), "set_description", "get_description");
|
ADD_PROPERTY(PropertyInfo(Variant::STRING, "description", PROPERTY_HINT_MULTILINE_TEXT), "set_description", "get_description");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard_plan", PROPERTY_HINT_RESOURCE_TYPE, "BlackboardPlan", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_blackboard_plan", "get_blackboard_plan");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard_plan", PROPERTY_HINT_RESOURCE_TYPE, "BlackboardPlan", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_blackboard_plan", "get_blackboard_plan");
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#define BEHAVIOR_TREE_H
|
#define BEHAVIOR_TREE_H
|
||||||
|
|
||||||
#include "../blackboard/blackboard_plan.h"
|
#include "../blackboard/blackboard_plan.h"
|
||||||
#include "bt_instance.h"
|
|
||||||
#include "tasks/bt_task.h"
|
#include "tasks/bt_task.h"
|
||||||
|
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
|
@ -59,7 +58,7 @@ public:
|
||||||
|
|
||||||
Ref<BehaviorTree> clone() const;
|
Ref<BehaviorTree> clone() const;
|
||||||
void copy_other(const Ref<BehaviorTree> &p_other);
|
void copy_other(const Ref<BehaviorTree> &p_other);
|
||||||
Ref<BTInstance> instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_instance_owner) const;
|
Ref<BTTask> instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) const;
|
||||||
|
|
||||||
BehaviorTree();
|
BehaviorTree();
|
||||||
~BehaviorTree();
|
~BehaviorTree();
|
||||||
|
|
|
@ -1,154 +0,0 @@
|
||||||
/**
|
|
||||||
* bt_instance.cpp
|
|
||||||
* =============================================================================
|
|
||||||
* Copyright 2021-2024 Serhii Snitsaruk
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style
|
|
||||||
* license that can be found in the LICENSE file or at
|
|
||||||
* https://opensource.org/licenses/MIT.
|
|
||||||
* =============================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "bt_instance.h"
|
|
||||||
|
|
||||||
#include "../editor/debugger/limbo_debugger.h"
|
|
||||||
#include "behavior_tree.h"
|
|
||||||
|
|
||||||
#ifdef LIMBOAI_MODULE
|
|
||||||
#include "core/os/time.h"
|
|
||||||
#include "main/performance.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef LIMBOAI_GDEXTENSION
|
|
||||||
#include <godot_cpp/classes/performance.hpp>
|
|
||||||
#include <godot_cpp/classes/time.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Ref<BTInstance> BTInstance::create(Ref<BTTask> p_root_task, String p_source_bt_path, Node *p_owner_node) {
|
|
||||||
ERR_FAIL_NULL_V(p_root_task, nullptr);
|
|
||||||
ERR_FAIL_NULL_V(p_owner_node, nullptr);
|
|
||||||
Ref<BTInstance> inst;
|
|
||||||
inst.instantiate();
|
|
||||||
inst->root_task = p_root_task;
|
|
||||||
inst->owner_node_id = p_owner_node->get_instance_id();
|
|
||||||
inst->source_bt_path = p_source_bt_path;
|
|
||||||
return inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
BT::Status BTInstance::update(double p_delta) {
|
|
||||||
ERR_FAIL_COND_V(!root_task.is_valid(), BT::FRESH);
|
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
double start = Time::get_singleton()->get_ticks_usec();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
last_status = root_task->execute(p_delta);
|
|
||||||
emit_signal(LimboStringNames::get_singleton()->updated, last_status);
|
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
double end = Time::get_singleton()->get_ticks_usec();
|
|
||||||
update_time_acc += (end - start);
|
|
||||||
update_time_n += 1.0;
|
|
||||||
#endif
|
|
||||||
return last_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BTInstance::set_monitor_performance(bool p_monitor) {
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
monitor_performance = p_monitor;
|
|
||||||
if (monitor_performance) {
|
|
||||||
_add_custom_monitor();
|
|
||||||
} else {
|
|
||||||
_remove_custom_monitor();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BTInstance::get_monitor_performance() const {
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
return monitor_performance;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void BTInstance::register_with_debugger() {
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if (LimboDebugger::get_singleton()->is_active()) {
|
|
||||||
LimboDebugger::get_singleton()->register_bt_instance(get_instance_id());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void BTInstance::unregister_with_debugger() {
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if (LimboDebugger::get_singleton()->is_active()) {
|
|
||||||
LimboDebugger::get_singleton()->unregister_bt_instance(get_instance_id());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
|
|
||||||
double BTInstance::_get_mean_update_time_msec_and_reset() {
|
|
||||||
if (update_time_n) {
|
|
||||||
double mean_time_msec = (update_time_acc * 0.001) / update_time_n;
|
|
||||||
update_time_acc = 0.0;
|
|
||||||
update_time_n = 0.0;
|
|
||||||
return mean_time_msec;
|
|
||||||
}
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BTInstance::_add_custom_monitor() {
|
|
||||||
ERR_FAIL_NULL(get_owner_node());
|
|
||||||
ERR_FAIL_NULL(root_task);
|
|
||||||
ERR_FAIL_NULL(root_task->get_agent());
|
|
||||||
|
|
||||||
if (monitor_id == StringName()) {
|
|
||||||
monitor_id = vformat("LimboAI/update_ms|%s_%s_%s", root_task->get_agent()->get_name(), get_owner_node()->get_name(),
|
|
||||||
String(itos(get_instance_id())).md5_text().substr(0, 4));
|
|
||||||
}
|
|
||||||
if (!Performance::get_singleton()->has_custom_monitor(monitor_id)) {
|
|
||||||
PERFORMANCE_ADD_CUSTOM_MONITOR(monitor_id, callable_mp(this, &BTInstance::_get_mean_update_time_msec_and_reset));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BTInstance::_remove_custom_monitor() {
|
|
||||||
if (monitor_id != StringName() && Performance::get_singleton()->has_custom_monitor(monitor_id)) {
|
|
||||||
Performance::get_singleton()->remove_custom_monitor(monitor_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // * DEBUG_ENABLED
|
|
||||||
|
|
||||||
void BTInstance::_bind_methods() {
|
|
||||||
ClassDB::bind_method(D_METHOD("get_root_task"), &BTInstance::get_root_task);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_owner_node"), &BTInstance::get_owner_node);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_last_status"), &BTInstance::get_last_status);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_source_bt_path"), &BTInstance::get_source_bt_path);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_agent"), &BTInstance::get_agent);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_blackboard"), &BTInstance::get_blackboard);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("is_instance_valid"), &BTInstance::is_instance_valid);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_monitor_performance", "monitor"), &BTInstance::set_monitor_performance);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_monitor_performance"), &BTInstance::get_monitor_performance);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("update", "delta"), &BTInstance::update);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("register_with_debugger"), &BTInstance::register_with_debugger);
|
|
||||||
ClassDB::bind_method(D_METHOD("unregister_with_debugger"), &BTInstance::unregister_with_debugger);
|
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitor_performance"), "set_monitor_performance", "get_monitor_performance");
|
|
||||||
|
|
||||||
ADD_SIGNAL(MethodInfo("updated", PropertyInfo(Variant::INT, "status")));
|
|
||||||
ADD_SIGNAL(MethodInfo("freed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
BTInstance::~BTInstance() {
|
|
||||||
emit_signal(LW_NAME(freed));
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
_remove_custom_monitor();
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
/**
|
|
||||||
* bt_instance.h
|
|
||||||
* =============================================================================
|
|
||||||
* Copyright 2021-2024 Serhii Snitsaruk
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by an MIT-style
|
|
||||||
* license that can be found in the LICENSE file or at
|
|
||||||
* https://opensource.org/licenses/MIT.
|
|
||||||
* =============================================================================
|
|
||||||
*/
|
|
||||||
#ifndef BT_INSTANCE_H
|
|
||||||
#define BT_INSTANCE_H
|
|
||||||
|
|
||||||
#include "tasks/bt_task.h"
|
|
||||||
|
|
||||||
class BTInstance : public RefCounted {
|
|
||||||
GDCLASS(BTInstance, RefCounted);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ref<BTTask> root_task;
|
|
||||||
uint64_t owner_node_id = 0;
|
|
||||||
String source_bt_path;
|
|
||||||
BT::Status last_status = BT::FRESH;
|
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
bool monitor_performance = false;
|
|
||||||
StringName monitor_id;
|
|
||||||
double update_time_acc = 0.0;
|
|
||||||
double update_time_n = 0.0;
|
|
||||||
|
|
||||||
double _get_mean_update_time_msec_and_reset();
|
|
||||||
void _add_custom_monitor();
|
|
||||||
void _remove_custom_monitor();
|
|
||||||
|
|
||||||
#endif // * DEBUG_ENABLED
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static void _bind_methods();
|
|
||||||
|
|
||||||
public:
|
|
||||||
_FORCE_INLINE_ Ref<BTTask> get_root_task() const { return root_task; }
|
|
||||||
_FORCE_INLINE_ Node *get_owner_node() const { return owner_node_id ? Object::cast_to<Node>(OBJECT_DB_GET_INSTANCE(owner_node_id)) : nullptr; }
|
|
||||||
_FORCE_INLINE_ BT::Status get_last_status() const { return last_status; }
|
|
||||||
_FORCE_INLINE_ String get_source_bt_path() const { return source_bt_path; }
|
|
||||||
_FORCE_INLINE_ Node *get_agent() const { return root_task.is_valid() ? root_task->get_agent() : nullptr; }
|
|
||||||
_FORCE_INLINE_ Ref<Blackboard> get_blackboard() const { return root_task.is_valid() ? root_task->get_blackboard() : Ref<Blackboard>(); }
|
|
||||||
|
|
||||||
_FORCE_INLINE_ bool is_instance_valid() const { return root_task.is_valid(); }
|
|
||||||
|
|
||||||
BT::Status update(double p_delta);
|
|
||||||
|
|
||||||
void set_monitor_performance(bool p_monitor);
|
|
||||||
bool get_monitor_performance() const;
|
|
||||||
|
|
||||||
void register_with_debugger();
|
|
||||||
void unregister_with_debugger();
|
|
||||||
|
|
||||||
static Ref<BTInstance> create(Ref<BTTask> p_root_task, String p_source_bt_path, Node *p_owner_node);
|
|
||||||
|
|
||||||
BTInstance() = default;
|
|
||||||
~BTInstance();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BT_INSTANCE_H
|
|
124
bt/bt_player.cpp
124
bt/bt_player.cpp
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "bt_player.h"
|
#include "bt_player.h"
|
||||||
|
|
||||||
|
#include "../editor/debugger/limbo_debugger.h"
|
||||||
#include "../util/limbo_compat.h"
|
#include "../util/limbo_compat.h"
|
||||||
#include "../util/limbo_string_names.h"
|
#include "../util/limbo_string_names.h"
|
||||||
|
|
||||||
|
@ -43,19 +44,24 @@
|
||||||
VARIANT_ENUM_CAST(BTPlayer::UpdateMode);
|
VARIANT_ENUM_CAST(BTPlayer::UpdateMode);
|
||||||
|
|
||||||
void BTPlayer::_load_tree() {
|
void BTPlayer::_load_tree() {
|
||||||
bt_instance.unref();
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
|
||||||
|
LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
tree_instance.unref();
|
||||||
ERR_FAIL_COND_MSG(!behavior_tree.is_valid(), "BTPlayer: Initialization failed - needs a valid behavior tree.");
|
ERR_FAIL_COND_MSG(!behavior_tree.is_valid(), "BTPlayer: Initialization failed - needs a valid behavior tree.");
|
||||||
ERR_FAIL_COND_MSG(!behavior_tree->get_root_task().is_valid(), "BTPlayer: Initialization failed - behavior tree has no valid root task.");
|
ERR_FAIL_COND_MSG(!behavior_tree->get_root_task().is_valid(), "BTPlayer: Initialization failed - behavior tree has no valid root task.");
|
||||||
Node *agent = GET_NODE(this, agent_node);
|
Node *agent = GET_NODE(this, agent_node);
|
||||||
ERR_FAIL_NULL_MSG(agent, vformat("BTPlayer: Initialization failed - can't get agent with path '%s'.", agent_node));
|
ERR_FAIL_NULL_MSG(agent, vformat("BTPlayer: Initialization failed - can't get agent with path '%s'.", agent_node));
|
||||||
Node *scene_root = get_owner();
|
Node *scene_root = get_owner();
|
||||||
ERR_FAIL_NULL_MSG(scene_root, "BTPlayer: Initialization failed - can't get scene root (make sure the BTPlayer's owner property is set).");
|
ERR_FAIL_NULL_MSG(scene_root, "BTPlayer: Initialization failed - can't get scene root (make sure the BTPlayer's owner property is set).");
|
||||||
bt_instance = behavior_tree->instantiate(agent, blackboard, this);
|
tree_instance = behavior_tree->instantiate(agent, blackboard, scene_root);
|
||||||
ERR_FAIL_COND_MSG(bt_instance.is_null(), "BTPlayer: Failed to instantiate behavior tree.");
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
bt_instance->set_monitor_performance(monitor_performance);
|
if (IS_DEBUGGER_ACTIVE()) {
|
||||||
bt_instance->register_with_debugger();
|
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
|
||||||
#endif // DEBUG_ENABLED
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTPlayer::_update_blackboard_plan() {
|
void BTPlayer::_update_blackboard_plan() {
|
||||||
|
@ -69,18 +75,6 @@ void BTPlayer::_update_blackboard_plan() {
|
||||||
blackboard_plan->set_base_plan(behavior_tree.is_valid() ? behavior_tree->get_blackboard_plan() : nullptr);
|
blackboard_plan->set_base_plan(behavior_tree.is_valid() ? behavior_tree->get_blackboard_plan() : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTPlayer::set_bt_instance(const Ref<BTInstance> &p_bt_instance) {
|
|
||||||
ERR_FAIL_COND_MSG(p_bt_instance.is_null(), "BTPlayer: Failed to set behavior tree instance - instance is null.");
|
|
||||||
ERR_FAIL_COND_MSG(!p_bt_instance->is_instance_valid(), "BTPlayer: Failed to set behavior tree instance - instance is not valid.");
|
|
||||||
|
|
||||||
bt_instance = p_bt_instance;
|
|
||||||
blackboard = p_bt_instance->get_blackboard();
|
|
||||||
agent_node = p_bt_instance->get_agent()->get_path();
|
|
||||||
|
|
||||||
blackboard_plan.unref();
|
|
||||||
behavior_tree.unref();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BTPlayer::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
|
void BTPlayer::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
if (behavior_tree.is_valid() && behavior_tree->is_connected(LW_NAME(plan_changed), callable_mp(this, &BTPlayer::_update_blackboard_plan))) {
|
if (behavior_tree.is_valid() && behavior_tree->is_connected(LW_NAME(plan_changed), callable_mp(this, &BTPlayer::_update_blackboard_plan))) {
|
||||||
|
@ -93,7 +87,7 @@ void BTPlayer::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
|
||||||
_update_blackboard_plan();
|
_update_blackboard_plan();
|
||||||
} else {
|
} else {
|
||||||
behavior_tree = p_tree;
|
behavior_tree = p_tree;
|
||||||
if (get_owner() && is_inside_tree()) {
|
if (get_owner()) {
|
||||||
_load_tree();
|
_load_tree();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +95,7 @@ void BTPlayer::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
|
||||||
|
|
||||||
void BTPlayer::set_agent_node(const NodePath &p_agent_node) {
|
void BTPlayer::set_agent_node(const NodePath &p_agent_node) {
|
||||||
agent_node = p_agent_node;
|
agent_node = p_agent_node;
|
||||||
if (bt_instance.is_valid()) {
|
if (tree_instance.is_valid()) {
|
||||||
ERR_PRINT("BTPlayer: Agent node cannot be set after the behavior tree is instantiated. This change will not affect the behavior tree instance.");
|
ERR_PRINT("BTPlayer: Agent node cannot be set after the behavior tree is instantiated. This change will not affect the behavior tree instance.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,25 +119,33 @@ void BTPlayer::set_active(bool p_active) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTPlayer::update(double p_delta) {
|
void BTPlayer::update(double p_delta) {
|
||||||
if (!bt_instance.is_valid()) {
|
if (!tree_instance.is_valid()) {
|
||||||
ERR_PRINT_ONCE(vformat("BTPlayer doesn't have a behavior tree with a valid root task to execute (owner: %s)", get_owner()));
|
ERR_PRINT_ONCE(vformat("BTPlayer doesn't have a behavior tree with a valid root task to execute (owner: %s)", get_owner()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
double start = GET_TICKS_USEC();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (active) {
|
if (active) {
|
||||||
BT::Status status = bt_instance->update(p_delta);
|
last_status = tree_instance->execute(p_delta);
|
||||||
emit_signal(LW_NAME(updated), status);
|
emit_signal(LimboStringNames::get_singleton()->updated, last_status);
|
||||||
#ifndef DISABLE_DEPRECATED
|
if (last_status == BTTask::SUCCESS || last_status == BTTask::FAILURE) {
|
||||||
if (status == BTTask::SUCCESS || status == BTTask::FAILURE) {
|
emit_signal(LimboStringNames::get_singleton()->behavior_tree_finished, last_status);
|
||||||
emit_signal(LW_NAME(behavior_tree_finished), status);
|
|
||||||
}
|
|
||||||
#endif // DISABLE_DEPRECATED
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
double end = GET_TICKS_USEC();
|
||||||
|
update_time_acc += (end - start);
|
||||||
|
update_time_n += 1.0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void BTPlayer::restart() {
|
void BTPlayer::restart() {
|
||||||
ERR_FAIL_COND_MSG(bt_instance.is_null(), "BTPlayer: Restart failed - no valid tree instance. Make sure the BTPlayer has a valid behavior tree with a valid root task.");
|
ERR_FAIL_COND_MSG(tree_instance.is_null(), "BTPlayer: Restart failed - no valid tree instance. Make sure the BTPlayer has a valid behavior tree with a valid root task.");
|
||||||
bt_instance->get_root_task()->abort();
|
tree_instance->abort();
|
||||||
set_active(true);
|
set_active(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,9 +154,42 @@ void BTPlayer::restart() {
|
||||||
void BTPlayer::_set_monitor_performance(bool p_monitor_performance) {
|
void BTPlayer::_set_monitor_performance(bool p_monitor_performance) {
|
||||||
monitor_performance = p_monitor_performance;
|
monitor_performance = p_monitor_performance;
|
||||||
|
|
||||||
if (bt_instance.is_valid()) {
|
if (!get_owner() && monitor_performance) {
|
||||||
bt_instance->set_monitor_performance(monitor_performance);
|
// Don't add custom monitor if not in scene.
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (monitor_performance) {
|
||||||
|
_add_custom_monitor();
|
||||||
|
} else {
|
||||||
|
_remove_custom_monitor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTPlayer::_add_custom_monitor() {
|
||||||
|
if (monitor_id == StringName()) {
|
||||||
|
monitor_id = vformat("LimboAI/update_ms|%s_%s_%s", get_owner()->get_name(), get_name(),
|
||||||
|
String(itos(get_instance_id())).md5_text().substr(0, 4));
|
||||||
|
}
|
||||||
|
if (!Performance::get_singleton()->has_custom_monitor(monitor_id)) {
|
||||||
|
PERFORMANCE_ADD_CUSTOM_MONITOR(monitor_id, callable_mp(this, &BTPlayer::_get_mean_update_time_msec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BTPlayer::_remove_custom_monitor() {
|
||||||
|
if (monitor_id != StringName() && Performance::get_singleton()->has_custom_monitor(monitor_id)) {
|
||||||
|
Performance::get_singleton()->remove_custom_monitor(monitor_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double BTPlayer::_get_mean_update_time_msec() {
|
||||||
|
if (update_time_n) {
|
||||||
|
double mean_time_msec = (update_time_acc * 0.001) / update_time_n;
|
||||||
|
update_time_acc = 0.0;
|
||||||
|
update_time_n = 0.0;
|
||||||
|
return mean_time_msec;
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ! DEBUG_ENABLED
|
#endif // ! DEBUG_ENABLED
|
||||||
|
@ -187,17 +222,21 @@ void BTPlayer::_notification(int p_notification) {
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (bt_instance.is_valid()) {
|
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
|
||||||
bt_instance->set_monitor_performance(monitor_performance);
|
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
|
||||||
bt_instance->register_with_debugger();
|
}
|
||||||
|
if (monitor_performance) {
|
||||||
|
_add_custom_monitor();
|
||||||
}
|
}
|
||||||
#endif // DEBUG_ENABLED
|
#endif // DEBUG_ENABLED
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (bt_instance.is_valid()) {
|
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
|
||||||
bt_instance->set_monitor_performance(false);
|
LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path());
|
||||||
bt_instance->unregister_with_debugger();
|
}
|
||||||
|
if (monitor_performance) {
|
||||||
|
_remove_custom_monitor();
|
||||||
}
|
}
|
||||||
#endif // DEBUG_ENABLED
|
#endif // DEBUG_ENABLED
|
||||||
|
|
||||||
|
@ -227,9 +266,9 @@ void BTPlayer::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("update", "delta"), &BTPlayer::update);
|
ClassDB::bind_method(D_METHOD("update", "delta"), &BTPlayer::update);
|
||||||
ClassDB::bind_method(D_METHOD("restart"), &BTPlayer::restart);
|
ClassDB::bind_method(D_METHOD("restart"), &BTPlayer::restart);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_last_status"), &BTPlayer::get_last_status);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_bt_instance"), &BTPlayer::get_bt_instance);
|
ClassDB::bind_method(D_METHOD("get_tree_instance"), &BTPlayer::get_tree_instance);
|
||||||
ClassDB::bind_method(D_METHOD("set_bt_instance", "bt_instance"), &BTPlayer::set_bt_instance);
|
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "behavior_tree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_behavior_tree", "get_behavior_tree");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "behavior_tree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_behavior_tree", "get_behavior_tree");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "agent_node"), "set_agent_node", "get_agent_node");
|
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "agent_node"), "set_agent_node", "get_agent_node");
|
||||||
|
@ -242,11 +281,8 @@ void BTPlayer::_bind_methods() {
|
||||||
BIND_ENUM_CONSTANT(PHYSICS);
|
BIND_ENUM_CONSTANT(PHYSICS);
|
||||||
BIND_ENUM_CONSTANT(MANUAL);
|
BIND_ENUM_CONSTANT(MANUAL);
|
||||||
|
|
||||||
ADD_SIGNAL(MethodInfo("updated", PropertyInfo(Variant::INT, "status")));
|
|
||||||
|
|
||||||
#ifndef DISABLE_DEPRECATED
|
|
||||||
ADD_SIGNAL(MethodInfo("behavior_tree_finished", PropertyInfo(Variant::INT, "status")));
|
ADD_SIGNAL(MethodInfo("behavior_tree_finished", PropertyInfo(Variant::INT, "status")));
|
||||||
#endif
|
ADD_SIGNAL(MethodInfo("updated", PropertyInfo(Variant::INT, "status")));
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
ClassDB::bind_method(D_METHOD("_set_monitor_performance", "enable"), &BTPlayer::_set_monitor_performance);
|
ClassDB::bind_method(D_METHOD("_set_monitor_performance", "enable"), &BTPlayer::_set_monitor_performance);
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "../blackboard/blackboard.h"
|
#include "../blackboard/blackboard.h"
|
||||||
#include "../blackboard/blackboard_plan.h"
|
#include "../blackboard/blackboard_plan.h"
|
||||||
#include "behavior_tree.h"
|
#include "behavior_tree.h"
|
||||||
#include "bt_instance.h"
|
|
||||||
#include "tasks/bt_task.h"
|
#include "tasks/bt_task.h"
|
||||||
|
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
|
@ -43,8 +42,9 @@ private:
|
||||||
UpdateMode update_mode = UpdateMode::PHYSICS;
|
UpdateMode update_mode = UpdateMode::PHYSICS;
|
||||||
bool active = true;
|
bool active = true;
|
||||||
Ref<Blackboard> blackboard;
|
Ref<Blackboard> blackboard;
|
||||||
|
int last_status = -1;
|
||||||
|
|
||||||
Ref<BTInstance> bt_instance;
|
Ref<BTTask> tree_instance;
|
||||||
|
|
||||||
void _load_tree();
|
void _load_tree();
|
||||||
void _update_blackboard_plan();
|
void _update_blackboard_plan();
|
||||||
|
@ -75,9 +75,9 @@ public:
|
||||||
|
|
||||||
void update(double p_delta);
|
void update(double p_delta);
|
||||||
void restart();
|
void restart();
|
||||||
|
int get_last_status() const { return last_status; }
|
||||||
|
|
||||||
Ref<BTInstance> get_bt_instance() { return bt_instance; }
|
Ref<BTTask> get_tree_instance() { return tree_instance; }
|
||||||
void set_bt_instance(const Ref<BTInstance> &p_bt_instance);
|
|
||||||
|
|
||||||
BTPlayer();
|
BTPlayer();
|
||||||
~BTPlayer();
|
~BTPlayer();
|
||||||
|
@ -86,11 +86,19 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool monitor_performance = false;
|
bool monitor_performance = false;
|
||||||
|
StringName monitor_id;
|
||||||
|
double update_time_acc = 0.0;
|
||||||
|
double update_time_n = 0.0;
|
||||||
|
|
||||||
void _set_monitor_performance(bool p_monitor_performance);
|
void _set_monitor_performance(bool p_monitor_performance);
|
||||||
bool _get_monitor_performance() const { return monitor_performance; }
|
bool _get_monitor_performance() const { return monitor_performance; }
|
||||||
|
|
||||||
#endif // * DEBUG_ENABLED
|
void _add_custom_monitor();
|
||||||
|
void _remove_custom_monitor();
|
||||||
|
|
||||||
|
double _get_mean_update_time_msec();
|
||||||
|
|
||||||
|
#endif // DEBUG_ENABLED
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BT_PLAYER_H
|
#endif // BT_PLAYER_H
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "bt_state.h"
|
#include "bt_state.h"
|
||||||
|
|
||||||
|
#include "../editor/debugger/limbo_debugger.h"
|
||||||
#include "../util/limbo_compat.h"
|
#include "../util/limbo_compat.h"
|
||||||
#include "../util/limbo_string_names.h"
|
#include "../util/limbo_string_names.h"
|
||||||
|
|
||||||
|
@ -37,16 +38,6 @@ void BTState::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
|
||||||
_update_blackboard_plan();
|
_update_blackboard_plan();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
void BTState::_set_monitor_performance(bool p_monitor) {
|
|
||||||
monitor_performance = p_monitor;
|
|
||||||
|
|
||||||
if (bt_instance.is_valid()) {
|
|
||||||
bt_instance->set_monitor_performance(monitor_performance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // DEBUG_ENABLED
|
|
||||||
|
|
||||||
void BTState::_update_blackboard_plan() {
|
void BTState::_update_blackboard_plan() {
|
||||||
if (get_blackboard_plan().is_null()) {
|
if (get_blackboard_plan().is_null()) {
|
||||||
set_blackboard_plan(memnew(BlackboardPlan));
|
set_blackboard_plan(memnew(BlackboardPlan));
|
||||||
|
@ -63,18 +54,18 @@ void BTState::_setup() {
|
||||||
ERR_FAIL_COND_MSG(behavior_tree.is_null(), "BTState: BehaviorTree is not assigned.");
|
ERR_FAIL_COND_MSG(behavior_tree.is_null(), "BTState: BehaviorTree is not assigned.");
|
||||||
Node *scene_root = get_owner();
|
Node *scene_root = get_owner();
|
||||||
ERR_FAIL_NULL_MSG(scene_root, "BTState: Initialization failed - can't get scene root (make sure the BTState's owner property is set).");
|
ERR_FAIL_NULL_MSG(scene_root, "BTState: Initialization failed - can't get scene root (make sure the BTState's owner property is set).");
|
||||||
bt_instance = behavior_tree->instantiate(get_agent(), get_blackboard(), this);
|
tree_instance = behavior_tree->instantiate(get_agent(), get_blackboard(), scene_root);
|
||||||
ERR_FAIL_COND_MSG(bt_instance.is_null(), "BTState: Initialization failed - can't instantiate behavior tree.");
|
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
bt_instance->register_with_debugger();
|
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
|
||||||
bt_instance->set_monitor_performance(monitor_performance);
|
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTState::_exit() {
|
void BTState::_exit() {
|
||||||
if (bt_instance.is_valid()) {
|
if (tree_instance.is_valid()) {
|
||||||
bt_instance->get_root_task()->abort();
|
tree_instance->abort();
|
||||||
} else {
|
} else {
|
||||||
ERR_PRINT_ONCE("BTState: BehaviorTree is not assigned.");
|
ERR_PRINT_ONCE("BTState: BehaviorTree is not assigned.");
|
||||||
}
|
}
|
||||||
|
@ -87,8 +78,8 @@ void BTState::_update(double p_delta) {
|
||||||
// Bail out if a transition happened in the meantime.
|
// Bail out if a transition happened in the meantime.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ERR_FAIL_NULL(bt_instance);
|
ERR_FAIL_NULL(tree_instance);
|
||||||
BT::Status status = bt_instance->update(p_delta);
|
int status = tree_instance->execute(p_delta);
|
||||||
if (status == BTTask::SUCCESS) {
|
if (status == BTTask::SUCCESS) {
|
||||||
get_root()->dispatch(success_event, Variant());
|
get_root()->dispatch(success_event, Variant());
|
||||||
} else if (status == BTTask::FAILURE) {
|
} else if (status == BTTask::FAILURE) {
|
||||||
|
@ -101,19 +92,16 @@ void BTState::_notification(int p_notification) {
|
||||||
switch (p_notification) {
|
switch (p_notification) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
if (bt_instance.is_valid()) {
|
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
|
||||||
bt_instance->register_with_debugger();
|
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
|
||||||
bt_instance->set_monitor_performance(monitor_performance);
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
#endif // DEBUG_ENABLED
|
#endif // DEBUG_ENABLED
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (bt_instance.is_valid()) {
|
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
|
||||||
bt_instance->unregister_with_debugger();
|
LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path());
|
||||||
bt_instance->set_monitor_performance(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // DEBUG_ENABLED
|
#endif // DEBUG_ENABLED
|
||||||
|
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
|
@ -129,7 +117,7 @@ void BTState::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_behavior_tree", "behavior_tree"), &BTState::set_behavior_tree);
|
ClassDB::bind_method(D_METHOD("set_behavior_tree", "behavior_tree"), &BTState::set_behavior_tree);
|
||||||
ClassDB::bind_method(D_METHOD("get_behavior_tree"), &BTState::get_behavior_tree);
|
ClassDB::bind_method(D_METHOD("get_behavior_tree"), &BTState::get_behavior_tree);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_bt_instance"), &BTState::get_bt_instance);
|
ClassDB::bind_method(D_METHOD("get_tree_instance"), &BTState::get_tree_instance);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_success_event", "event"), &BTState::set_success_event);
|
ClassDB::bind_method(D_METHOD("set_success_event", "event"), &BTState::set_success_event);
|
||||||
ClassDB::bind_method(D_METHOD("get_success_event"), &BTState::get_success_event);
|
ClassDB::bind_method(D_METHOD("get_success_event"), &BTState::get_success_event);
|
||||||
|
@ -140,12 +128,6 @@ void BTState::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "behavior_tree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_behavior_tree", "get_behavior_tree");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "behavior_tree", PROPERTY_HINT_RESOURCE_TYPE, "BehaviorTree"), "set_behavior_tree", "get_behavior_tree");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "success_event"), "set_success_event", "get_success_event");
|
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "success_event"), "set_success_event", "get_success_event");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "failure_event"), "set_failure_event", "get_failure_event");
|
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "failure_event"), "set_failure_event", "get_failure_event");
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
ClassDB::bind_method(D_METHOD("_set_monitor_performance", "enable"), &BTState::_set_monitor_performance);
|
|
||||||
ClassDB::bind_method(D_METHOD("_get_monitor_performance"), &BTState::_get_monitor_performance);
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitor_performance"), "_set_monitor_performance", "_get_monitor_performance");
|
|
||||||
#endif // DEBUG_ENABLED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BTState::BTState() {
|
BTState::BTState() {
|
||||||
|
|
|
@ -22,7 +22,7 @@ class BTState : public LimboState {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ref<BehaviorTree> behavior_tree;
|
Ref<BehaviorTree> behavior_tree;
|
||||||
Ref<BTInstance> bt_instance;
|
Ref<BTTask> tree_instance;
|
||||||
StringName success_event;
|
StringName success_event;
|
||||||
StringName failure_event;
|
StringName failure_event;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public:
|
||||||
void set_behavior_tree(const Ref<BehaviorTree> &p_value);
|
void set_behavior_tree(const Ref<BehaviorTree> &p_value);
|
||||||
Ref<BehaviorTree> get_behavior_tree() const { return behavior_tree; }
|
Ref<BehaviorTree> get_behavior_tree() const { return behavior_tree; }
|
||||||
|
|
||||||
Ref<BTInstance> get_bt_instance() const { return bt_instance; }
|
Ref<BTTask> get_tree_instance() const { return tree_instance; }
|
||||||
|
|
||||||
void set_success_event(const StringName &p_success_event) { success_event = p_success_event; }
|
void set_success_event(const StringName &p_success_event) { success_event = p_success_event; }
|
||||||
StringName get_success_event() const { return success_event; }
|
StringName get_success_event() const { return success_event; }
|
||||||
|
@ -51,14 +51,6 @@ public:
|
||||||
StringName get_failure_event() const { return failure_event; }
|
StringName get_failure_event() const { return failure_event; }
|
||||||
|
|
||||||
BTState();
|
BTState();
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
private:
|
|
||||||
bool monitor_performance = false;
|
|
||||||
|
|
||||||
void _set_monitor_performance(bool p_monitor);
|
|
||||||
bool _get_monitor_performance() const { return monitor_performance; }
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BT_STATE_H
|
#endif // BT_STATE_H
|
||||||
|
|
|
@ -83,7 +83,6 @@ def get_doc_classes():
|
||||||
"BTDynamicSequence",
|
"BTDynamicSequence",
|
||||||
"BTFail",
|
"BTFail",
|
||||||
"BTForEach",
|
"BTForEach",
|
||||||
"BTInstance",
|
|
||||||
"BTInvert",
|
"BTInvert",
|
||||||
"BTNewScope",
|
"BTNewScope",
|
||||||
"BTParallel",
|
"BTParallel",
|
||||||
|
|
|
@ -42,8 +42,8 @@ func _ready() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(_delta: float) -> void:
|
func _physics_process(_delta: float) -> void:
|
||||||
var inst: BTInstance = bt_player.get_bt_instance()
|
var inst: BTTask = bt_player.get_tree_instance()
|
||||||
var bt_data: BehaviorTreeData = BehaviorTreeData.create_from_bt_instance(inst)
|
var bt_data: BehaviorTreeData = BehaviorTreeData.create_from_tree_instance(inst)
|
||||||
behavior_tree_view.update_tree(bt_data)
|
behavior_tree_view.update_tree(bt_data)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -257,8 +257,8 @@ anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
offset_left = 4.0
|
offset_left = 4.0
|
||||||
offset_top = 4.0
|
offset_top = 4.0
|
||||||
offset_right = 1020.0
|
offset_right = -4.0
|
||||||
offset_bottom = 704.0
|
offset_bottom = -4.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
gutters_draw_line_numbers = true
|
gutters_draw_line_numbers = true
|
||||||
|
|
|
@ -55,17 +55,17 @@ Methods
|
||||||
.. table::
|
.. table::
|
||||||
:widths: auto
|
:widths: auto
|
||||||
|
|
||||||
+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`BehaviorTree<class_BehaviorTree>` | :ref:`clone<class_BehaviorTree_method_clone>`\ (\ ) |const| |
|
| :ref:`BehaviorTree<class_BehaviorTree>` | :ref:`clone<class_BehaviorTree_method_clone>`\ (\ ) |const| |
|
||||||
+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| |void| | :ref:`copy_other<class_BehaviorTree_method_copy_other>`\ (\ other\: :ref:`BehaviorTree<class_BehaviorTree>`\ ) |
|
| |void| | :ref:`copy_other<class_BehaviorTree_method_copy_other>`\ (\ other\: :ref:`BehaviorTree<class_BehaviorTree>`\ ) |
|
||||||
+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`BTTask<class_BTTask>` | :ref:`get_root_task<class_BehaviorTree_method_get_root_task>`\ (\ ) |const| |
|
| :ref:`BTTask<class_BTTask>` | :ref:`get_root_task<class_BehaviorTree_method_get_root_task>`\ (\ ) |const| |
|
||||||
+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`BTInstance<class_BTInstance>` | :ref:`instantiate<class_BehaviorTree_method_instantiate>`\ (\ agent\: ``Node``, blackboard\: :ref:`Blackboard<class_Blackboard>`, instance_owner\: ``Node``\ ) |const| |
|
| :ref:`BTTask<class_BTTask>` | :ref:`instantiate<class_BehaviorTree_method_instantiate>`\ (\ agent\: ``Node``, blackboard\: :ref:`Blackboard<class_Blackboard>`, scene_root\: ``Node``\ ) |const| |
|
||||||
+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| |void| | :ref:`set_root_task<class_BehaviorTree_method_set_root_task>`\ (\ task\: :ref:`BTTask<class_BTTask>`\ ) |
|
| |void| | :ref:`set_root_task<class_BehaviorTree_method_set_root_task>`\ (\ task\: :ref:`BTTask<class_BTTask>`\ ) |
|
||||||
+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
.. rst-class:: classref-section-separator
|
.. rst-class:: classref-section-separator
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ Stores and manages variables that will be used in constructing new :ref:`Blackbo
|
||||||
- |void| **set_description**\ (\ value\: ``String``\ )
|
- |void| **set_description**\ (\ value\: ``String``\ )
|
||||||
- ``String`` **get_description**\ (\ )
|
- ``String`` **get_description**\ (\ )
|
||||||
|
|
||||||
User-provided description of the **BehaviorTree**.
|
User-provided description of the BehaviorTree.
|
||||||
|
|
||||||
.. rst-class:: classref-section-separator
|
.. rst-class:: classref-section-separator
|
||||||
|
|
||||||
|
@ -172,9 +172,9 @@ Returns the root task of the BehaviorTree resource.
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
:ref:`BTInstance<class_BTInstance>` **instantiate**\ (\ agent\: ``Node``, blackboard\: :ref:`Blackboard<class_Blackboard>`, instance_owner\: ``Node``\ ) |const| :ref:`🔗<class_BehaviorTree_method_instantiate>`
|
:ref:`BTTask<class_BTTask>` **instantiate**\ (\ agent\: ``Node``, blackboard\: :ref:`Blackboard<class_Blackboard>`, scene_root\: ``Node``\ ) |const| :ref:`🔗<class_BehaviorTree_method_instantiate>`
|
||||||
|
|
||||||
Instantiates the behavior tree and returns :ref:`BTInstance<class_BTInstance>`. ``instance_owner`` should be the scene node that will own the behavior tree instance. This is typically a :ref:`BTPlayer<class_BTPlayer>`, :ref:`BTState<class_BTState>`, or a custom player node that controls the behavior tree execution. Make sure to pass a :ref:`Blackboard<class_Blackboard>` with values populated from :ref:`blackboard_plan<class_BehaviorTree_property_blackboard_plan>`. See also ``BlackboardPlan.populate_blackboard`` & ``BlackboardPlan.create_blackboard``.
|
Instantiates the behavior tree and returns the root :ref:`BTTask<class_BTTask>`. ``scene_root`` should be the root node of the scene that the Behavior Tree will be used in (e.g., the owner of the node that contains the behavior tree).
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
.. rst-class:: classref-item-separator
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@ Methods
|
||||||
.. table::
|
.. table::
|
||||||
:widths: auto
|
:widths: auto
|
||||||
|
|
||||||
+-------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| :ref:`BehaviorTreeData<class_BehaviorTreeData>` | :ref:`create_from_bt_instance<class_BehaviorTreeData_method_create_from_bt_instance>`\ (\ bt_instance\: :ref:`BTInstance<class_BTInstance>`\ ) |static| |
|
| :ref:`BehaviorTreeData<class_BehaviorTreeData>` | :ref:`create_from_tree_instance<class_BehaviorTreeData_method_create_from_tree_instance>`\ (\ tree_instance\: :ref:`BTTask<class_BTTask>`\ ) |static| |
|
||||||
+-------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
|
+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
.. rst-class:: classref-section-separator
|
.. rst-class:: classref-section-separator
|
||||||
|
|
||||||
|
@ -44,15 +44,15 @@ Methods
|
||||||
Method Descriptions
|
Method Descriptions
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
.. _class_BehaviorTreeData_method_create_from_bt_instance:
|
.. _class_BehaviorTreeData_method_create_from_tree_instance:
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
:ref:`BehaviorTreeData<class_BehaviorTreeData>` **create_from_bt_instance**\ (\ bt_instance\: :ref:`BTInstance<class_BTInstance>`\ ) |static| :ref:`🔗<class_BehaviorTreeData_method_create_from_bt_instance>`
|
:ref:`BehaviorTreeData<class_BehaviorTreeData>` **create_from_tree_instance**\ (\ tree_instance\: :ref:`BTTask<class_BTTask>`\ ) |static| :ref:`🔗<class_BehaviorTreeData_method_create_from_tree_instance>`
|
||||||
|
|
||||||
Returns current state of the ``bt_instance`` encoded as a **BehaviorTreeData**, suitable for use with :ref:`BehaviorTreeView<class_BehaviorTreeView>`.
|
Returns current state of the ``tree_instance`` encoded as a **BehaviorTreeData**, suitable for use with :ref:`BehaviorTreeView<class_BehaviorTreeView>`.
|
||||||
|
|
||||||
Behavior tree instance can be acquired with :ref:`BTPlayer.get_bt_instance<class_BTPlayer_method_get_bt_instance>`.
|
Behavior tree instance can be acquired with :ref:`BTPlayer.get_tree_instance<class_BTPlayer_method_get_tree_instance>`.
|
||||||
|
|
||||||
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
||||||
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
||||||
|
|
|
@ -1,249 +0,0 @@
|
||||||
:github_url: hide
|
|
||||||
|
|
||||||
.. DO NOT EDIT THIS FILE!!!
|
|
||||||
.. Generated automatically from Godot engine sources.
|
|
||||||
.. Generator: https://github.com/godotengine/godot/tree/master/doc/tools/make_rst.py.
|
|
||||||
.. XML source: https://github.com/godotengine/godot/tree/master/modules/limboai/doc_classes/BTInstance.xml.
|
|
||||||
|
|
||||||
.. _class_BTInstance:
|
|
||||||
|
|
||||||
BTInstance
|
|
||||||
==========
|
|
||||||
|
|
||||||
**Inherits:**
|
|
||||||
|
|
||||||
Represents a runtime instance of a :ref:`BehaviorTree<class_BehaviorTree>` resource.
|
|
||||||
|
|
||||||
.. rst-class:: classref-introduction-group
|
|
||||||
|
|
||||||
Description
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Can be created using the :ref:`BehaviorTree.instantiate<class_BehaviorTree_method_instantiate>` method.
|
|
||||||
|
|
||||||
.. rst-class:: classref-reftable-group
|
|
||||||
|
|
||||||
Properties
|
|
||||||
----------
|
|
||||||
|
|
||||||
.. table::
|
|
||||||
:widths: auto
|
|
||||||
|
|
||||||
+----------+---------------------------------------------------------------------------+-----------+
|
|
||||||
| ``bool`` | :ref:`monitor_performance<class_BTInstance_property_monitor_performance>` | ``false`` |
|
|
||||||
+----------+---------------------------------------------------------------------------+-----------+
|
|
||||||
|
|
||||||
.. rst-class:: classref-reftable-group
|
|
||||||
|
|
||||||
Methods
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. table::
|
|
||||||
:widths: auto
|
|
||||||
|
|
||||||
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
|
||||||
| ``Node`` | :ref:`get_agent<class_BTInstance_method_get_agent>`\ (\ ) |const| |
|
|
||||||
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
|
||||||
| :ref:`Blackboard<class_Blackboard>` | :ref:`get_blackboard<class_BTInstance_method_get_blackboard>`\ (\ ) |const| |
|
|
||||||
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
|
||||||
| :ref:`Status<enum_BT_Status>` | :ref:`get_last_status<class_BTInstance_method_get_last_status>`\ (\ ) |const| |
|
|
||||||
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
|
||||||
| ``Node`` | :ref:`get_owner_node<class_BTInstance_method_get_owner_node>`\ (\ ) |const| |
|
|
||||||
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
|
||||||
| :ref:`BTTask<class_BTTask>` | :ref:`get_root_task<class_BTInstance_method_get_root_task>`\ (\ ) |const| |
|
|
||||||
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
|
||||||
| ``String`` | :ref:`get_source_bt_path<class_BTInstance_method_get_source_bt_path>`\ (\ ) |const| |
|
|
||||||
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
|
||||||
| ``bool`` | :ref:`is_instance_valid<class_BTInstance_method_is_instance_valid>`\ (\ ) |const| |
|
|
||||||
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
|
||||||
| |void| | :ref:`register_with_debugger<class_BTInstance_method_register_with_debugger>`\ (\ ) |
|
|
||||||
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
|
||||||
| |void| | :ref:`unregister_with_debugger<class_BTInstance_method_unregister_with_debugger>`\ (\ ) |
|
|
||||||
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
|
||||||
| :ref:`Status<enum_BT_Status>` | :ref:`update<class_BTInstance_method_update>`\ (\ delta\: ``float``\ ) |
|
|
||||||
+-------------------------------------+-----------------------------------------------------------------------------------------+
|
|
||||||
|
|
||||||
.. rst-class:: classref-section-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. rst-class:: classref-descriptions-group
|
|
||||||
|
|
||||||
Signals
|
|
||||||
-------
|
|
||||||
|
|
||||||
.. _class_BTInstance_signal_freed:
|
|
||||||
|
|
||||||
.. rst-class:: classref-signal
|
|
||||||
|
|
||||||
**freed**\ (\ ) :ref:`🔗<class_BTInstance_signal_freed>`
|
|
||||||
|
|
||||||
Emitted when the behavior tree instance is freed. Used by debugger to unregister.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTInstance_signal_updated:
|
|
||||||
|
|
||||||
.. rst-class:: classref-signal
|
|
||||||
|
|
||||||
**updated**\ (\ status\: ``int``\ ) :ref:`🔗<class_BTInstance_signal_updated>`
|
|
||||||
|
|
||||||
Emitted when the behavior tree instance has finished updating.
|
|
||||||
|
|
||||||
.. rst-class:: classref-section-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. rst-class:: classref-descriptions-group
|
|
||||||
|
|
||||||
Property Descriptions
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
.. _class_BTInstance_property_monitor_performance:
|
|
||||||
|
|
||||||
.. rst-class:: classref-property
|
|
||||||
|
|
||||||
``bool`` **monitor_performance** = ``false`` :ref:`🔗<class_BTInstance_property_monitor_performance>`
|
|
||||||
|
|
||||||
.. rst-class:: classref-property-setget
|
|
||||||
|
|
||||||
- |void| **set_monitor_performance**\ (\ value\: ``bool``\ )
|
|
||||||
- ``bool`` **get_monitor_performance**\ (\ )
|
|
||||||
|
|
||||||
If ``true``, adds a performance monitor for this instance to "Debugger->Monitors" in the editor.
|
|
||||||
|
|
||||||
.. rst-class:: classref-section-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. rst-class:: classref-descriptions-group
|
|
||||||
|
|
||||||
Method Descriptions
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
.. _class_BTInstance_method_get_agent:
|
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
|
||||||
|
|
||||||
``Node`` **get_agent**\ (\ ) |const| :ref:`🔗<class_BTInstance_method_get_agent>`
|
|
||||||
|
|
||||||
Returns the agent of the behavior tree instance.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTInstance_method_get_blackboard:
|
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
|
||||||
|
|
||||||
:ref:`Blackboard<class_Blackboard>` **get_blackboard**\ (\ ) |const| :ref:`🔗<class_BTInstance_method_get_blackboard>`
|
|
||||||
|
|
||||||
Returns the blackboard of the behavior tree instance.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTInstance_method_get_last_status:
|
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
|
||||||
|
|
||||||
:ref:`Status<enum_BT_Status>` **get_last_status**\ (\ ) |const| :ref:`🔗<class_BTInstance_method_get_last_status>`
|
|
||||||
|
|
||||||
Returns the execution status of the last update.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTInstance_method_get_owner_node:
|
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
|
||||||
|
|
||||||
``Node`` **get_owner_node**\ (\ ) |const| :ref:`🔗<class_BTInstance_method_get_owner_node>`
|
|
||||||
|
|
||||||
Returns the scene ``Node`` that owns this behavior tree instance.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTInstance_method_get_root_task:
|
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
|
||||||
|
|
||||||
:ref:`BTTask<class_BTTask>` **get_root_task**\ (\ ) |const| :ref:`🔗<class_BTInstance_method_get_root_task>`
|
|
||||||
|
|
||||||
Returns the root task of the behavior tree instance.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTInstance_method_get_source_bt_path:
|
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
|
||||||
|
|
||||||
``String`` **get_source_bt_path**\ (\ ) |const| :ref:`🔗<class_BTInstance_method_get_source_bt_path>`
|
|
||||||
|
|
||||||
Returns the file path to the behavior tree resource that was used to create this instance.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTInstance_method_is_instance_valid:
|
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
|
||||||
|
|
||||||
``bool`` **is_instance_valid**\ (\ ) |const| :ref:`🔗<class_BTInstance_method_is_instance_valid>`
|
|
||||||
|
|
||||||
Returns ``true`` if the behavior tree instance is properly initialized and can be used.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTInstance_method_register_with_debugger:
|
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
|
||||||
|
|
||||||
|void| **register_with_debugger**\ (\ ) :ref:`🔗<class_BTInstance_method_register_with_debugger>`
|
|
||||||
|
|
||||||
Registers the behavior tree instance with the debugger.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTInstance_method_unregister_with_debugger:
|
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
|
||||||
|
|
||||||
|void| **unregister_with_debugger**\ (\ ) :ref:`🔗<class_BTInstance_method_unregister_with_debugger>`
|
|
||||||
|
|
||||||
Unregisters the behavior tree instance from the debugger. This is typically not necessary, as the debugger will automatically unregister the instance when it is freed.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTInstance_method_update:
|
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
|
||||||
|
|
||||||
:ref:`Status<enum_BT_Status>` **update**\ (\ delta\: ``float``\ ) :ref:`🔗<class_BTInstance_method_update>`
|
|
||||||
|
|
||||||
Ticks the behavior tree instance and returns its status.
|
|
||||||
|
|
||||||
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
|
||||||
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
|
||||||
.. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`
|
|
||||||
.. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`
|
|
||||||
.. |static| replace:: :abbr:`static (This method doesn't need an instance to be called, so it can be called directly using the class name.)`
|
|
||||||
.. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`
|
|
||||||
.. |bitfield| replace:: :abbr:`BitField (This value is an integer composed as a bitmask of the following flags.)`
|
|
||||||
.. |void| replace:: :abbr:`void (No return value.)`
|
|
|
@ -55,15 +55,15 @@ Methods
|
||||||
.. table::
|
.. table::
|
||||||
:widths: auto
|
:widths: auto
|
||||||
|
|
||||||
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------+-----------------------------------------------------------------------------+
|
||||||
| :ref:`BTInstance<class_BTInstance>` | :ref:`get_bt_instance<class_BTPlayer_method_get_bt_instance>`\ (\ ) |
|
| ``int`` | :ref:`get_last_status<class_BTPlayer_method_get_last_status>`\ (\ ) |const| |
|
||||||
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------+-----------------------------------------------------------------------------+
|
||||||
|
| :ref:`BTTask<class_BTTask>` | :ref:`get_tree_instance<class_BTPlayer_method_get_tree_instance>`\ (\ ) |
|
||||||
|
+-----------------------------+-----------------------------------------------------------------------------+
|
||||||
| |void| | :ref:`restart<class_BTPlayer_method_restart>`\ (\ ) |
|
| |void| | :ref:`restart<class_BTPlayer_method_restart>`\ (\ ) |
|
||||||
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------+-----------------------------------------------------------------------------+
|
||||||
| |void| | :ref:`set_bt_instance<class_BTPlayer_method_set_bt_instance>`\ (\ bt_instance\: :ref:`BTInstance<class_BTInstance>`\ ) |
|
|
||||||
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------+
|
|
||||||
| |void| | :ref:`update<class_BTPlayer_method_update>`\ (\ delta\: ``float``\ ) |
|
| |void| | :ref:`update<class_BTPlayer_method_update>`\ (\ delta\: ``float``\ ) |
|
||||||
+-------------------------------------+------------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------+-----------------------------------------------------------------------------+
|
||||||
|
|
||||||
.. rst-class:: classref-section-separator
|
.. rst-class:: classref-section-separator
|
||||||
|
|
||||||
|
@ -80,8 +80,6 @@ Signals
|
||||||
|
|
||||||
**behavior_tree_finished**\ (\ status\: ``int``\ ) :ref:`🔗<class_BTPlayer_signal_behavior_tree_finished>`
|
**behavior_tree_finished**\ (\ status\: ``int``\ ) :ref:`🔗<class_BTPlayer_signal_behavior_tree_finished>`
|
||||||
|
|
||||||
**Deprecated:** Use :ref:`updated<class_BTPlayer_signal_updated>` signal instead.
|
|
||||||
|
|
||||||
Emitted when the behavior tree has finished executing and returned ``SUCCESS`` or ``FAILURE``.
|
Emitted when the behavior tree has finished executing and returned ``SUCCESS`` or ``FAILURE``.
|
||||||
|
|
||||||
Argument ``status`` holds the status returned by the behavior tree. See :ref:`Status<enum_BT_Status>`.
|
Argument ``status`` holds the status returned by the behavior tree. See :ref:`Status<enum_BT_Status>`.
|
||||||
|
@ -267,13 +265,25 @@ Determines when the behavior tree is executed. See :ref:`UpdateMode<enum_BTPlaye
|
||||||
Method Descriptions
|
Method Descriptions
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
.. _class_BTPlayer_method_get_bt_instance:
|
.. _class_BTPlayer_method_get_last_status:
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
:ref:`BTInstance<class_BTInstance>` **get_bt_instance**\ (\ ) :ref:`🔗<class_BTPlayer_method_get_bt_instance>`
|
``int`` **get_last_status**\ (\ ) |const| :ref:`🔗<class_BTPlayer_method_get_last_status>`
|
||||||
|
|
||||||
Returns the behavior tree instance.
|
Returns the behavior tree's last execution status. See :ref:`Status<enum_BT_Status>`.
|
||||||
|
|
||||||
|
.. rst-class:: classref-item-separator
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
.. _class_BTPlayer_method_get_tree_instance:
|
||||||
|
|
||||||
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
|
:ref:`BTTask<class_BTTask>` **get_tree_instance**\ (\ ) :ref:`🔗<class_BTPlayer_method_get_tree_instance>`
|
||||||
|
|
||||||
|
Returns the root task of the instantiated behavior tree.
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
.. rst-class:: classref-item-separator
|
||||||
|
|
||||||
|
@ -291,18 +301,6 @@ Resets the behavior tree's execution. Each running task will be aborted and the
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
.. _class_BTPlayer_method_set_bt_instance:
|
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
|
||||||
|
|
||||||
|void| **set_bt_instance**\ (\ bt_instance\: :ref:`BTInstance<class_BTInstance>`\ ) :ref:`🔗<class_BTPlayer_method_set_bt_instance>`
|
|
||||||
|
|
||||||
Sets the :ref:`BTInstance<class_BTInstance>` to play. This method is useful when you want to switch to a different behavior tree instance at runtime. See also :ref:`BehaviorTree.instantiate<class_BehaviorTree_property_instantiate>`.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTPlayer_method_update:
|
.. _class_BTPlayer_method_update:
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
|
|
@ -29,15 +29,13 @@ Properties
|
||||||
.. table::
|
.. table::
|
||||||
:widths: auto
|
:widths: auto
|
||||||
|
|
||||||
+-----------------------------------------+------------------------------------------------------------------------+----------------+
|
+-----------------------------------------+------------------------------------------------------------+----------------+
|
||||||
| :ref:`BehaviorTree<class_BehaviorTree>` | :ref:`behavior_tree<class_BTState_property_behavior_tree>` | |
|
| :ref:`BehaviorTree<class_BehaviorTree>` | :ref:`behavior_tree<class_BTState_property_behavior_tree>` | |
|
||||||
+-----------------------------------------+------------------------------------------------------------------------+----------------+
|
+-----------------------------------------+------------------------------------------------------------+----------------+
|
||||||
| ``StringName`` | :ref:`failure_event<class_BTState_property_failure_event>` | ``&"failure"`` |
|
| ``StringName`` | :ref:`failure_event<class_BTState_property_failure_event>` | ``&"failure"`` |
|
||||||
+-----------------------------------------+------------------------------------------------------------------------+----------------+
|
+-----------------------------------------+------------------------------------------------------------+----------------+
|
||||||
| ``bool`` | :ref:`monitor_performance<class_BTState_property_monitor_performance>` | ``false`` |
|
|
||||||
+-----------------------------------------+------------------------------------------------------------------------+----------------+
|
|
||||||
| ``StringName`` | :ref:`success_event<class_BTState_property_success_event>` | ``&"success"`` |
|
| ``StringName`` | :ref:`success_event<class_BTState_property_success_event>` | ``&"success"`` |
|
||||||
+-----------------------------------------+------------------------------------------------------------------------+----------------+
|
+-----------------------------------------+------------------------------------------------------------+----------------+
|
||||||
|
|
||||||
.. rst-class:: classref-reftable-group
|
.. rst-class:: classref-reftable-group
|
||||||
|
|
||||||
|
@ -47,9 +45,9 @@ Methods
|
||||||
.. table::
|
.. table::
|
||||||
:widths: auto
|
:widths: auto
|
||||||
|
|
||||||
+-------------------------------------+----------------------------------------------------------------------------+
|
+-----------------------------+--------------------------------------------------------------------------------+
|
||||||
| :ref:`BTInstance<class_BTInstance>` | :ref:`get_bt_instance<class_BTState_method_get_bt_instance>`\ (\ ) |const| |
|
| :ref:`BTTask<class_BTTask>` | :ref:`get_tree_instance<class_BTState_method_get_tree_instance>`\ (\ ) |const| |
|
||||||
+-------------------------------------+----------------------------------------------------------------------------+
|
+-----------------------------+--------------------------------------------------------------------------------+
|
||||||
|
|
||||||
.. rst-class:: classref-section-separator
|
.. rst-class:: classref-section-separator
|
||||||
|
|
||||||
|
@ -94,18 +92,6 @@ HSM event that will be dispatched when the behavior tree results in ``FAILURE``.
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
.. _class_BTState_property_monitor_performance:
|
|
||||||
|
|
||||||
.. rst-class:: classref-property
|
|
||||||
|
|
||||||
``bool`` **monitor_performance** = ``false`` :ref:`🔗<class_BTState_property_monitor_performance>`
|
|
||||||
|
|
||||||
If ``true``, adds a performance monitor to "Debugger->Monitors" for each instance of this **BTState** node.
|
|
||||||
|
|
||||||
.. rst-class:: classref-item-separator
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
.. _class_BTState_property_success_event:
|
.. _class_BTState_property_success_event:
|
||||||
|
|
||||||
.. rst-class:: classref-property
|
.. rst-class:: classref-property
|
||||||
|
@ -128,13 +114,13 @@ HSM event that will be dispatched when the behavior tree results in ``SUCCESS``.
|
||||||
Method Descriptions
|
Method Descriptions
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
.. _class_BTState_method_get_bt_instance:
|
.. _class_BTState_method_get_tree_instance:
|
||||||
|
|
||||||
.. rst-class:: classref-method
|
.. rst-class:: classref-method
|
||||||
|
|
||||||
:ref:`BTInstance<class_BTInstance>` **get_bt_instance**\ (\ ) |const| :ref:`🔗<class_BTState_method_get_bt_instance>`
|
:ref:`BTTask<class_BTTask>` **get_tree_instance**\ (\ ) |const| :ref:`🔗<class_BTState_method_get_tree_instance>`
|
||||||
|
|
||||||
Returns the behavior tree instance.
|
Returns the root task of the instantiated behavior tree.
|
||||||
|
|
||||||
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
.. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`
|
||||||
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
.. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<class name="BTInstance" inherits="RefCounted" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
|
|
||||||
<brief_description>
|
|
||||||
Represents a runtime instance of a [BehaviorTree] resource.
|
|
||||||
</brief_description>
|
|
||||||
<description>
|
|
||||||
Can be created using the [method BehaviorTree.instantiate] method.
|
|
||||||
</description>
|
|
||||||
<tutorials>
|
|
||||||
</tutorials>
|
|
||||||
<methods>
|
|
||||||
<method name="get_agent" qualifiers="const">
|
|
||||||
<return type="Node" />
|
|
||||||
<description>
|
|
||||||
Returns the agent of the behavior tree instance.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_blackboard" qualifiers="const">
|
|
||||||
<return type="Blackboard" />
|
|
||||||
<description>
|
|
||||||
Returns the blackboard of the behavior tree instance.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_last_status" qualifiers="const">
|
|
||||||
<return type="int" enum="BT.Status" />
|
|
||||||
<description>
|
|
||||||
Returns the execution status of the last update.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_owner_node" qualifiers="const">
|
|
||||||
<return type="Node" />
|
|
||||||
<description>
|
|
||||||
Returns the scene [Node] that owns this behavior tree instance.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_root_task" qualifiers="const">
|
|
||||||
<return type="BTTask" />
|
|
||||||
<description>
|
|
||||||
Returns the root task of the behavior tree instance.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="get_source_bt_path" qualifiers="const">
|
|
||||||
<return type="String" />
|
|
||||||
<description>
|
|
||||||
Returns the file path to the behavior tree resource that was used to create this instance.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="is_instance_valid" qualifiers="const">
|
|
||||||
<return type="bool" />
|
|
||||||
<description>
|
|
||||||
Returns [code]true[/code] if the behavior tree instance is properly initialized and can be used.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="register_with_debugger">
|
|
||||||
<return type="void" />
|
|
||||||
<description>
|
|
||||||
Registers the behavior tree instance with the debugger.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="unregister_with_debugger">
|
|
||||||
<return type="void" />
|
|
||||||
<description>
|
|
||||||
Unregisters the behavior tree instance from the debugger. This is typically not necessary, as the debugger will automatically unregister the instance when it is freed.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="update">
|
|
||||||
<return type="int" enum="BT.Status" />
|
|
||||||
<param index="0" name="delta" type="float" />
|
|
||||||
<description>
|
|
||||||
Ticks the behavior tree instance and returns its status.
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
</methods>
|
|
||||||
<members>
|
|
||||||
<member name="monitor_performance" type="bool" setter="set_monitor_performance" getter="get_monitor_performance" default="false">
|
|
||||||
If [code]true[/code], adds a performance monitor for this instance to "Debugger->Monitors" in the editor.
|
|
||||||
</member>
|
|
||||||
</members>
|
|
||||||
<signals>
|
|
||||||
<signal name="freed">
|
|
||||||
<description>
|
|
||||||
Emitted when the behavior tree instance is freed. Used by debugger to unregister.
|
|
||||||
</description>
|
|
||||||
</signal>
|
|
||||||
<signal name="updated">
|
|
||||||
<param index="0" name="status" type="int" />
|
|
||||||
<description>
|
|
||||||
Emitted when the behavior tree instance has finished updating.
|
|
||||||
</description>
|
|
||||||
</signal>
|
|
||||||
</signals>
|
|
||||||
</class>
|
|
|
@ -10,10 +10,16 @@
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
<method name="get_bt_instance">
|
<method name="get_last_status" qualifiers="const">
|
||||||
<return type="BTInstance" />
|
<return type="int" />
|
||||||
<description>
|
<description>
|
||||||
Returns the behavior tree instance.
|
Returns the behavior tree's last execution status. See [enum BT.Status].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="get_tree_instance">
|
||||||
|
<return type="BTTask" />
|
||||||
|
<description>
|
||||||
|
Returns the root task of the instantiated behavior tree.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="restart">
|
<method name="restart">
|
||||||
|
@ -22,13 +28,6 @@
|
||||||
Resets the behavior tree's execution. Each running task will be aborted and the next tree execution will start anew. This method does not reset [Blackboard].
|
Resets the behavior tree's execution. Each running task will be aborted and the next tree execution will start anew. This method does not reset [Blackboard].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="set_bt_instance">
|
|
||||||
<return type="void" />
|
|
||||||
<param index="0" name="bt_instance" type="BTInstance" />
|
|
||||||
<description>
|
|
||||||
Sets the [BTInstance] to play. This method is useful when you want to switch to a different behavior tree instance at runtime. See also [member BehaviorTree.instantiate].
|
|
||||||
</description>
|
|
||||||
</method>
|
|
||||||
<method name="update">
|
<method name="update">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="delta" type="float" />
|
<param index="0" name="delta" type="float" />
|
||||||
|
@ -61,7 +60,7 @@
|
||||||
</member>
|
</member>
|
||||||
</members>
|
</members>
|
||||||
<signals>
|
<signals>
|
||||||
<signal name="behavior_tree_finished" deprecated="Use [signal updated] signal instead.">
|
<signal name="behavior_tree_finished">
|
||||||
<param index="0" name="status" type="int" />
|
<param index="0" name="status" type="int" />
|
||||||
<description>
|
<description>
|
||||||
Emitted when the behavior tree has finished executing and returned [code]SUCCESS[/code] or [code]FAILURE[/code].
|
Emitted when the behavior tree has finished executing and returned [code]SUCCESS[/code] or [code]FAILURE[/code].
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
<method name="get_bt_instance" qualifiers="const">
|
<method name="get_tree_instance" qualifiers="const">
|
||||||
<return type="BTInstance" />
|
<return type="BTTask" />
|
||||||
<description>
|
<description>
|
||||||
Returns the behavior tree instance.
|
Returns the root task of the instantiated behavior tree.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
@ -23,9 +23,6 @@
|
||||||
<member name="failure_event" type="StringName" setter="set_failure_event" getter="get_failure_event" default="&"failure"">
|
<member name="failure_event" type="StringName" setter="set_failure_event" getter="get_failure_event" default="&"failure"">
|
||||||
HSM event that will be dispatched when the behavior tree results in [code]FAILURE[/code]. See [method LimboState.dispatch].
|
HSM event that will be dispatched when the behavior tree results in [code]FAILURE[/code]. See [method LimboState.dispatch].
|
||||||
</member>
|
</member>
|
||||||
<member name="monitor_performance" type="bool" setter="_set_monitor_performance" getter="_get_monitor_performance" default="false">
|
|
||||||
If [code]true[/code], adds a performance monitor to "Debugger->Monitors" for each instance of this [BTState] node.
|
|
||||||
</member>
|
|
||||||
<member name="success_event" type="StringName" setter="set_success_event" getter="get_success_event" default="&"success"">
|
<member name="success_event" type="StringName" setter="set_success_event" getter="get_success_event" default="&"success"">
|
||||||
HSM event that will be dispatched when the behavior tree results in [code]SUCCESS[/code]. See [method LimboState.dispatch].
|
HSM event that will be dispatched when the behavior tree results in [code]SUCCESS[/code]. See [method LimboState.dispatch].
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -35,12 +35,12 @@
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="instantiate" qualifiers="const">
|
<method name="instantiate" qualifiers="const">
|
||||||
<return type="BTInstance" />
|
<return type="BTTask" />
|
||||||
<param index="0" name="agent" type="Node" />
|
<param index="0" name="agent" type="Node" />
|
||||||
<param index="1" name="blackboard" type="Blackboard" />
|
<param index="1" name="blackboard" type="Blackboard" />
|
||||||
<param index="2" name="instance_owner" type="Node" />
|
<param index="2" name="scene_root" type="Node" />
|
||||||
<description>
|
<description>
|
||||||
Instantiates the behavior tree and returns [BTInstance]. [param instance_owner] should be the scene node that will own the behavior tree instance. This is typically a [BTPlayer], [BTState], or a custom player node that controls the behavior tree execution. Make sure to pass a [Blackboard] with values populated from [member blackboard_plan]. See also [BlackboardPlan.populate_blackboard] & [BlackboardPlan.create_blackboard].
|
Instantiates the behavior tree and returns the root [BTTask]. [param scene_root] should be the root node of the scene that the Behavior Tree will be used in (e.g., the owner of the node that contains the behavior tree).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="set_root_task">
|
<method name="set_root_task">
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
Stores and manages variables that will be used in constructing new [Blackboard] instances.
|
Stores and manages variables that will be used in constructing new [Blackboard] instances.
|
||||||
</member>
|
</member>
|
||||||
<member name="description" type="String" setter="set_description" getter="get_description" default="""">
|
<member name="description" type="String" setter="set_description" getter="get_description" default="""">
|
||||||
User-provided description of the [BehaviorTree].
|
User-provided description of the BehaviorTree.
|
||||||
</member>
|
</member>
|
||||||
</members>
|
</members>
|
||||||
<signals>
|
<signals>
|
||||||
|
|
|
@ -10,12 +10,12 @@
|
||||||
<tutorials>
|
<tutorials>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<methods>
|
<methods>
|
||||||
<method name="create_from_bt_instance" qualifiers="static">
|
<method name="create_from_tree_instance" qualifiers="static">
|
||||||
<return type="BehaviorTreeData" />
|
<return type="BehaviorTreeData" />
|
||||||
<param index="0" name="bt_instance" type="BTInstance" />
|
<param index="0" name="tree_instance" type="BTTask" />
|
||||||
<description>
|
<description>
|
||||||
Returns current state of the [param bt_instance] encoded as a [BehaviorTreeData], suitable for use with [BehaviorTreeView].
|
Returns current state of the [param tree_instance] encoded as a [BehaviorTreeData], suitable for use with [BehaviorTreeView].
|
||||||
Behavior tree instance can be acquired with [method BTPlayer.get_bt_instance].
|
Behavior tree instance can be acquired with [method BTPlayer.get_tree_instance].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
|
|
@ -17,15 +17,14 @@
|
||||||
|
|
||||||
//**** BehaviorTreeData
|
//**** BehaviorTreeData
|
||||||
|
|
||||||
Array BehaviorTreeData::serialize(const Ref<BTInstance> &p_instance) {
|
Array BehaviorTreeData::serialize(const Ref<BTTask> &p_tree_instance, const NodePath &p_player_path, const String &p_bt_resource_path) {
|
||||||
Array arr;
|
Array arr;
|
||||||
arr.push_back(uint64_t(p_instance->get_instance_id()));
|
arr.push_back(p_player_path);
|
||||||
arr.push_back(p_instance->get_owner_node() ? p_instance->get_owner_node()->get_path() : NodePath());
|
arr.push_back(p_bt_resource_path);
|
||||||
arr.push_back(p_instance->get_source_bt_path());
|
|
||||||
|
|
||||||
// Flatten tree into list depth first
|
// Flatten tree into list depth first
|
||||||
List<Ref<BTTask>> stack;
|
List<Ref<BTTask>> stack;
|
||||||
stack.push_back(p_instance->get_root_task());
|
stack.push_back(p_tree_instance);
|
||||||
while (stack.size()) {
|
while (stack.size()) {
|
||||||
Ref<BTTask> task = stack.front()->get();
|
Ref<BTTask> task = stack.front()->get();
|
||||||
stack.pop_front();
|
stack.pop_front();
|
||||||
|
@ -55,17 +54,15 @@ Array BehaviorTreeData::serialize(const Ref<BTInstance> &p_instance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BehaviorTreeData> BehaviorTreeData::deserialize(const Array &p_array) {
|
Ref<BehaviorTreeData> BehaviorTreeData::deserialize(const Array &p_array) {
|
||||||
ERR_FAIL_COND_V(p_array.size() < 3, nullptr);
|
ERR_FAIL_COND_V(p_array.size() < 2, nullptr);
|
||||||
ERR_FAIL_COND_V(p_array[0].get_type() != Variant::INT, nullptr);
|
ERR_FAIL_COND_V(p_array[0].get_type() != Variant::NODE_PATH, nullptr);
|
||||||
ERR_FAIL_COND_V(p_array[1].get_type() != Variant::NODE_PATH, nullptr);
|
ERR_FAIL_COND_V(p_array[1].get_type() != Variant::STRING, nullptr);
|
||||||
ERR_FAIL_COND_V(p_array[2].get_type() != Variant::STRING, nullptr);
|
|
||||||
|
|
||||||
Ref<BehaviorTreeData> data = memnew(BehaviorTreeData);
|
Ref<BehaviorTreeData> data = memnew(BehaviorTreeData);
|
||||||
data->bt_instance_id = uint64_t(p_array[0]);
|
data->bt_player_path = p_array[0];
|
||||||
data->node_owner_path = p_array[1];
|
data->bt_resource_path = p_array[1];
|
||||||
data->source_bt_path = p_array[2];
|
|
||||||
|
|
||||||
int idx = 3;
|
int idx = 2;
|
||||||
while (p_array.size() > idx + 1) {
|
while (p_array.size() > idx + 1) {
|
||||||
ERR_FAIL_COND_V(p_array.size() < idx + 7, nullptr);
|
ERR_FAIL_COND_V(p_array.size() < idx + 7, nullptr);
|
||||||
ERR_FAIL_COND_V(p_array[idx].get_type() != Variant::INT, nullptr);
|
ERR_FAIL_COND_V(p_array[idx].get_type() != Variant::INT, nullptr);
|
||||||
|
@ -83,16 +80,12 @@ Ref<BehaviorTreeData> BehaviorTreeData::deserialize(const Array &p_array) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BehaviorTreeData> BehaviorTreeData::create_from_bt_instance(const Ref<BTInstance> &p_bt_instance) {
|
Ref<BehaviorTreeData> BehaviorTreeData::create_from_tree_instance(const Ref<BTTask> &p_tree_instance) {
|
||||||
Ref<BehaviorTreeData> data = memnew(BehaviorTreeData);
|
Ref<BehaviorTreeData> data = memnew(BehaviorTreeData);
|
||||||
|
|
||||||
data->bt_instance_id = p_bt_instance->get_instance_id();
|
|
||||||
data->node_owner_path = p_bt_instance->get_owner_node() ? p_bt_instance->get_owner_node()->get_path() : NodePath();
|
|
||||||
data->source_bt_path = p_bt_instance->get_source_bt_path();
|
|
||||||
|
|
||||||
// Flatten tree into list depth first
|
// Flatten tree into list depth first
|
||||||
List<Ref<BTTask>> stack;
|
List<Ref<BTTask>> stack;
|
||||||
stack.push_back(p_bt_instance->get_root_task());
|
stack.push_back(p_tree_instance);
|
||||||
while (stack.size()) {
|
while (stack.size()) {
|
||||||
Ref<BTTask> task = stack.front()->get();
|
Ref<BTTask> task = stack.front()->get();
|
||||||
stack.pop_front();
|
stack.pop_front();
|
||||||
|
@ -122,7 +115,9 @@ Ref<BehaviorTreeData> BehaviorTreeData::create_from_bt_instance(const Ref<BTInst
|
||||||
}
|
}
|
||||||
|
|
||||||
void BehaviorTreeData::_bind_methods() {
|
void BehaviorTreeData::_bind_methods() {
|
||||||
ClassDB::bind_static_method("BehaviorTreeData", D_METHOD("create_from_bt_instance", "bt_instance"), &BehaviorTreeData::create_from_bt_instance);
|
// ClassDB::bind_static_method("BehaviorTreeData", D_METHOD("serialize", "p_tree_instance", "p_player_path", "p_bt_resource_path"), &BehaviorTreeData::serialize);
|
||||||
|
// ClassDB::bind_static_method("BehaviorTreeData", D_METHOD("deserialize", "p_array"), &BehaviorTreeData::deserialize);
|
||||||
|
ClassDB::bind_static_method("BehaviorTreeData", D_METHOD("create_from_tree_instance", "tree_instance"), &BehaviorTreeData::create_from_tree_instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
BehaviorTreeData::BehaviorTreeData() {
|
BehaviorTreeData::BehaviorTreeData() {
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#ifndef BEHAVIOR_TREE_DATA_H
|
#ifndef BEHAVIOR_TREE_DATA_H
|
||||||
#define BEHAVIOR_TREE_DATA_H
|
#define BEHAVIOR_TREE_DATA_H
|
||||||
|
|
||||||
#include "../../bt/bt_instance.h"
|
|
||||||
#include "../../bt/tasks/bt_task.h"
|
#include "../../bt/tasks/bt_task.h"
|
||||||
|
|
||||||
class BehaviorTreeData : public RefCounted {
|
class BehaviorTreeData : public RefCounted {
|
||||||
|
@ -47,14 +46,13 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
List<TaskData> tasks;
|
List<TaskData> tasks;
|
||||||
uint64_t bt_instance_id = 0;
|
NodePath bt_player_path;
|
||||||
NodePath node_owner_path;
|
String bt_resource_path;
|
||||||
String source_bt_path;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Array serialize(const Ref<BTInstance> &p_instance);
|
static Array serialize(const Ref<BTTask> &p_tree_instance, const NodePath &p_player_path, const String &p_bt_resource_path);
|
||||||
static Ref<BehaviorTreeData> deserialize(const Array &p_array);
|
static Ref<BehaviorTreeData> deserialize(const Array &p_array);
|
||||||
static Ref<BehaviorTreeData> create_from_bt_instance(const Ref<BTInstance> &p_bt_instance);
|
static Ref<BehaviorTreeData> create_from_tree_instance(const Ref<BTTask> &p_tree_instance);
|
||||||
|
|
||||||
BehaviorTreeData();
|
BehaviorTreeData();
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,13 +11,13 @@
|
||||||
|
|
||||||
#include "limbo_debugger.h"
|
#include "limbo_debugger.h"
|
||||||
|
|
||||||
#include "../../bt/bt_instance.h"
|
|
||||||
#include "../../bt/tasks/bt_task.h"
|
#include "../../bt/tasks/bt_task.h"
|
||||||
#include "../../util/limbo_compat.h"
|
#include "../../util/limbo_compat.h"
|
||||||
#include "behavior_tree_data.h"
|
#include "behavior_tree_data.h"
|
||||||
|
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
#include "core/debugger/engine_debugger.h"
|
#include "core/debugger/engine_debugger.h"
|
||||||
|
#include "core/error/error_macros.h"
|
||||||
#include "core/io/resource.h"
|
#include "core/io/resource.h"
|
||||||
#include "core/string/node_path.h"
|
#include "core/string/node_path.h"
|
||||||
#include "scene/main/scene_tree.h"
|
#include "scene/main/scene_tree.h"
|
||||||
|
@ -33,6 +33,9 @@
|
||||||
//**** LimboDebugger
|
//**** LimboDebugger
|
||||||
|
|
||||||
LimboDebugger *LimboDebugger::singleton = nullptr;
|
LimboDebugger *LimboDebugger::singleton = nullptr;
|
||||||
|
LimboDebugger *LimboDebugger::get_singleton() {
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
LimboDebugger::LimboDebugger() {
|
LimboDebugger::LimboDebugger() {
|
||||||
singleton = this;
|
singleton = this;
|
||||||
|
@ -60,6 +63,14 @@ void LimboDebugger::deinitialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebugger::_bind_methods() {
|
void LimboDebugger::_bind_methods() {
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
|
||||||
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
|
ClassDB::bind_method(D_METHOD("parse_message_gdext"), &LimboDebugger::parse_message_gdext);
|
||||||
|
#endif
|
||||||
|
ClassDB::bind_method(D_METHOD("_on_bt_updated", "status", "path"), &LimboDebugger::_on_bt_updated);
|
||||||
|
ClassDB::bind_method(D_METHOD("_on_state_updated", "delta", "path"), &LimboDebugger::_on_state_updated);
|
||||||
|
#endif // ! DEBUG_ENABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
@ -88,96 +99,100 @@ bool LimboDebugger::parse_message_gdext(const String &p_msg, const Array &p_args
|
||||||
}
|
}
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
void LimboDebugger::register_bt_instance(uint64_t p_instance_id) {
|
void LimboDebugger::register_bt_instance(Ref<BTTask> p_instance, NodePath p_player_path) {
|
||||||
ERR_FAIL_COND(p_instance_id == 0);
|
ERR_FAIL_COND(p_instance.is_null());
|
||||||
if (!IS_DEBUGGER_ACTIVE()) {
|
ERR_FAIL_COND(p_player_path.is_empty());
|
||||||
|
if (active_trees.has(p_player_path)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BTInstance *inst = Object::cast_to<BTInstance>(OBJECT_DB_GET_INSTANCE(p_instance_id));
|
active_trees.insert(p_player_path, p_instance);
|
||||||
ERR_FAIL_NULL(inst);
|
|
||||||
ERR_FAIL_COND(!inst->is_instance_valid());
|
|
||||||
|
|
||||||
if (active_bt_instances.has(p_instance_id)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!inst->is_connected(LW_NAME(freed), callable_mp(this, &LimboDebugger::unregister_bt_instance).bind(p_instance_id))) {
|
|
||||||
inst->connect(LW_NAME(freed), callable_mp(this, &LimboDebugger::unregister_bt_instance).bind(p_instance_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
active_bt_instances.insert(p_instance_id);
|
|
||||||
if (session_active) {
|
if (session_active) {
|
||||||
_send_active_bt_players();
|
_send_active_bt_players();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebugger::unregister_bt_instance(uint64_t p_instance_id) {
|
void LimboDebugger::unregister_bt_instance(Ref<BTTask> p_instance, NodePath p_player_path) {
|
||||||
if (!active_bt_instances.has(p_instance_id)) {
|
ERR_FAIL_COND(p_instance.is_null());
|
||||||
return;
|
ERR_FAIL_COND(p_player_path.is_empty());
|
||||||
}
|
ERR_FAIL_COND(!active_trees.has(p_player_path));
|
||||||
|
|
||||||
if (tracked_instance_id == p_instance_id) {
|
if (tracked_player == p_player_path) {
|
||||||
_untrack_tree();
|
_untrack_tree();
|
||||||
}
|
}
|
||||||
active_bt_instances.erase(p_instance_id);
|
active_trees.erase(p_player_path);
|
||||||
|
|
||||||
if (session_active) {
|
if (session_active) {
|
||||||
_send_active_bt_players();
|
_send_active_bt_players();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LimboDebugger::is_active() const {
|
void LimboDebugger::_track_tree(NodePath p_path) {
|
||||||
return IS_DEBUGGER_ACTIVE();
|
ERR_FAIL_COND(!active_trees.has(p_path));
|
||||||
|
|
||||||
|
if (!tracked_player.is_empty()) {
|
||||||
|
_untrack_tree();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebugger::_track_tree(uint64_t p_instance_id) {
|
Node *node = SCENE_TREE()->get_root()->get_node_or_null(p_path);
|
||||||
ERR_FAIL_COND(p_instance_id == 0);
|
ERR_FAIL_COND(node == nullptr);
|
||||||
ERR_FAIL_COND(!active_bt_instances.has(p_instance_id));
|
|
||||||
|
|
||||||
_untrack_tree();
|
tracked_player = p_path;
|
||||||
|
|
||||||
tracked_instance_id = p_instance_id;
|
Ref<Resource> bt = node->get(LW_NAME(behavior_tree));
|
||||||
|
|
||||||
BTInstance *inst = Object::cast_to<BTInstance>(OBJECT_DB_GET_INSTANCE(p_instance_id));
|
if (bt.is_valid()) {
|
||||||
ERR_FAIL_NULL(inst);
|
bt_resource_path = bt->get_path();
|
||||||
inst->connect(LW_NAME(updated), callable_mp(this, &LimboDebugger::_on_bt_instance_updated).bind(p_instance_id));
|
} else {
|
||||||
|
bt_resource_path = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->is_class("BTPlayer")) {
|
||||||
|
node->connect(LW_NAME(updated), callable_mp(this, &LimboDebugger::_on_bt_updated).bind(p_path));
|
||||||
|
} else if (node->is_class("BTState")) {
|
||||||
|
node->connect(LW_NAME(updated), callable_mp(this, &LimboDebugger::_on_state_updated).bind(p_path));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebugger::_untrack_tree() {
|
void LimboDebugger::_untrack_tree() {
|
||||||
if (tracked_instance_id == 0) {
|
if (tracked_player.is_empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BTInstance *inst = Object::cast_to<BTInstance>(OBJECT_DB_GET_INSTANCE(tracked_instance_id));
|
NodePath was_tracking = tracked_player;
|
||||||
if (inst) {
|
tracked_player = NodePath();
|
||||||
inst->disconnect(LW_NAME(updated), callable_mp(this, &LimboDebugger::_on_bt_instance_updated));
|
|
||||||
|
Node *node = SCENE_TREE()->get_root()->get_node_or_null(was_tracking);
|
||||||
|
ERR_FAIL_COND(node == nullptr);
|
||||||
|
|
||||||
|
if (node->is_class("BTPlayer")) {
|
||||||
|
node->disconnect(LW_NAME(updated), callable_mp(this, &LimboDebugger::_on_bt_updated));
|
||||||
|
} else if (node->is_class("BTState")) {
|
||||||
|
node->disconnect(LW_NAME(updated), callable_mp(this, &LimboDebugger::_on_state_updated));
|
||||||
}
|
}
|
||||||
tracked_instance_id = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebugger::_send_active_bt_players() {
|
void LimboDebugger::_send_active_bt_players() {
|
||||||
Array arr;
|
Array arr;
|
||||||
for (uint64_t instance_id : active_bt_instances) {
|
for (KeyValue<NodePath, Ref<BTTask>> kv : active_trees) {
|
||||||
arr.append(instance_id);
|
arr.append(kv.key);
|
||||||
BTInstance *inst = Object::cast_to<BTInstance>(OBJECT_DB_GET_INSTANCE(instance_id));
|
|
||||||
if (inst == nullptr) {
|
|
||||||
ERR_PRINT("LimboDebugger::_send_active_bt_players: Registered BTInstance not found (no longer exists?).");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Node *owner_node = inst->get_owner_node();
|
|
||||||
arr.append(owner_node ? owner_node->get_path() : NodePath());
|
|
||||||
}
|
}
|
||||||
EngineDebugger::get_singleton()->send_message("limboai:active_bt_players", arr);
|
EngineDebugger::get_singleton()->send_message("limboai:active_bt_players", arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebugger::_on_bt_instance_updated(int _status, uint64_t p_instance_id) {
|
void LimboDebugger::_on_bt_updated(int _status, NodePath p_path) {
|
||||||
if (p_instance_id != tracked_instance_id) {
|
if (p_path != tracked_player) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BTInstance *inst = Object::cast_to<BTInstance>(OBJECT_DB_GET_INSTANCE(p_instance_id));
|
Array arr = BehaviorTreeData::serialize(active_trees.get(tracked_player), tracked_player, bt_resource_path);
|
||||||
ERR_FAIL_NULL(inst);
|
EngineDebugger::get_singleton()->send_message("limboai:bt_update", arr);
|
||||||
Array arr = BehaviorTreeData::serialize(inst);
|
}
|
||||||
|
|
||||||
|
void LimboDebugger::_on_state_updated(float _delta, NodePath p_path) {
|
||||||
|
if (p_path != tracked_player) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Array arr = BehaviorTreeData::serialize(active_trees.get(tracked_player), tracked_player, bt_resource_path);
|
||||||
EngineDebugger::get_singleton()->send_message("limboai:bt_update", arr);
|
EngineDebugger::get_singleton()->send_message("limboai:bt_update", arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#ifndef LIMBO_DEBUGGER_H
|
#ifndef LIMBO_DEBUGGER_H
|
||||||
#define LIMBO_DEBUGGER_H
|
#define LIMBO_DEBUGGER_H
|
||||||
|
|
||||||
#include "../../bt/bt_instance.h"
|
|
||||||
#include "../../bt/tasks/bt_task.h"
|
#include "../../bt/tasks/bt_task.h"
|
||||||
|
|
||||||
#ifdef LIMBOAI_MODULE
|
#ifdef LIMBOAI_MODULE
|
||||||
|
@ -24,7 +23,6 @@
|
||||||
#ifdef LIMBOAI_GDEXTENSION
|
#ifdef LIMBOAI_GDEXTENSION
|
||||||
#include <godot_cpp/classes/object.hpp>
|
#include <godot_cpp/classes/object.hpp>
|
||||||
#include <godot_cpp/core/class_db.hpp>
|
#include <godot_cpp/core/class_db.hpp>
|
||||||
#include <godot_cpp/templates/hash_set.hpp>
|
|
||||||
#include <godot_cpp/variant/node_path.hpp>
|
#include <godot_cpp/variant/node_path.hpp>
|
||||||
#endif // LIMBOAI_GDEXTENSION
|
#endif // LIMBOAI_GDEXTENSION
|
||||||
|
|
||||||
|
@ -39,7 +37,7 @@ private:
|
||||||
public:
|
public:
|
||||||
static void initialize();
|
static void initialize();
|
||||||
static void deinitialize();
|
static void deinitialize();
|
||||||
_FORCE_INLINE_ static LimboDebugger *get_singleton() { return singleton; }
|
static LimboDebugger *get_singleton();
|
||||||
|
|
||||||
~LimboDebugger();
|
~LimboDebugger();
|
||||||
|
|
||||||
|
@ -48,15 +46,17 @@ protected:
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
private:
|
private:
|
||||||
HashSet<uint64_t> active_bt_instances;
|
HashMap<NodePath, Ref<BTTask>> active_trees;
|
||||||
uint64_t tracked_instance_id = 0;
|
NodePath tracked_player;
|
||||||
|
String bt_resource_path;
|
||||||
bool session_active = false;
|
bool session_active = false;
|
||||||
|
|
||||||
void _track_tree(uint64_t p_instance_id);
|
void _track_tree(NodePath p_path);
|
||||||
void _untrack_tree();
|
void _untrack_tree();
|
||||||
void _send_active_bt_players();
|
void _send_active_bt_players();
|
||||||
|
|
||||||
void _on_bt_instance_updated(int status, uint64_t p_instance_id);
|
void _on_bt_updated(int status, NodePath p_path);
|
||||||
|
void _on_state_updated(float _delta, NodePath p_path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Error parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured);
|
static Error parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured);
|
||||||
|
@ -64,9 +64,8 @@ public:
|
||||||
bool parse_message_gdext(const String &p_msg, const Array &p_args);
|
bool parse_message_gdext(const String &p_msg, const Array &p_args);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void register_bt_instance(uint64_t p_instance_id);
|
void register_bt_instance(Ref<BTTask> p_instance, NodePath p_player_path);
|
||||||
void unregister_bt_instance(uint64_t p_instance_id);
|
void unregister_bt_instance(Ref<BTTask> p_instance, NodePath p_player_path);
|
||||||
bool is_active() const;
|
|
||||||
|
|
||||||
#endif // ! DEBUG_ENABLED
|
#endif // ! DEBUG_ENABLED
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
//**** LimboDebuggerTab
|
//**** LimboDebuggerTab
|
||||||
|
|
||||||
void LimboDebuggerTab::_reset_controls() {
|
void LimboDebuggerTab::_reset_controls() {
|
||||||
bt_instance_list->clear();
|
bt_player_list->clear();
|
||||||
bt_view->clear();
|
bt_view->clear();
|
||||||
alert_box->hide();
|
alert_box->hide();
|
||||||
info_message->set_text(TTR("Run project to start debugging."));
|
info_message->set_text(TTR("Run project to start debugging."));
|
||||||
|
@ -68,7 +68,7 @@ void LimboDebuggerTab::_reset_controls() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebuggerTab::start_session() {
|
void LimboDebuggerTab::start_session() {
|
||||||
bt_instance_list->clear();
|
bt_player_list->clear();
|
||||||
bt_view->clear();
|
bt_view->clear();
|
||||||
alert_box->hide();
|
alert_box->hide();
|
||||||
info_message->set_text(TTR("Pick a player from the list to display behavior tree."));
|
info_message->set_text(TTR("Pick a player from the list to display behavior tree."));
|
||||||
|
@ -81,25 +81,23 @@ void LimboDebuggerTab::stop_session() {
|
||||||
session->send_message("limboai:stop_session", Array());
|
session->send_message("limboai:stop_session", Array());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebuggerTab::update_active_bt_instances(const Array &p_data) {
|
void LimboDebuggerTab::update_active_bt_players(const Array &p_node_paths) {
|
||||||
active_bt_instances.clear();
|
active_bt_players.clear();
|
||||||
for (int i = 0; i < p_data.size(); i += 2) {
|
for (int i = 0; i < p_node_paths.size(); i++) {
|
||||||
BTInstanceInfo info{ p_data[i], p_data[i + 1] };
|
active_bt_players.push_back(p_node_paths[i]);
|
||||||
|
|
||||||
active_bt_instances.push_back(info);
|
|
||||||
}
|
}
|
||||||
_update_bt_instance_list(active_bt_instances, filter_players->get_text());
|
_update_bt_player_list(active_bt_players, filter_players->get_text());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t LimboDebuggerTab::get_selected_bt_instance_id() {
|
String LimboDebuggerTab::get_selected_bt_player() {
|
||||||
if (!bt_instance_list->is_anything_selected()) {
|
if (!bt_player_list->is_anything_selected()) {
|
||||||
return 0;
|
return "";
|
||||||
}
|
}
|
||||||
return bt_instance_list->get_item_metadata(bt_instance_list->get_selected_items()[0]);
|
return bt_player_list->get_item_text(bt_player_list->get_selected_items()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebuggerTab::update_behavior_tree(const Ref<BehaviorTreeData> &p_data) {
|
void LimboDebuggerTab::update_behavior_tree(const Ref<BehaviorTreeData> &p_data) {
|
||||||
resource_header->set_text(p_data->source_bt_path);
|
resource_header->set_text(p_data->bt_resource_path);
|
||||||
resource_header->set_disabled(false);
|
resource_header->set_disabled(false);
|
||||||
bt_view->update_tree(p_data);
|
bt_view->update_tree(p_data);
|
||||||
info_message->hide();
|
info_message->hide();
|
||||||
|
@ -110,58 +108,58 @@ void LimboDebuggerTab::_show_alert(const String &p_message) {
|
||||||
alert_box->set_visible(!p_message.is_empty());
|
alert_box->set_visible(!p_message.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebuggerTab::_update_bt_instance_list(const Vector<BTInstanceInfo> &p_instances, const String &p_filter) {
|
void LimboDebuggerTab::_update_bt_player_list(const List<String> &p_node_paths, const String &p_filter) {
|
||||||
// Remember selected item.
|
// Remember selected item.
|
||||||
uint64_t selected_instance_id = 0;
|
String selected_player = "";
|
||||||
if (bt_instance_list->is_anything_selected()) {
|
if (bt_player_list->is_anything_selected()) {
|
||||||
selected_instance_id = uint64_t(bt_instance_list->get_item_metadata(bt_instance_list->get_selected_items()[0]));
|
selected_player = bt_player_list->get_item_text(bt_player_list->get_selected_items()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_instance_list->clear();
|
bt_player_list->clear();
|
||||||
int select_idx = -1;
|
int select_idx = -1;
|
||||||
bool selection_filtered_out = false;
|
bool selection_filtered_out = false;
|
||||||
for (const BTInstanceInfo &info : p_instances) {
|
for (const String &p : p_node_paths) {
|
||||||
if (p_filter.is_empty() || info.owner_node_path.contains(p_filter)) {
|
if (p_filter.is_empty() || p.contains(p_filter)) {
|
||||||
int idx = bt_instance_list->add_item(info.owner_node_path);
|
int idx = bt_player_list->add_item(p);
|
||||||
bt_instance_list->set_item_metadata(idx, info.instance_id);
|
|
||||||
// Make item text shortened from the left, e.g ".../Agent/BTPlayer".
|
// Make item text shortened from the left, e.g ".../Agent/BTPlayer".
|
||||||
bt_instance_list->set_item_text_direction(idx, TEXT_DIRECTION_RTL);
|
bt_player_list->set_item_text_direction(idx, TEXT_DIRECTION_RTL);
|
||||||
if (info.instance_id == selected_instance_id) {
|
if (p == selected_player) {
|
||||||
select_idx = idx;
|
select_idx = idx;
|
||||||
}
|
}
|
||||||
} else if (info.instance_id == selected_instance_id) {
|
} else if (p == selected_player) {
|
||||||
selection_filtered_out = true;
|
selection_filtered_out = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore selected item.
|
// Restore selected item.
|
||||||
if (select_idx > -1) {
|
if (select_idx > -1) {
|
||||||
bt_instance_list->select(select_idx);
|
bt_player_list->select(select_idx);
|
||||||
} else if (selected_instance_id != 0) {
|
} else if (!selected_player.is_empty()) {
|
||||||
if (selection_filtered_out) {
|
if (selection_filtered_out) {
|
||||||
session->send_message("limboai:untrack_bt_player", Array());
|
session->send_message("limboai:untrack_bt_player", Array());
|
||||||
bt_view->clear();
|
bt_view->clear();
|
||||||
_show_alert("");
|
_show_alert("");
|
||||||
} else {
|
} else {
|
||||||
_show_alert(TTR("Behavior tree instance is no longer present."));
|
_show_alert("BehaviorTree player is no longer present.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebuggerTab::_bt_instance_selected(int p_idx) {
|
void LimboDebuggerTab::_bt_selected(int p_idx) {
|
||||||
alert_box->hide();
|
alert_box->hide();
|
||||||
bt_view->clear();
|
bt_view->clear();
|
||||||
info_message->set_text(TTR("Waiting for behavior tree update."));
|
info_message->set_text(TTR("Waiting for behavior tree update."));
|
||||||
info_message->show();
|
info_message->show();
|
||||||
resource_header->set_text(TTR("Waiting for data"));
|
resource_header->set_text(TTR("Waiting for data"));
|
||||||
resource_header->set_disabled(true);
|
resource_header->set_disabled(true);
|
||||||
|
NodePath path = bt_player_list->get_item_text(p_idx);
|
||||||
Array msg_data;
|
Array msg_data;
|
||||||
msg_data.push_back(bt_instance_list->get_item_metadata(p_idx));
|
msg_data.push_back(path);
|
||||||
session->send_message("limboai:track_bt_player", msg_data);
|
session->send_message("limboai:track_bt_player", msg_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebuggerTab::_filter_changed(String p_text) {
|
void LimboDebuggerTab::_filter_changed(String p_text) {
|
||||||
_update_bt_instance_list(active_bt_instances, p_text);
|
_update_bt_player_list(active_bt_players, p_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimboDebuggerTab::_window_visibility_changed(bool p_visible) {
|
void LimboDebuggerTab::_window_visibility_changed(bool p_visible) {
|
||||||
|
@ -187,7 +185,7 @@ void LimboDebuggerTab::_notification(int p_what) {
|
||||||
case NOTIFICATION_READY: {
|
case NOTIFICATION_READY: {
|
||||||
resource_header->connect(LW_NAME(pressed), callable_mp(this, &LimboDebuggerTab::_resource_header_pressed));
|
resource_header->connect(LW_NAME(pressed), callable_mp(this, &LimboDebuggerTab::_resource_header_pressed));
|
||||||
filter_players->connect(LW_NAME(text_changed), callable_mp(this, &LimboDebuggerTab::_filter_changed));
|
filter_players->connect(LW_NAME(text_changed), callable_mp(this, &LimboDebuggerTab::_filter_changed));
|
||||||
bt_instance_list->connect(LW_NAME(item_selected), callable_mp(this, &LimboDebuggerTab::_bt_instance_selected));
|
bt_player_list->connect(LW_NAME(item_selected), callable_mp(this, &LimboDebuggerTab::_bt_selected));
|
||||||
update_interval->connect("value_changed", callable_mp(bt_view, &BehaviorTreeView::set_update_interval_msec));
|
update_interval->connect("value_changed", callable_mp(bt_view, &BehaviorTreeView::set_update_interval_msec));
|
||||||
|
|
||||||
Ref<ConfigFile> cf;
|
Ref<ConfigFile> cf;
|
||||||
|
@ -273,11 +271,11 @@ LimboDebuggerTab::LimboDebuggerTab() {
|
||||||
filter_players->set_placeholder(TTR("Filter Players"));
|
filter_players->set_placeholder(TTR("Filter Players"));
|
||||||
list_box->add_child(filter_players);
|
list_box->add_child(filter_players);
|
||||||
|
|
||||||
bt_instance_list = memnew(ItemList);
|
bt_player_list = memnew(ItemList);
|
||||||
bt_instance_list->set_custom_minimum_size(Size2(240.0 * EDSCALE, 0.0));
|
bt_player_list->set_custom_minimum_size(Size2(240.0 * EDSCALE, 0.0));
|
||||||
bt_instance_list->set_h_size_flags(SIZE_FILL);
|
bt_player_list->set_h_size_flags(SIZE_FILL);
|
||||||
bt_instance_list->set_v_size_flags(SIZE_EXPAND_FILL);
|
bt_player_list->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||||
list_box->add_child(bt_instance_list);
|
list_box->add_child(bt_player_list);
|
||||||
|
|
||||||
view_box = memnew(VBoxContainer);
|
view_box = memnew(VBoxContainer);
|
||||||
hsc->add_child(view_box);
|
hsc->add_child(view_box);
|
||||||
|
@ -354,10 +352,10 @@ bool LimboDebuggerPlugin::_capture(const String &p_message, const Array &p_data,
|
||||||
ERR_FAIL_NULL_V(tab, false);
|
ERR_FAIL_NULL_V(tab, false);
|
||||||
bool captured = true;
|
bool captured = true;
|
||||||
if (p_message == "limboai:active_bt_players") {
|
if (p_message == "limboai:active_bt_players") {
|
||||||
tab->update_active_bt_instances(p_data);
|
tab->update_active_bt_players(p_data);
|
||||||
} else if (p_message == "limboai:bt_update") {
|
} else if (p_message == "limboai:bt_update") {
|
||||||
Ref<BehaviorTreeData> data = BehaviorTreeData::deserialize(p_data);
|
Ref<BehaviorTreeData> data = BehaviorTreeData::deserialize(p_data);
|
||||||
if (data->bt_instance_id == tab->get_selected_bt_instance_id()) {
|
if (data->bt_player_path == NodePath(tab->get_selected_bt_player())) {
|
||||||
tab->update_behavior_tree(data);
|
tab->update_behavior_tree(data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -51,18 +51,13 @@ class LimboDebuggerTab : public PanelContainer {
|
||||||
GDCLASS(LimboDebuggerTab, PanelContainer);
|
GDCLASS(LimboDebuggerTab, PanelContainer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct BTInstanceInfo {
|
List<String> active_bt_players;
|
||||||
uint64_t instance_id = 0;
|
|
||||||
String owner_node_path;
|
|
||||||
};
|
|
||||||
|
|
||||||
Vector<BTInstanceInfo> active_bt_instances;
|
|
||||||
Ref<EditorDebuggerSession> session;
|
Ref<EditorDebuggerSession> session;
|
||||||
VBoxContainer *root_vb = nullptr;
|
VBoxContainer *root_vb = nullptr;
|
||||||
HBoxContainer *toolbar = nullptr;
|
HBoxContainer *toolbar = nullptr;
|
||||||
HSplitContainer *hsc = nullptr;
|
HSplitContainer *hsc = nullptr;
|
||||||
Label *info_message = nullptr;
|
Label *info_message = nullptr;
|
||||||
ItemList *bt_instance_list = nullptr;
|
ItemList *bt_player_list = nullptr;
|
||||||
BehaviorTreeView *bt_view = nullptr;
|
BehaviorTreeView *bt_view = nullptr;
|
||||||
VBoxContainer *view_box = nullptr;
|
VBoxContainer *view_box = nullptr;
|
||||||
HBoxContainer *alert_box = nullptr;
|
HBoxContainer *alert_box = nullptr;
|
||||||
|
@ -76,8 +71,8 @@ private:
|
||||||
|
|
||||||
void _reset_controls();
|
void _reset_controls();
|
||||||
void _show_alert(const String &p_message);
|
void _show_alert(const String &p_message);
|
||||||
void _update_bt_instance_list(const Vector<BTInstanceInfo> &p_instances, const String &p_filter);
|
void _update_bt_player_list(const List<String> &p_node_paths, const String &p_filter);
|
||||||
void _bt_instance_selected(int p_idx);
|
void _bt_selected(int p_idx);
|
||||||
void _filter_changed(String p_text);
|
void _filter_changed(String p_text);
|
||||||
void _window_visibility_changed(bool p_visible);
|
void _window_visibility_changed(bool p_visible);
|
||||||
void _resource_header_pressed();
|
void _resource_header_pressed();
|
||||||
|
@ -89,9 +84,9 @@ protected:
|
||||||
public:
|
public:
|
||||||
void start_session();
|
void start_session();
|
||||||
void stop_session();
|
void stop_session();
|
||||||
void update_active_bt_instances(const Array &p_data);
|
void update_active_bt_players(const Array &p_node_paths);
|
||||||
BehaviorTreeView *get_behavior_tree_view() const { return bt_view; }
|
BehaviorTreeView *get_behavior_tree_view() const { return bt_view; }
|
||||||
uint64_t get_selected_bt_instance_id();
|
String get_selected_bt_player();
|
||||||
void update_behavior_tree(const Ref<BehaviorTreeData> &p_data);
|
void update_behavior_tree(const Ref<BehaviorTreeData> &p_data);
|
||||||
|
|
||||||
void setup(Ref<EditorDebuggerSession> p_session, CompatWindowWrapper *p_wrapper);
|
void setup(Ref<EditorDebuggerSession> p_session, CompatWindowWrapper *p_wrapper);
|
||||||
|
|
|
@ -148,7 +148,6 @@ void initialize_limboai_module(ModuleInitializationLevel p_level) {
|
||||||
GDREGISTER_ABSTRACT_CLASS(BT);
|
GDREGISTER_ABSTRACT_CLASS(BT);
|
||||||
GDREGISTER_ABSTRACT_CLASS(BTTask);
|
GDREGISTER_ABSTRACT_CLASS(BTTask);
|
||||||
GDREGISTER_CLASS(BehaviorTree);
|
GDREGISTER_CLASS(BehaviorTree);
|
||||||
GDREGISTER_CLASS(BTInstance);
|
|
||||||
GDREGISTER_CLASS(BTPlayer);
|
GDREGISTER_CLASS(BTPlayer);
|
||||||
GDREGISTER_CLASS(BTState);
|
GDREGISTER_CLASS(BTState);
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
#define GET_SCRIPT(m_obj) (m_obj->get_script_instance() ? m_obj->get_script_instance()->get_script() : nullptr)
|
#define GET_SCRIPT(m_obj) (m_obj->get_script_instance() ? m_obj->get_script_instance()->get_script() : nullptr)
|
||||||
#define ADD_STYLEBOX_OVERRIDE(m_control, m_name, m_stylebox) (m_control->add_theme_style_override(m_name, m_stylebox))
|
#define ADD_STYLEBOX_OVERRIDE(m_control, m_name, m_stylebox) (m_control->add_theme_style_override(m_name, m_stylebox))
|
||||||
#define GET_NODE(m_parent, m_path) m_parent->get_node(m_path)
|
#define GET_NODE(m_parent, m_path) m_parent->get_node(m_path)
|
||||||
#define OBJECT_DB_GET_INSTANCE(m_id) ObjectDB::get_instance(ObjectID(m_id))
|
|
||||||
|
|
||||||
_FORCE_INLINE_ bool OBJECT_HAS_PROPERTY(Object *p_obj, const StringName &p_prop) {
|
_FORCE_INLINE_ bool OBJECT_HAS_PROPERTY(Object *p_obj, const StringName &p_prop) {
|
||||||
bool r_valid;
|
bool r_valid;
|
||||||
|
@ -113,7 +112,6 @@ using namespace godot;
|
||||||
#define GET_SCRIPT(m_obj) (m_obj->get_script())
|
#define GET_SCRIPT(m_obj) (m_obj->get_script())
|
||||||
#define ADD_STYLEBOX_OVERRIDE(m_control, m_name, m_stylebox) (m_control->add_theme_stylebox_override(m_name, m_stylebox))
|
#define ADD_STYLEBOX_OVERRIDE(m_control, m_name, m_stylebox) (m_control->add_theme_stylebox_override(m_name, m_stylebox))
|
||||||
#define GET_NODE(m_parent, m_path) m_parent->get_node_internal(m_path)
|
#define GET_NODE(m_parent, m_path) m_parent->get_node_internal(m_path)
|
||||||
#define OBJECT_DB_GET_INSTANCE(m_id) ObjectDB::get_instance(m_id)
|
|
||||||
|
|
||||||
_FORCE_INLINE_ bool OBJECT_HAS_PROPERTY(Object *p_obj, const StringName &p_prop) {
|
_FORCE_INLINE_ bool OBJECT_HAS_PROPERTY(Object *p_obj, const StringName &p_prop) {
|
||||||
return Variant(p_obj).has_key(p_prop);
|
return Variant(p_obj).has_key(p_prop);
|
||||||
|
|
|
@ -85,7 +85,6 @@ LimboStringNames::LimboStringNames() {
|
||||||
font_color = SN("font_color");
|
font_color = SN("font_color");
|
||||||
font_size = SN("font_size");
|
font_size = SN("font_size");
|
||||||
Forward = SN("Forward");
|
Forward = SN("Forward");
|
||||||
freed = SN("freed");
|
|
||||||
gui_input = SN("gui_input");
|
gui_input = SN("gui_input");
|
||||||
GuiOptionArrow = SN("GuiOptionArrow");
|
GuiOptionArrow = SN("GuiOptionArrow");
|
||||||
GuiTreeArrowDown = SN("GuiTreeArrowDown");
|
GuiTreeArrowDown = SN("GuiTreeArrowDown");
|
||||||
|
|
|
@ -101,7 +101,6 @@ public:
|
||||||
StringName font_size;
|
StringName font_size;
|
||||||
StringName font;
|
StringName font;
|
||||||
StringName Forward;
|
StringName Forward;
|
||||||
StringName freed;
|
|
||||||
StringName gui_input;
|
StringName gui_input;
|
||||||
StringName GuiOptionArrow;
|
StringName GuiOptionArrow;
|
||||||
StringName GuiTreeArrowDown;
|
StringName GuiTreeArrowDown;
|
||||||
|
|
Loading…
Reference in New Issue