Refactor BTPlayer and BTState
This commit is contained in:
parent
0bb03c2b4c
commit
c67216c1e1
|
@ -5,6 +5,7 @@
|
||||||
#include "../limbo_string_names.h"
|
#include "../limbo_string_names.h"
|
||||||
#include "bt_task.h"
|
#include "bt_task.h"
|
||||||
#include "core/config/engine.h"
|
#include "core/config/engine.h"
|
||||||
|
#include "core/error/error_macros.h"
|
||||||
#include "core/io/resource_loader.h"
|
#include "core/io/resource_loader.h"
|
||||||
#include "core/object/class_db.h"
|
#include "core/object/class_db.h"
|
||||||
#include "core/object/object.h"
|
#include "core/object/object.h"
|
||||||
|
@ -15,23 +16,19 @@
|
||||||
VARIANT_ENUM_CAST(BTPlayer::UpdateMode);
|
VARIANT_ENUM_CAST(BTPlayer::UpdateMode);
|
||||||
|
|
||||||
void BTPlayer::_load_tree() {
|
void BTPlayer::_load_tree() {
|
||||||
_loaded_tree.unref();
|
tree_instance.unref();
|
||||||
_root_task.unref();
|
ERR_FAIL_COND_MSG(!behavior_tree.is_valid(), "BTPlayer: Needs a valid behavior tree.");
|
||||||
ERR_FAIL_COND_MSG(!behavior_tree.is_valid(), "BTPlayer needs a valid behavior tree.");
|
ERR_FAIL_COND_MSG(!behavior_tree->get_root_task().is_valid(), "BTPlayer: Behavior tree has no valid root task.");
|
||||||
ERR_FAIL_COND_MSG(!behavior_tree->get_root_task().is_valid(), "Behavior tree has no valid root task.");
|
|
||||||
_loaded_tree = behavior_tree;
|
|
||||||
if (prefetch_nodepath_vars == true) {
|
if (prefetch_nodepath_vars == true) {
|
||||||
// blackboard->prefetch_nodepath_vars(get_owner());
|
|
||||||
blackboard->prefetch_nodepath_vars(this);
|
blackboard->prefetch_nodepath_vars(this);
|
||||||
}
|
}
|
||||||
_root_task = _loaded_tree->instantiate(get_owner(), blackboard);
|
tree_instance = behavior_tree->instantiate(get_owner(), blackboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTPlayer::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
|
void BTPlayer::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
|
||||||
behavior_tree = p_tree;
|
behavior_tree = p_tree;
|
||||||
if (Engine::get_singleton()->is_editor_hint() == false && get_owner()) {
|
if (Engine::get_singleton()->is_editor_hint() == false && get_owner()) {
|
||||||
_load_tree();
|
_load_tree();
|
||||||
set_update_mode(update_mode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,44 +39,39 @@ void BTPlayer::set_update_mode(UpdateMode p_mode) {
|
||||||
|
|
||||||
void BTPlayer::set_active(bool p_active) {
|
void BTPlayer::set_active(bool p_active) {
|
||||||
active = p_active;
|
active = p_active;
|
||||||
if (!Engine::get_singleton()->is_editor_hint()) {
|
bool is_not_editor = !Engine::get_singleton()->is_editor_hint();
|
||||||
set_process(update_mode == UpdateMode::IDLE);
|
set_process(update_mode == UpdateMode::IDLE && active && is_not_editor);
|
||||||
set_physics_process(update_mode == UpdateMode::PHYSICS);
|
set_physics_process(update_mode == UpdateMode::PHYSICS && active && is_not_editor);
|
||||||
}
|
set_process_input(active && is_not_editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTPlayer::update(float p_delta) {
|
void BTPlayer::update(float p_delta) {
|
||||||
if (!_root_task.is_valid()) {
|
if (!tree_instance.is_valid()) {
|
||||||
ERR_PRINT_ONCE(vformat("BTPlayer has no root task to update (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;
|
||||||
}
|
}
|
||||||
if (active) {
|
if (active) {
|
||||||
int status = _root_task->execute(p_delta);
|
last_status = tree_instance->execute(p_delta);
|
||||||
if (status == BTTask::SUCCESS || status == BTTask::FAILURE) {
|
if (last_status == BTTask::SUCCESS || last_status == BTTask::FAILURE) {
|
||||||
set_active(auto_restart);
|
emit_signal(LimboStringNames::get_singleton()->behavior_tree_finished, last_status);
|
||||||
emit_signal(LimboStringNames::get_singleton()->behavior_tree_finished, status);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTPlayer::restart() {
|
void BTPlayer::restart() {
|
||||||
_root_task->cancel();
|
tree_instance->cancel();
|
||||||
set_active(true);
|
set_active(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTPlayer::_notification(int p_notification) {
|
void BTPlayer::_notification(int p_notification) {
|
||||||
switch (p_notification) {
|
switch (p_notification) {
|
||||||
case NOTIFICATION_PROCESS: {
|
case NOTIFICATION_PROCESS: {
|
||||||
if (active) {
|
|
||||||
Variant time = get_process_delta_time();
|
Variant time = get_process_delta_time();
|
||||||
update(time);
|
update(time);
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_PHYSICS_PROCESS: {
|
case NOTIFICATION_PHYSICS_PROCESS: {
|
||||||
if (active) {
|
|
||||||
Variant time = get_process_delta_time();
|
Variant time = get_process_delta_time();
|
||||||
update(time);
|
update(time);
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_READY: {
|
case NOTIFICATION_READY: {
|
||||||
if (!Engine::get_singleton()->is_editor_hint()) {
|
if (!Engine::get_singleton()->is_editor_hint()) {
|
||||||
|
@ -99,8 +91,6 @@ void BTPlayer::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_update_mode"), &BTPlayer::get_update_mode);
|
ClassDB::bind_method(D_METHOD("get_update_mode"), &BTPlayer::get_update_mode);
|
||||||
ClassDB::bind_method(D_METHOD("set_active", "p_active"), &BTPlayer::set_active);
|
ClassDB::bind_method(D_METHOD("set_active", "p_active"), &BTPlayer::set_active);
|
||||||
ClassDB::bind_method(D_METHOD("get_active"), &BTPlayer::get_active);
|
ClassDB::bind_method(D_METHOD("get_active"), &BTPlayer::get_active);
|
||||||
ClassDB::bind_method(D_METHOD("set_auto_restart", "p_value"), &BTPlayer::set_auto_restart);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_auto_restart"), &BTPlayer::get_auto_restart);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_blackboard", "p_blackboard"), &BTPlayer::set_blackboard);
|
ClassDB::bind_method(D_METHOD("set_blackboard", "p_blackboard"), &BTPlayer::set_blackboard);
|
||||||
ClassDB::bind_method(D_METHOD("get_blackboard"), &BTPlayer::get_blackboard);
|
ClassDB::bind_method(D_METHOD("get_blackboard"), &BTPlayer::get_blackboard);
|
||||||
ClassDB::bind_method(D_METHOD("set_prefetch_nodepath_vars", "p_value"), &BTPlayer::set_prefetch_nodepath_vars);
|
ClassDB::bind_method(D_METHOD("set_prefetch_nodepath_vars", "p_value"), &BTPlayer::set_prefetch_nodepath_vars);
|
||||||
|
@ -111,11 +101,11 @@ void BTPlayer::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("update", "p_delta"), &BTPlayer::update);
|
ClassDB::bind_method(D_METHOD("update", "p_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);
|
||||||
|
|
||||||
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::INT, "update_mode", PROPERTY_HINT_ENUM, "Idle,Physics,Manual"), "set_update_mode", "get_update_mode");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Idle,Physics,Manual"), "set_update_mode", "get_update_mode");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "get_active");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "get_active");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_restart"), "set_auto_restart", "get_auto_restart");
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard", PROPERTY_HINT_NONE, "Blackboard", 0), "", "get_blackboard");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "blackboard", PROPERTY_HINT_NONE, "Blackboard", 0), "", "get_blackboard");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_blackboard_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_blackboard_data", "_get_blackboard_data");
|
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_blackboard_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_blackboard_data", "_get_blackboard_data");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "prefetch_nodepath_vars"), "set_prefetch_nodepath_vars", "get_prefetch_nodepath_vars");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "prefetch_nodepath_vars"), "set_prefetch_nodepath_vars", "get_prefetch_nodepath_vars");
|
||||||
|
|
|
@ -21,14 +21,13 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ref<BehaviorTree> behavior_tree;
|
Ref<BehaviorTree> behavior_tree;
|
||||||
UpdateMode update_mode = UpdateMode::IDLE;
|
UpdateMode update_mode = UpdateMode::PHYSICS;
|
||||||
bool active = false;
|
bool active = true;
|
||||||
bool auto_restart = false;
|
|
||||||
Ref<Blackboard> blackboard;
|
Ref<Blackboard> blackboard;
|
||||||
bool prefetch_nodepath_vars = true;
|
bool prefetch_nodepath_vars = true;
|
||||||
|
int last_status = -1;
|
||||||
|
|
||||||
Ref<BehaviorTree> _loaded_tree;
|
Ref<BTTask> tree_instance;
|
||||||
Ref<BTTask> _root_task;
|
|
||||||
|
|
||||||
void _load_tree();
|
void _load_tree();
|
||||||
|
|
||||||
|
@ -50,9 +49,6 @@ public:
|
||||||
void set_active(bool p_active);
|
void set_active(bool p_active);
|
||||||
bool get_active() const { return active; }
|
bool get_active() const { return active; }
|
||||||
|
|
||||||
void set_auto_restart(bool p_value) { auto_restart = p_value; }
|
|
||||||
bool get_auto_restart() const { return auto_restart; }
|
|
||||||
|
|
||||||
Ref<Blackboard> get_blackboard() const { return blackboard; }
|
Ref<Blackboard> get_blackboard() const { return blackboard; }
|
||||||
void set_blackboard(const Ref<Blackboard> &p_blackboard) { blackboard = p_blackboard; }
|
void set_blackboard(const Ref<Blackboard> &p_blackboard) { blackboard = p_blackboard; }
|
||||||
|
|
||||||
|
@ -61,6 +57,7 @@ public:
|
||||||
|
|
||||||
void update(float p_delta);
|
void update(float p_delta);
|
||||||
void restart();
|
void restart();
|
||||||
|
int get_last_status() const { return last_status; }
|
||||||
|
|
||||||
BTPlayer();
|
BTPlayer();
|
||||||
~BTPlayer();
|
~BTPlayer();
|
||||||
|
|
|
@ -1,21 +1,25 @@
|
||||||
/* bt_state.cpp */
|
/* bt_state.cpp */
|
||||||
|
|
||||||
#include "bt_state.h"
|
#include "bt_state.h"
|
||||||
|
#include "core/error/error_macros.h"
|
||||||
#include "core/object/class_db.h"
|
#include "core/object/class_db.h"
|
||||||
#include "core/variant/variant.h"
|
#include "core/variant/variant.h"
|
||||||
#include "modules/limboai/bt/bt_task.h"
|
#include "modules/limboai/bt/bt_task.h"
|
||||||
#include "modules/limboai/limbo_state.h"
|
#include "modules/limboai/limbo_state.h"
|
||||||
|
|
||||||
void BTState::_setup() {
|
void BTState::_setup() {
|
||||||
root_task = behavior_tree->instantiate(get_agent(), get_blackboard());
|
ERR_FAIL_COND_MSG(behavior_tree.is_null(), "BTState: BehaviorTree is not assigned.");
|
||||||
|
tree_instance = behavior_tree->instantiate(get_agent(), get_blackboard());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTState::_exit() {
|
void BTState::_exit() {
|
||||||
root_task->cancel();
|
ERR_FAIL_COND(tree_instance == nullptr);
|
||||||
|
tree_instance->cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BTState::_update(float p_delta) {
|
void BTState::_update(float p_delta) {
|
||||||
int status = root_task->execute(p_delta);
|
ERR_FAIL_COND(tree_instance == nullptr);
|
||||||
|
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) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ class BTState : public LimboState {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ref<BehaviorTree> behavior_tree;
|
Ref<BehaviorTree> behavior_tree;
|
||||||
Ref<BTTask> root_task;
|
Ref<BTTask> tree_instance;
|
||||||
String success_event;
|
String success_event;
|
||||||
String failure_event;
|
String failure_event;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
virtual void _setup() override;
|
virtual void _setup() override;
|
||||||
virtual void _enter() override {}
|
// virtual void _enter() override {}
|
||||||
virtual void _exit() override;
|
virtual void _exit() override;
|
||||||
virtual void _update(float p_delta) override;
|
virtual void _update(float p_delta) override;
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,6 @@ 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_58ujo")
|
||||||
update_mode = 1
|
|
||||||
active = true
|
|
||||||
_blackboard_data = {
|
_blackboard_data = {
|
||||||
"speed": 500.0
|
"speed": 500.0
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue