BlackboardPlanEditor: Fixes and clean up

This commit is contained in:
Serhii Snitsaruk 2024-01-25 00:23:34 +01:00
parent 15e0323919
commit 06052332b2
8 changed files with 86 additions and 37 deletions

View File

@ -107,8 +107,6 @@ bool BlackboardPlan::_property_get_revert(const StringName &p_name, Variant &r_p
void BlackboardPlan::set_base_plan(const Ref<BlackboardPlan> &p_base) { void BlackboardPlan::set_base_plan(const Ref<BlackboardPlan> &p_base) {
base = p_base; base = p_base;
sync_with_base_plan(); sync_with_base_plan();
emit_changed();
notify_property_list_changed();
} }
void BlackboardPlan::set_value(const String &p_name, const Variant &p_value) { void BlackboardPlan::set_value(const String &p_name, const Variant &p_value) {

View File

@ -71,16 +71,21 @@ void BTPlayer::_update_blackboard_plan() {
} }
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 (behavior_tree.is_valid() && behavior_tree->is_connected(LW_NAME(changed), callable_mp(this, &BTPlayer::_update_blackboard_plan))) { if (behavior_tree.is_valid() && behavior_tree->is_connected(LW_NAME(changed), callable_mp(this, &BTPlayer::_update_blackboard_plan))) {
behavior_tree->disconnect(LW_NAME(changed), callable_mp(this, &BTPlayer::_update_blackboard_plan)); behavior_tree->disconnect(LW_NAME(changed), callable_mp(this, &BTPlayer::_update_blackboard_plan));
} }
behavior_tree = p_tree; if (p_tree.is_valid()) {
if (!Engine::get_singleton()->is_editor_hint() && get_owner()) { p_tree->connect(LW_NAME(changed), callable_mp(this, &BTPlayer::_update_blackboard_plan));
_load_tree();
} else if (behavior_tree.is_valid()) {
behavior_tree->connect(LW_NAME(changed), callable_mp(this, &BTPlayer::_update_blackboard_plan));
} }
behavior_tree = p_tree;
_update_blackboard_plan(); _update_blackboard_plan();
} else {
behavior_tree = p_tree;
if (get_owner()) {
_load_tree();
}
}
} }
void BTPlayer::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) { void BTPlayer::set_blackboard_plan(const Ref<BlackboardPlan> &p_plan) {
@ -193,18 +198,27 @@ void BTPlayer::_notification(int p_notification) {
#endif #endif
} }
} break; } break;
#ifdef DEBUG_ENABLED
case NOTIFICATION_ENTER_TREE: { case NOTIFICATION_ENTER_TREE: {
#ifdef DEBUG_ENABLED
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) { if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path()); LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
} }
#endif // DEBUG_ENABLED
} break; } break;
case NOTIFICATION_EXIT_TREE: { case NOTIFICATION_EXIT_TREE: {
#ifdef DEBUG_ENABLED
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) { if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path()); LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path());
} }
} break;
#endif // DEBUG_ENABLED #endif // DEBUG_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
if (behavior_tree.is_valid() && behavior_tree->is_connected(LW_NAME(changed), callable_mp(this, &BTPlayer::_update_blackboard_plan))) {
behavior_tree->disconnect(LW_NAME(changed), callable_mp(this, &BTPlayer::_update_blackboard_plan));
}
}
} break;
} }
} }

View File

@ -26,17 +26,23 @@
#include <godot_cpp/classes/engine_debugger.hpp> #include <godot_cpp/classes/engine_debugger.hpp>
#endif // LIMBOAI_GDEXTENSION #endif // LIMBOAI_GDEXTENSION
void BTState::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
if (Engine::get_singleton()->is_editor_hint()) {
if (behavior_tree.is_valid() && behavior_tree->is_connected(LW_NAME(changed), callable_mp(this, &BTState::_update_blackboard_plan))) {
behavior_tree->disconnect(LW_NAME(changed), callable_mp(this, &BTState::_update_blackboard_plan));
}
if (p_tree.is_valid()) {
p_tree->connect(LW_NAME(changed), callable_mp(this, &BTState::_update_blackboard_plan));
}
}
behavior_tree = p_tree;
}
void BTState::_update_blackboard_plan() { void BTState::_update_blackboard_plan() {
if (behavior_tree.is_valid() && behavior_tree->get_blackboard_plan().is_valid()) {
if (get_blackboard_plan().is_null()) { if (get_blackboard_plan().is_null()) {
set_blackboard_plan(Ref<BlackboardPlan>(memnew(BlackboardPlan))); set_blackboard_plan(Ref<BlackboardPlan>(memnew(BlackboardPlan)));
} }
if (get_blackboard_plan() == behavior_tree->get_blackboard_plan()) { get_blackboard_plan()->set_base_plan(behavior_tree.is_valid() ? behavior_tree->get_blackboard_plan() : nullptr);
get_blackboard_plan()->sync_with_base_plan();
} else {
get_blackboard_plan()->set_base_plan(behavior_tree->get_blackboard_plan());
}
}
} }
void BTState::_setup() { void BTState::_setup() {
@ -66,22 +72,30 @@ void BTState::_update(double p_delta) {
} }
} }
#ifdef DEBUG_ENABLED
void BTState::_notification(int p_notification) { void BTState::_notification(int p_notification) {
switch (p_notification) { switch (p_notification) {
#ifdef DEBUG_ENABLED
case NOTIFICATION_ENTER_TREE: { case NOTIFICATION_ENTER_TREE: {
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) { if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path()); LimboDebugger::get_singleton()->register_bt_instance(tree_instance, get_path());
} }
} break; } break;
#endif // DEBUG_ENABLED
case NOTIFICATION_EXIT_TREE: { case NOTIFICATION_EXIT_TREE: {
#ifdef DEBUG_ENABLED
if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) { if (tree_instance.is_valid() && IS_DEBUGGER_ACTIVE()) {
LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path()); LimboDebugger::get_singleton()->unregister_bt_instance(tree_instance, get_path());
} }
#endif // DEBUG_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
if (behavior_tree.is_valid() && behavior_tree->is_connected(LW_NAME(changed), callable_mp(this, &BTState::_update_blackboard_plan))) {
behavior_tree->disconnect(LW_NAME(changed), callable_mp(this, &BTState::_update_blackboard_plan));
}
}
} break; } break;
} }
} }
#endif // DEBUG_ENABLED
void BTState::_bind_methods() { void BTState::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_behavior_tree", "p_value"), &BTState::set_behavior_tree); ClassDB::bind_method(D_METHOD("set_behavior_tree", "p_value"), &BTState::set_behavior_tree);

View File

@ -36,7 +36,7 @@ protected:
virtual void _update(double p_delta) override; virtual void _update(double p_delta) override;
public: public:
void set_behavior_tree(const Ref<BehaviorTree> &p_value) { behavior_tree = 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; }
void set_success_event(String p_success_event) { success_event = p_success_event; } void set_success_event(String p_success_event) { success_event = p_success_event; }
@ -47,11 +47,8 @@ public:
BTState(); BTState();
#ifdef DEBUG_ENABLED
protected: protected:
void _notification(int p_notification); void _notification(int p_notification);
#endif
}; };
#endif // BT_STATE_H #endif // BT_STATE_H

View File

@ -1,7 +1,14 @@
[gd_resource type="BehaviorTree" load_steps=10 format=3 uid="uid://cjkqi41oagagd"] [gd_resource type="BehaviorTree" load_steps=11 format=3 uid="uid://cjkqi41oagagd"]
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="1_rhs33"] [ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="1_rhs33"]
[sub_resource type="BlackboardPlan" id="BlackboardPlan_2hcqi"]
var/speed/name = null
var/speed/type = 3
var/speed/value = 200.0
var/speed/hint = 1
var/speed/hint_string = "10,1000,10"
[sub_resource type="BTAction" id="BTAction_3xal7"] [sub_resource type="BTAction" id="BTAction_3xal7"]
script = ExtResource("1_rhs33") script = ExtResource("1_rhs33")
target_position_var = "wp" target_position_var = "wp"
@ -37,3 +44,4 @@ children = [SubResource("BTCooldown_gen0l")]
[resource] [resource]
root_task = SubResource("BTSelector_5dclr") root_task = SubResource("BTSelector_5dclr")
blackboard_plan = SubResource("BlackboardPlan_2hcqi")

View File

@ -1,9 +1,16 @@
[gd_scene load_steps=7 format=3 uid="uid://c26b8c8dndtop"] [gd_scene load_steps=8 format=3 uid="uid://c26b8c8dndtop"]
[ext_resource type="Script" path="res://demo/examples/waypoints/patrolling_agent.gd" id="1_5wwhb"] [ext_resource type="Script" path="res://demo/examples/waypoints/patrolling_agent.gd" id="1_5wwhb"]
[ext_resource type="BehaviorTree" uid="uid://cjkqi41oagagd" path="res://demo/ai/trees/waypoints.tres" id="2_66y4v"] [ext_resource type="BehaviorTree" uid="uid://cjkqi41oagagd" path="res://demo/ai/trees/waypoints.tres" id="2_66y4v"]
[ext_resource type="Texture2D" uid="uid://d0mht3ntak7e5" path="res://demo/godot.png" id="3_64ge2"] [ext_resource type="Texture2D" uid="uid://d0mht3ntak7e5" path="res://demo/godot.png" id="3_64ge2"]
[sub_resource type="BlackboardPlan" id="BlackboardPlan_b86q8"]
var/speed/name = null
var/speed/type = 3
var/speed/value = 200.0
var/speed/hint = 1
var/speed/hint_string = "10,1000,10"
[sub_resource type="Animation" id="Animation_5id00"] [sub_resource type="Animation" id="Animation_5id00"]
length = 0.001 length = 0.001
tracks/0/type = "value" tracks/0/type = "value"
@ -46,9 +53,7 @@ script = ExtResource("1_5wwhb")
[node name="BTPlayer" type="BTPlayer" parent="."] [node name="BTPlayer" type="BTPlayer" parent="."]
behavior_tree = ExtResource("2_66y4v") behavior_tree = ExtResource("2_66y4v")
_blackboard_data = { blackboard_plan = SubResource("BlackboardPlan_b86q8")
"speed": 200.0
}
[node name="Sprite2D" type="Sprite2D" parent="."] [node name="Sprite2D" type="Sprite2D" parent="."]
texture = ExtResource("3_64ge2") texture = ExtResource("3_64ge2")

View File

@ -266,7 +266,7 @@ void BlackboardPlanEditor::_notification(int p_what) {
} }
BlackboardPlanEditor::BlackboardPlanEditor() { BlackboardPlanEditor::BlackboardPlanEditor() {
set_title(TTR("Edit Blackboard Plan")); set_title(TTR("Manage Blackboard Plan"));
VBoxContainer *vbox = memnew(VBoxContainer); VBoxContainer *vbox = memnew(VBoxContainer);
vbox->add_theme_constant_override(LW_NAME(separation), 8 * EDSCALE); vbox->add_theme_constant_override(LW_NAME(separation), 8 * EDSCALE);
@ -378,8 +378,14 @@ void EditorInspectorPluginBBPlan::parse_begin(Object *p_object) {
Ref<BlackboardPlan> plan = Object::cast_to<BlackboardPlan>(p_object); Ref<BlackboardPlan> plan = Object::cast_to<BlackboardPlan>(p_object);
ERR_FAIL_NULL(plan); ERR_FAIL_NULL(plan);
PanelContainer *panel = memnew(PanelContainer);
panel->add_theme_style_override(LW_NAME(panel), toolbar_style);
MarginContainer *margin_container = memnew(MarginContainer); MarginContainer *margin_container = memnew(MarginContainer);
panel->add_child(margin_container);
margin_container->set_theme_type_variation("MarginContainer4px"); margin_container->set_theme_type_variation("MarginContainer4px");
margin_container->set_v_size_flags(Control::SIZE_EXPAND_FILL);
margin_container->set_h_size_flags(Control::SIZE_EXPAND_FILL);
VBoxContainer *toolbar = memnew(VBoxContainer); VBoxContainer *toolbar = memnew(VBoxContainer);
margin_container->add_child(toolbar); margin_container->add_child(toolbar);
@ -388,24 +394,30 @@ void EditorInspectorPluginBBPlan::parse_begin(Object *p_object) {
if (plan->is_derived()) { if (plan->is_derived()) {
Button *goto_btn = memnew(Button); Button *goto_btn = memnew(Button);
toolbar->add_child(goto_btn); toolbar->add_child(goto_btn);
goto_btn->set_text(TTR("Open Base Plan")); goto_btn->set_text(TTR("Edit Base"));
goto_btn->set_h_size_flags(Control::SIZE_SHRINK_CENTER); goto_btn->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
goto_btn->set_custom_minimum_size(Size2(200.0, 0.0) * EDSCALE); goto_btn->set_custom_minimum_size(Size2(200.0, 0.0) * EDSCALE);
goto_btn->connect(LW_NAME(pressed), callable_mp(this, &EditorInspectorPluginBBPlan::_open_base_plan).bind(plan)); goto_btn->connect(LW_NAME(pressed), callable_mp(this, &EditorInspectorPluginBBPlan::_open_base_plan).bind(plan));
} else { } else {
Button *edit_btn = memnew(Button); Button *edit_btn = memnew(Button);
toolbar->add_child(edit_btn); toolbar->add_child(edit_btn);
edit_btn->set_text(TTR("Edit...")); edit_btn->set_text(TTR("Manage..."));
edit_btn->set_h_size_flags(Control::SIZE_SHRINK_CENTER); edit_btn->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
edit_btn->set_custom_minimum_size(Size2(200.0, 0.0) * EDSCALE); edit_btn->set_custom_minimum_size(Size2(200.0, 0.0) * EDSCALE);
edit_btn->connect(LW_NAME(pressed), callable_mp(this, &EditorInspectorPluginBBPlan::_edit_plan).bind(plan)); edit_btn->connect(LW_NAME(pressed), callable_mp(this, &EditorInspectorPluginBBPlan::_edit_plan).bind(plan));
} }
add_custom_control(margin_container); add_custom_control(panel);
} }
EditorInspectorPluginBBPlan::EditorInspectorPluginBBPlan() { EditorInspectorPluginBBPlan::EditorInspectorPluginBBPlan() {
plan_editor = memnew(BlackboardPlanEditor); plan_editor = memnew(BlackboardPlanEditor);
EditorInterface::get_singleton()->get_base_control()->add_child(plan_editor); EditorInterface::get_singleton()->get_base_control()->add_child(plan_editor);
plan_editor->hide(); plan_editor->hide();
toolbar_style = Ref<StyleBoxFlat>(memnew(StyleBoxFlat));
Color bg = EditorInterface::get_singleton()->get_editor_theme()->get_color(LW_NAME(accent_color), LW_NAME(Editor));
bg = bg.darkened(-0.1);
bg.a *= 0.2;
toolbar_style->set_bg_color(bg);
} }

View File

@ -36,7 +36,7 @@ private:
int last_index = 0; int last_index = 0;
int drag_mouse_y_delta = 0; int drag_mouse_y_delta = 0;
int drag_index = 0; int drag_index = -1;
Ref<BlackboardPlan> plan; Ref<BlackboardPlan> plan;
@ -81,6 +81,7 @@ class EditorInspectorPluginBBPlan : public EditorInspectorPlugin {
private: private:
BlackboardPlanEditor *plan_editor; BlackboardPlanEditor *plan_editor;
Ref<StyleBoxFlat> toolbar_style;
void _edit_plan(const Ref<BlackboardPlan> &p_plan); void _edit_plan(const Ref<BlackboardPlan> &p_plan);
void _open_base_plan(const Ref<BlackboardPlan> &p_plan); void _open_base_plan(const Ref<BlackboardPlan> &p_plan);