Refactor BTTask class

This commit is contained in:
Serhii Snitsaruk 2022-12-17 08:33:18 +01:00
parent c67216c1e1
commit 0ba36cb3dd
11 changed files with 54 additions and 134 deletions

View File

@ -76,7 +76,7 @@ void BTTask::set_custom_name(const String &p_name) {
} }
}; };
void BTTask::initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard) { void BTTask::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) {
ERR_FAIL_COND(p_agent == nullptr); ERR_FAIL_COND(p_agent == nullptr);
ERR_FAIL_COND(p_blackboard == nullptr); ERR_FAIL_COND(p_blackboard == nullptr);
agent = p_agent; agent = p_agent;
@ -88,12 +88,6 @@ void BTTask::initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard) {
if (!GDVIRTUAL_CALL(_setup)) { if (!GDVIRTUAL_CALL(_setup)) {
_setup(); _setup();
} }
// if (get_script_instance() &&
// get_script_instance()->has_method(LimboStringNames::get_singleton()->_setup)) {
// get_script_instance()->call(LimboStringNames::get_singleton()->_setup);
// } else {
// _setup();
// }
} }
Ref<BTTask> BTTask::clone() const { Ref<BTTask> BTTask::clone() const {
@ -141,37 +135,16 @@ int BTTask::execute(float p_delta) {
if (!GDVIRTUAL_CALL(_enter)) { if (!GDVIRTUAL_CALL(_enter)) {
_enter(); _enter();
} }
// if (get_script_instance() &&
// // get_script_instance()->get_script()->is_valid() &&
// get_script_instance()->has_method(LimboStringNames::get_singleton()->_enter)) {
// get_script_instance()->call(LimboStringNames::get_singleton()->_enter);
// } else {
// _enter();
// }
} }
if (!GDVIRTUAL_CALL(_tick, p_delta, status)) { if (!GDVIRTUAL_CALL(_tick, p_delta, status)) {
status = _tick(p_delta); status = _tick(p_delta);
} }
// if (get_script_instance() &&
// // get_script_instance()->get_script()->is_valid() &&
// get_script_instance()->has_method(LimboStringNames::get_singleton()->_tick)) {
// status = get_script_instance()->call(LimboStringNames::get_singleton()->_tick, Variant(p_delta));
// } else {
// status = _tick(p_delta);
// }
if (status != RUNNING) { if (status != RUNNING) {
if (!GDVIRTUAL_CALL(_exit)) { if (!GDVIRTUAL_CALL(_exit)) {
_exit(); _exit();
} }
// if (get_script_instance() &&
// // get_script_instance()->get_script()->is_valid() &&
// get_script_instance()->has_method(LimboStringNames::get_singleton()->_exit)) {
// get_script_instance()->call(LimboStringNames::get_singleton()->_exit);
// } else {
// _exit();
// }
} }
return status; return status;
} }
@ -184,13 +157,6 @@ void BTTask::cancel() {
if (!GDVIRTUAL_CALL(_exit)) { if (!GDVIRTUAL_CALL(_exit)) {
_exit(); _exit();
} }
// if (get_script_instance() &&
// // get_script_instance()->get_script()->is_valid() &&
// get_script_instance()->has_method(LimboStringNames::get_singleton()->_exit)) {
// get_script_instance()->call(LimboStringNames::get_singleton()->_exit);
// } else {
// _exit();
// }
} }
status = FRESH; status = FRESH;
} }
@ -270,10 +236,6 @@ String BTTask::get_configuration_warning() const {
String warning = ""; String warning = "";
GDVIRTUAL_CALL(_get_configuration_warning, warning); GDVIRTUAL_CALL(_get_configuration_warning, warning);
// if (get_script_instance() &&
// get_script_instance()->has_method(LimboStringNames::get_singleton()->_get_configuration_warning)) {
// warning = get_script_instance()->call(LimboStringNames::get_singleton()->_get_configuration_warning);
// }
return warning; return warning;
} }
@ -290,43 +252,6 @@ void BTTask::print_tree(int p_initial_tabs) const {
} }
void BTTask::_bind_methods() { void BTTask::_bind_methods() {
// Properties.
ClassDB::bind_method(D_METHOD("get_custom_name"), &BTTask::get_custom_name);
ClassDB::bind_method(D_METHOD("set_custom_name", "p_name"), &BTTask::set_custom_name);
ClassDB::bind_method(D_METHOD("get_agent"), &BTTask::get_agent);
ClassDB::bind_method(D_METHOD("set_agent", "p_agent"), &BTTask::set_agent);
ClassDB::bind_method(D_METHOD("_get_children"), &BTTask::_get_children);
ClassDB::bind_method(D_METHOD("_set_children", "p_children"), &BTTask::_set_children);
ClassDB::bind_method(D_METHOD("get_blackboard"), &BTTask::get_blackboard);
ClassDB::bind_method(D_METHOD("get_parent"), &BTTask::get_parent);
ClassDB::bind_method(D_METHOD("get_status"), &BTTask::get_status);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "custom_name"), "set_custom_name", "get_custom_name");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "agent", PROPERTY_HINT_RESOURCE_TYPE, "Object", 0), "set_agent", "get_agent");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard", PROPERTY_HINT_RESOURCE_TYPE, "Blackboard", 0), "", "get_blackboard");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "parent", PROPERTY_HINT_RESOURCE_TYPE, "BTTask", 0), "", "get_parent");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "children", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_children", "_get_children");
ADD_PROPERTY(PropertyInfo(Variant::INT, "status", PROPERTY_HINT_NONE, "", 0), "", "get_status");
// Virtual methods.
// TODO: Remove if unneeded.
ClassDB::bind_method(D_METHOD("_setup"), &BTTask::_setup);
ClassDB::bind_method(D_METHOD("_enter"), &BTTask::_enter);
ClassDB::bind_method(D_METHOD("_exit"), &BTTask::_exit);
ClassDB::bind_method(D_METHOD("_tick", "p_delta"), &BTTask::_tick);
ClassDB::bind_method(D_METHOD("_generate_name"), &BTTask::_generate_name);
ClassDB::bind_method(D_METHOD("_get_configuration_warning"), &BTTask::get_configuration_warning);
GDVIRTUAL_BIND(_setup);
GDVIRTUAL_BIND(_enter);
GDVIRTUAL_BIND(_exit);
GDVIRTUAL_BIND(_tick, "p_delta");
GDVIRTUAL_BIND(_generate_name);
GDVIRTUAL_BIND(_get_configuration_warning);
// Public Methods. // Public Methods.
ClassDB::bind_method(D_METHOD("is_root"), &BTTask::is_root); ClassDB::bind_method(D_METHOD("is_root"), &BTTask::is_root);
ClassDB::bind_method(D_METHOD("get_root"), &BTTask::get_root); ClassDB::bind_method(D_METHOD("get_root"), &BTTask::get_root);
@ -345,6 +270,33 @@ void BTTask::_bind_methods() {
ClassDB::bind_method(D_METHOD("next_sibling"), &BTTask::next_sibling); ClassDB::bind_method(D_METHOD("next_sibling"), &BTTask::next_sibling);
ClassDB::bind_method(D_METHOD("print_tree", "p_initial_tabs"), &BTTask::print_tree, Variant(0)); ClassDB::bind_method(D_METHOD("print_tree", "p_initial_tabs"), &BTTask::print_tree, Variant(0));
ClassDB::bind_method(D_METHOD("get_task_name"), &BTTask::get_task_name); ClassDB::bind_method(D_METHOD("get_task_name"), &BTTask::get_task_name);
ClassDB::bind_method(D_METHOD("get_custom_name"), &BTTask::get_custom_name);
ClassDB::bind_method(D_METHOD("set_custom_name", "p_name"), &BTTask::set_custom_name);
// Properties, setters and getters.
ClassDB::bind_method(D_METHOD("get_agent"), &BTTask::get_agent);
ClassDB::bind_method(D_METHOD("set_agent", "p_agent"), &BTTask::set_agent);
ClassDB::bind_method(D_METHOD("_get_children"), &BTTask::_get_children);
ClassDB::bind_method(D_METHOD("_set_children", "p_children"), &BTTask::_set_children);
ClassDB::bind_method(D_METHOD("get_blackboard"), &BTTask::get_blackboard);
ClassDB::bind_method(D_METHOD("get_parent"), &BTTask::get_parent);
ClassDB::bind_method(D_METHOD("get_status"), &BTTask::get_status);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "custom_name"), "set_custom_name", "get_custom_name");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "agent", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_agent", "get_agent");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard", PROPERTY_HINT_RESOURCE_TYPE, "Blackboard", 0), "", "get_blackboard");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "parent", PROPERTY_HINT_RESOURCE_TYPE, "BTTask", 0), "", "get_parent");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "children", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_children", "_get_children");
ADD_PROPERTY(PropertyInfo(Variant::INT, "status", PROPERTY_HINT_NONE, "", 0), "", "get_status");
GDVIRTUAL_BIND(_setup);
GDVIRTUAL_BIND(_enter);
GDVIRTUAL_BIND(_exit);
GDVIRTUAL_BIND(_tick, "p_delta");
GDVIRTUAL_BIND(_generate_name);
GDVIRTUAL_BIND(_get_configuration_warning);
// Enums. // Enums.
ClassDB::bind_integer_constant(get_class_static(), "TaskStatus", "FRESH", FRESH); ClassDB::bind_integer_constant(get_class_static(), "TaskStatus", "FRESH", FRESH);

View File

@ -28,7 +28,7 @@ private:
friend class BehaviorTree; friend class BehaviorTree;
String custom_name; String custom_name;
Object *agent; Node *agent;
Ref<Blackboard> blackboard; Ref<Blackboard> blackboard;
BTTask *parent; BTTask *parent;
Vector<Ref<BTTask>> children; Vector<Ref<BTTask>> children;
@ -54,22 +54,25 @@ protected:
GDVIRTUAL0RC(String, _get_configuration_warning); GDVIRTUAL0RC(String, _get_configuration_warning);
public: public:
Object *get_agent() const { return agent; } Node *get_agent() const { return agent; }
void set_agent(Object *p_agent) { agent = p_agent; } void set_agent(Node *p_agent) { agent = p_agent; }
Ref<Blackboard> get_blackboard() const { return blackboard; }
Ref<BTTask> get_parent() const { return Ref<BTTask>(parent); }
bool is_root() const { return parent == nullptr; }
Ref<BTTask> get_root() const;
int get_status() const { return status; }
String get_custom_name() const { return custom_name; } String get_custom_name() const { return custom_name; }
void set_custom_name(const String &p_name); void set_custom_name(const String &p_name);
String get_task_name() const; String get_task_name() const;
Ref<Blackboard> get_blackboard() const { return blackboard; }
Ref<BTTask> get_parent() const { return Ref<BTTask>(parent); }
Ref<BTTask> get_root() const;
bool is_root() const { return parent == nullptr; }
virtual Ref<BTTask> clone() const; virtual Ref<BTTask> clone() const;
virtual void initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard); virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard);
int execute(float p_delta); int execute(float p_delta);
void cancel(); void cancel();
int get_status() const { return status; }
Ref<BTTask> get_child(int p_idx) const; Ref<BTTask> get_child(int p_idx) const;
int get_child_count() const; int get_child_count() const;
void add_child(Ref<BTTask> p_child); void add_child(Ref<BTTask> p_child);
@ -80,6 +83,7 @@ public:
bool is_descendant_of(const Ref<BTTask> &p_task) const; bool is_descendant_of(const Ref<BTTask> &p_task) const;
int get_child_index(const Ref<BTTask> &p_child) const; int get_child_index(const Ref<BTTask> &p_child) const;
Ref<BTTask> next_sibling() const; Ref<BTTask> next_sibling() const;
virtual String get_configuration_warning() const; virtual String get_configuration_warning() const;
void print_tree(int p_initial_tabs = 0) const; void print_tree(int p_initial_tabs = 0) const;

View File

@ -6,7 +6,7 @@
#include "core/string/ustring.h" #include "core/string/ustring.h"
#include "modules/limboai/blackboard.h" #include "modules/limboai/blackboard.h"
void BTNewScope::initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard) { void BTNewScope::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) {
ERR_FAIL_COND(p_agent == nullptr); ERR_FAIL_COND(p_agent == nullptr);
ERR_FAIL_COND(p_blackboard == nullptr); ERR_FAIL_COND(p_blackboard == nullptr);

View File

@ -22,7 +22,7 @@ protected:
virtual int _tick(float p_delta) override; virtual int _tick(float p_delta) override;
public: public:
virtual void initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard) override; virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) override;
}; };
#endif // BT_NEW_SCOPE_H #endif // BT_NEW_SCOPE_H

View File

@ -25,15 +25,11 @@ String BTSubtree::_generate_name() const {
return vformat("Subtree %s", s); return vformat("Subtree %s", s);
} }
void BTSubtree::initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard) { void BTSubtree::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) {
ERR_FAIL_COND_MSG(!subtree.is_valid(), "Subtree is not assigned."); ERR_FAIL_COND_MSG(!subtree.is_valid(), "Subtree is not assigned.");
ERR_FAIL_COND_MSG(!subtree->get_root_task().is_valid(), "Subtree root task is not valid."); ERR_FAIL_COND_MSG(!subtree->get_root_task().is_valid(), "Subtree root task is not valid.");
ERR_FAIL_COND_MSG(get_child_count() != 0, "Subtree task shouldn't have children during initialization."); ERR_FAIL_COND_MSG(get_child_count() != 0, "Subtree task shouldn't have children during initialization.");
// while (get_child_count() > 0) {
// remove_child_at_index(get_child_count() - 1);
// }
add_child(subtree->get_root_task()->clone()); add_child(subtree->get_root_task()->clone());
BTNewScope::initialize(p_agent, p_blackboard); BTNewScope::initialize(p_agent, p_blackboard);

View File

@ -26,7 +26,7 @@ public:
} }
Ref<BehaviorTree> get_subtree() const { return subtree; } Ref<BehaviorTree> get_subtree() const { return subtree; }
virtual void initialize(Object *p_agent, const Ref<Blackboard> &p_blackboard) override; virtual void initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard) override;
virtual String get_configuration_warning() const override; virtual String get_configuration_warning() const override;
}; };

View File

@ -1,7 +0,0 @@
[gd_scene load_steps=2 format=3 uid="uid://pgnoaj17gaew"]
[ext_resource type="PackedScene" uid="uid://c26b8c8dndtop" path="res://tests/waypoints/Agent.tscn" id="1"]
[node name="Test" type="Node2D"]
[node name="Agent" parent="." instance=ExtResource("1")]

View File

@ -1,21 +0,0 @@
[gd_resource type="BehaviorTree" load_steps=6 format=3 uid="uid://6l0b3cyvwy56"]
[sub_resource type="BTSequence" id="BTSequence_hlsn5"]
custom_name = "3"
[sub_resource type="BTSequence" id="BTSequence_g3hm1"]
custom_name = "2"
children = [SubResource("BTSequence_hlsn5")]
[sub_resource type="BTSequence" id="BTSequence_b0qql"]
custom_name = "4"
[sub_resource type="BTSequence" id="BTSequence_78a5u"]
custom_name = "5"
[sub_resource type="BTSequence" id="1"]
custom_name = "1"
children = [SubResource("BTSequence_g3hm1"), SubResource("BTSequence_b0qql"), SubResource("BTSequence_78a5u")]
[resource]
root_task = SubResource("1")

View File

@ -1,16 +1,16 @@
[gd_resource type="BehaviorTree" load_steps=9 format=3 uid="uid://c5cp2lpww1qcc"] [gd_resource type="BehaviorTree" load_steps=8 format=3 uid="uid://cjkqi41oagagd"]
[ext_resource type="Script" path="res://ai/tasks/arrive_pos.gd" id="1_6wvrl"] [ext_resource type="Script" path="res://ai/tasks/arrive_pos.gd" id="1_rhs33"]
[ext_resource type="Script" path="res://ai/tasks/play_animation.gd" id="2_hcuvn"] [ext_resource type="Script" path="res://ai/tasks/play_animation.gd" id="2_dg0ss"]
[sub_resource type="BTAction" id="BTAction_3xal7"] [sub_resource type="BTAction" id="BTAction_3xal7"]
script = ExtResource("1_6wvrl") script = ExtResource("1_rhs33")
target_position_var = "wp" target_position_var = "wp"
speed_var = "speed" speed_var = "speed"
tolerance = 50.0 tolerance = 50.0
[sub_resource type="BTAction" id="BTAction_yq1vl"] [sub_resource type="BTAction" id="BTAction_yq1vl"]
script = ExtResource("2_hcuvn") script = ExtResource("2_dg0ss")
animation_name = "bounce" animation_name = "bounce"
animation_player = NodePath("AnimationPlayer") animation_player = NodePath("AnimationPlayer")
@ -22,12 +22,8 @@ children = [SubResource("BTSequence_a2ng0")]
array_var = "waypoints" array_var = "waypoints"
save_var = "wp" save_var = "wp"
[sub_resource type="BTRepeat" id="BTRepeat_xljhp"]
children = [SubResource("BTForEach_0cp04")]
times = 999
[sub_resource type="BTSelector" id="BTSelector_5dclr"] [sub_resource type="BTSelector" id="BTSelector_5dclr"]
children = [SubResource("BTRepeat_xljhp")] children = [SubResource("BTForEach_0cp04")]
[resource] [resource]
root_task = SubResource("BTSelector_5dclr") root_task = SubResource("BTSelector_5dclr")

View File

@ -11,7 +11,7 @@ config_version=5
[application] [application]
config/name="LimboAI Test" config/name="LimboAI Test"
run/main_scene="res://Test.tscn" run/main_scene="res://tests/waypoints/test_waypoints.tscn"
config/features=PackedStringArray("4.0") config/features=PackedStringArray("4.0")
config/icon="res://icon.png" config/icon="res://icon.png"

View File

@ -1,7 +1,7 @@
[gd_scene load_steps=7 format=3 uid="uid://c26b8c8dndtop"] [gd_scene load_steps=7 format=3 uid="uid://c26b8c8dndtop"]
[ext_resource type="Script" path="res://tests/waypoints/Agent.gd" id="1_1l3ql"] [ext_resource type="Script" path="res://tests/waypoints/Agent.gd" id="1_1l3ql"]
[ext_resource type="BehaviorTree" uid="uid://c5cp2lpww1qcc" path="res://ai/trees/waypoints_agent.tres" id="2_58ujo"] [ext_resource type="BehaviorTree" uid="uid://cjkqi41oagagd" path="res://ai/trees/waypoints.tres" id="2_ijwrx"]
[ext_resource type="Texture2D" uid="uid://d0mht3ntak7e5" path="res://icon.png" id="2_xqtrc"] [ext_resource type="Texture2D" uid="uid://d0mht3ntak7e5" path="res://icon.png" id="2_xqtrc"]
[sub_resource type="Animation" id="Animation_5id00"] [sub_resource type="Animation" id="Animation_5id00"]
@ -44,7 +44,7 @@ _data = {
script = ExtResource("1_1l3ql") script = ExtResource("1_1l3ql")
[node name="BTPlayer" type="BTPlayer" parent="."] [node name="BTPlayer" type="BTPlayer" parent="."]
behavior_tree = ExtResource("2_58ujo") behavior_tree = ExtResource("2_ijwrx")
_blackboard_data = { _blackboard_data = {
"speed": 500.0 "speed": 500.0
} }