diff --git a/bt/bt_player.cpp b/bt/bt_player.cpp index 64bda5a..38472e0 100644 --- a/bt/bt_player.cpp +++ b/bt/bt_player.cpp @@ -5,6 +5,7 @@ #include "../limbo_string_names.h" #include "bt_task.h" #include "core/config/engine.h" +#include "core/error/error_macros.h" #include "core/io/resource_loader.h" #include "core/object/class_db.h" #include "core/object/object.h" @@ -15,23 +16,19 @@ VARIANT_ENUM_CAST(BTPlayer::UpdateMode); void BTPlayer::_load_tree() { - _loaded_tree.unref(); - _root_task.unref(); - 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(), "Behavior tree has no valid root task."); - _loaded_tree = behavior_tree; + tree_instance.unref(); + 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."); if (prefetch_nodepath_vars == true) { - // blackboard->prefetch_nodepath_vars(get_owner()); 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 &p_tree) { behavior_tree = p_tree; if (Engine::get_singleton()->is_editor_hint() == false && get_owner()) { _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) { active = p_active; - if (!Engine::get_singleton()->is_editor_hint()) { - set_process(update_mode == UpdateMode::IDLE); - set_physics_process(update_mode == UpdateMode::PHYSICS); - } + bool is_not_editor = !Engine::get_singleton()->is_editor_hint(); + set_process(update_mode == UpdateMode::IDLE && active && is_not_editor); + set_physics_process(update_mode == UpdateMode::PHYSICS && active && is_not_editor); + set_process_input(active && is_not_editor); } void BTPlayer::update(float p_delta) { - if (!_root_task.is_valid()) { - ERR_PRINT_ONCE(vformat("BTPlayer has no root task to update (owner: %s)", get_owner())); + 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())); return; } if (active) { - int status = _root_task->execute(p_delta); - if (status == BTTask::SUCCESS || status == BTTask::FAILURE) { - set_active(auto_restart); - emit_signal(LimboStringNames::get_singleton()->behavior_tree_finished, status); + last_status = tree_instance->execute(p_delta); + if (last_status == BTTask::SUCCESS || last_status == BTTask::FAILURE) { + emit_signal(LimboStringNames::get_singleton()->behavior_tree_finished, last_status); } } } void BTPlayer::restart() { - _root_task->cancel(); + tree_instance->cancel(); set_active(true); } void BTPlayer::_notification(int p_notification) { switch (p_notification) { case NOTIFICATION_PROCESS: { - if (active) { - Variant time = get_process_delta_time(); - update(time); - } + Variant time = get_process_delta_time(); + update(time); } break; case NOTIFICATION_PHYSICS_PROCESS: { - if (active) { - Variant time = get_process_delta_time(); - update(time); - } + Variant time = get_process_delta_time(); + update(time); } break; case NOTIFICATION_READY: { 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("set_active", "p_active"), &BTPlayer::set_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("get_blackboard"), &BTPlayer::get_blackboard); 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("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::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, "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::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"); diff --git a/bt/bt_player.h b/bt/bt_player.h index 46e4062..b89087b 100644 --- a/bt/bt_player.h +++ b/bt/bt_player.h @@ -21,14 +21,13 @@ public: private: Ref behavior_tree; - UpdateMode update_mode = UpdateMode::IDLE; - bool active = false; - bool auto_restart = false; + UpdateMode update_mode = UpdateMode::PHYSICS; + bool active = true; Ref blackboard; bool prefetch_nodepath_vars = true; + int last_status = -1; - Ref _loaded_tree; - Ref _root_task; + Ref tree_instance; void _load_tree(); @@ -50,9 +49,6 @@ public: void set_active(bool p_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 get_blackboard() const { return blackboard; } void set_blackboard(const Ref &p_blackboard) { blackboard = p_blackboard; } @@ -61,6 +57,7 @@ public: void update(float p_delta); void restart(); + int get_last_status() const { return last_status; } BTPlayer(); ~BTPlayer(); diff --git a/bt/bt_state.cpp b/bt/bt_state.cpp index 9870413..3f79cf3 100644 --- a/bt/bt_state.cpp +++ b/bt/bt_state.cpp @@ -1,21 +1,25 @@ /* bt_state.cpp */ #include "bt_state.h" +#include "core/error/error_macros.h" #include "core/object/class_db.h" #include "core/variant/variant.h" #include "modules/limboai/bt/bt_task.h" #include "modules/limboai/limbo_state.h" 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() { - root_task->cancel(); + ERR_FAIL_COND(tree_instance == nullptr); + tree_instance->cancel(); } 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) { get_root()->dispatch(success_event, Variant()); } else if (status == BTTask::FAILURE) { diff --git a/bt/bt_state.h b/bt/bt_state.h index 51fc677..5f97311 100644 --- a/bt/bt_state.h +++ b/bt/bt_state.h @@ -13,7 +13,7 @@ class BTState : public LimboState { private: Ref behavior_tree; - Ref root_task; + Ref tree_instance; String success_event; String failure_event; @@ -21,7 +21,7 @@ protected: static void _bind_methods(); virtual void _setup() override; - virtual void _enter() override {} + // virtual void _enter() override {} virtual void _exit() override; virtual void _update(float p_delta) override; diff --git a/test/tests/waypoints/Agent.tscn b/test/tests/waypoints/Agent.tscn index 4e610d0..cc8b406 100644 --- a/test/tests/waypoints/Agent.tscn +++ b/test/tests/waypoints/Agent.tscn @@ -45,8 +45,6 @@ script = ExtResource("1_1l3ql") [node name="BTPlayer" type="BTPlayer" parent="."] behavior_tree = ExtResource("2_58ujo") -update_mode = 1 -active = true _blackboard_data = { "speed": 500.0 }