Improved Behaviour debugging, NPCs look around or focus player if nearby.

main
Martin Felis 2024-12-28 16:34:30 +01:00
parent 7b3a1976d7
commit e2c9b14560
10 changed files with 199 additions and 75 deletions

View File

@ -0,0 +1,19 @@
@tool
extends BTAction
@export var target_location_var: StringName = &"target_location"
@export var output_var: StringName = &"location_distance"
func _generate_name() -> String:
return "CalcDistanceToLocation \"%s\" -> %s" % [
target_location_var,
output_var
]
func _tick(_delta: float) -> Status:
var target_location:Vector3 = blackboard.get_var(target_location_var)
var distance:float = (target_location - agent.global_position).length()
blackboard.set_var(output_var, distance)
return SUCCESS

View File

@ -0,0 +1,23 @@
@tool
extends BTAction
@export var max_distance:float = 1.0
@export var target_var: StringName = &"target"
@export var output_var: StringName = &"target_location"
func _generate_name() -> String:
return "GetTargetLocation \"%s\"%s" % [
target_var,
LimboUtility.decorate_var(target_var)
]
func _tick(_delta: float) -> Status:
var target_node:Node3D = blackboard.get_var(target_var)
if not is_instance_valid(target_node):
push_error("Cannot check distance to target: invalid target node!")
return FAILURE
blackboard.set_var(output_var, target_node.global_position)
return SUCCESS

View File

@ -1,4 +1,4 @@
[gd_resource type="BehaviorTree" load_steps=9 format=3 uid="uid://2v14hwp2gtg"]
[gd_resource type="BehaviorTree" load_steps=8 format=3 uid="uid://2v14hwp2gtg"]
[ext_resource type="Script" path="res://ai/tasks/look_at_location.gd" id="1_1lumv"]
[ext_resource type="Script" path="res://ai/tasks/find_nearby_random_location.gd" id="2_jrbpg"]
@ -16,16 +16,11 @@ stay_in_radius = true
script = ExtResource("1_1lumv")
target_location_var = &"target_location"
[sub_resource type="BTWait" id="BTWait_jmtj2"]
duration = 2.0
[sub_resource type="BTRandomWait" id="BTRandomWait_d2kpo"]
[sub_resource type="BTSequence" id="BTSequence_ouv1e"]
children = [SubResource("BTAction_ba1hn"), SubResource("BTAction_d7u7l"), SubResource("BTWait_jmtj2")]
[sub_resource type="BTRepeat" id="BTRepeat_nqqvt"]
forever = true
children = [SubResource("BTSequence_ouv1e")]
children = [SubResource("BTAction_ba1hn"), SubResource("BTAction_d7u7l"), SubResource("BTRandomWait_d2kpo")]
[resource]
blackboard_plan = SubResource("BlackboardPlan_sdda8")
root_task = SubResource("BTRepeat_nqqvt")
root_task = SubResource("BTSequence_ouv1e")

View File

@ -0,0 +1,67 @@
[gd_resource type="BehaviorTree" load_steps=19 format=3 uid="uid://ci1dpjqvsq0ax"]
[ext_resource type="Script" path="res://ai/tasks/find_target_by_name.gd" id="1_crjnn"]
[ext_resource type="Script" path="res://ai/tasks/get_target_location.gd" id="2_a4moq"]
[ext_resource type="Script" path="res://ai/tasks/calc_distance_to_location.gd" id="3_21rvk"]
[ext_resource type="Script" path="res://ai/tasks/look_at_location.gd" id="4_0f2uh"]
[ext_resource type="BehaviorTree" uid="uid://2v14hwp2gtg" path="res://ai/trees/look_around.tres" id="5_n3u5i"]
[sub_resource type="BlackboardPlan" id="BlackboardPlan_rxiwf"]
var/target_distance/name = &"target_distance"
var/target_distance/type = 3
var/target_distance/value = 0.0
var/target_distance/hint = 0
var/target_distance/hint_string = ""
[sub_resource type="BTAction" id="BTAction_rgjhs"]
script = ExtResource("1_crjnn")
target_name = "Player"
output_var = &"target"
[sub_resource type="BTAction" id="BTAction_2cqtn"]
script = ExtResource("2_a4moq")
max_distance = 1.0
target_var = &"target"
output_var = &"target_location"
[sub_resource type="BTAction" id="BTAction_rp83o"]
script = ExtResource("3_21rvk")
target_location_var = &"target_location"
output_var = &"target_distance"
[sub_resource type="BBVariant" id="BBVariant_4v4ud"]
type = 3
saved_value = 2.0
resource_name = "2"
[sub_resource type="BTCheckVar" id="BTCheckVar_0itqd"]
variable = &"target_distance"
check_type = 2
value = SubResource("BBVariant_4v4ud")
[sub_resource type="BTAction" id="BTAction_4e23b"]
script = ExtResource("4_0f2uh")
target_location_var = &"target_location"
[sub_resource type="BTSequence" id="BTSequence_ytwco"]
children = [SubResource("BTCheckVar_0itqd"), SubResource("BTAction_4e23b")]
[sub_resource type="BlackboardPlan" id="BlackboardPlan_02yjb"]
[sub_resource type="BTSubtree" id="BTSubtree_dnwew"]
subtree = ExtResource("5_n3u5i")
blackboard_plan = SubResource("BlackboardPlan_02yjb")
[sub_resource type="BTSelector" id="BTSelector_cu7cu"]
children = [SubResource("BTSequence_ytwco"), SubResource("BTSubtree_dnwew")]
[sub_resource type="BTSequence" id="BTSequence_yk8po"]
children = [SubResource("BTAction_rgjhs"), SubResource("BTAction_2cqtn"), SubResource("BTAction_rp83o"), SubResource("BTSelector_cu7cu")]
[sub_resource type="BTRepeat" id="BTRepeat_713a6"]
forever = true
children = [SubResource("BTSequence_yk8po")]
[resource]
blackboard_plan = SubResource("BlackboardPlan_rxiwf")
root_task = SubResource("BTRepeat_713a6")

View File

@ -1,40 +1,19 @@
[gd_resource type="BehaviorTree" load_steps=12 format=3 uid="uid://blccr23qjixws"]
[gd_resource type="BehaviorTree" load_steps=6 format=3 uid="uid://blccr23qjixws"]
[ext_resource type="Script" path="res://ai/tasks/find_target_by_name.gd" id="1_v4edy"]
[ext_resource type="Script" path="res://ai/tasks/navigate_to_location.gd" id="2_k36i0"]
[ext_resource type="BehaviorTree" uid="uid://caxmpcyhpt6em" path="res://ai/trees/wander.tres" id="1_rsg0c"]
[sub_resource type="BlackboardPlan" id="BlackboardPlan_yg732"]
[sub_resource type="BTAction" id="BTAction_7a1kv"]
script = ExtResource("1_v4edy")
target_name = "Player"
output_var = &"target"
[sub_resource type="BlackboardPlan" id="BlackboardPlan_x4gxn"]
[sub_resource type="BTWait" id="BTWait_8cgex"]
duration = 2.0
[sub_resource type="BTSubtree" id="BTSubtree_krik0"]
subtree = ExtResource("1_rsg0c")
blackboard_plan = SubResource("BlackboardPlan_x4gxn")
[sub_resource type="BTAction" id="BTAction_qfrs5"]
script = ExtResource("1_v4edy")
target_name = "Bone"
output_var = &"target"
[sub_resource type="BTSequence" id="BTSequence_u84lc"]
children = [SubResource("BTAction_7a1kv"), SubResource("BTWait_8cgex"), SubResource("BTAction_qfrs5")]
[sub_resource type="BTAction" id="BTAction_l2eti"]
script = ExtResource("2_k36i0")
target_var = &"target"
[sub_resource type="BTRepeat" id="BTRepeat_dam0f"]
[sub_resource type="BTRepeat" id="BTRepeat_i5p3p"]
forever = true
children = [SubResource("BTAction_l2eti")]
[sub_resource type="BTParallel" id="BTParallel_l5msj"]
children = [SubResource("BTSequence_u84lc"), SubResource("BTRepeat_dam0f")]
[sub_resource type="BTSequence" id="BTSequence_77owj"]
children = [SubResource("BTParallel_l5msj")]
children = [SubResource("BTSubtree_krik0")]
[resource]
blackboard_plan = SubResource("BlackboardPlan_yg732")
root_task = SubResource("BTSequence_77owj")
root_task = SubResource("BTRepeat_i5p3p")

View File

@ -1,4 +1,4 @@
[gd_resource type="BehaviorTree" load_steps=11 format=3 uid="uid://caxmpcyhpt6em"]
[gd_resource type="BehaviorTree" load_steps=10 format=3 uid="uid://caxmpcyhpt6em"]
[ext_resource type="Script" path="res://ai/tasks/find_nearby_random_location.gd" id="1_5wpmm"]
[ext_resource type="Script" path="res://ai/tasks/look_at_location.gd" id="2_d6sgo"]
@ -21,16 +21,12 @@ target_location_var = &"target_location"
script = ExtResource("3_ch0o3")
target_var = &"target_location"
[sub_resource type="BTWait" id="BTWait_yneys"]
duration = 3.0
[sub_resource type="BTRandomWait" id="BTRandomWait_gert2"]
max_duration = 3.0
[sub_resource type="BTSequence" id="BTSequence_o4qno"]
children = [SubResource("BTAction_s4a8v"), SubResource("BTAction_lschq"), SubResource("BTAction_onf00"), SubResource("BTWait_yneys")]
[sub_resource type="BTRepeat" id="BTRepeat_o23de"]
forever = true
children = [SubResource("BTSequence_o4qno")]
children = [SubResource("BTAction_s4a8v"), SubResource("BTAction_lschq"), SubResource("BTAction_onf00"), SubResource("BTRandomWait_gert2")]
[resource]
blackboard_plan = SubResource("BlackboardPlan_yo8p7")
root_task = SubResource("BTRepeat_o23de")
root_task = SubResource("BTSequence_o4qno")

View File

@ -16,8 +16,6 @@ signal quit_game_scene
var _game_scene:Game
var _player:Player
var _all_recipes:Array[RecipeResource] = []
var _debug_npc_name = "PugNPC"
var _debug_npc:NonPlayerCharacter = null
func _ready():
for file in DirAccess.get_files_at("res://data/recipes"):
@ -28,8 +26,6 @@ func _ready():
tool_container.connect("item_selected", _on_tool_select)
func reset():
_debug_npc = null
if _player != null:
disconnect_player_signals()
@ -51,9 +47,6 @@ func activate_game_scene(game_scene:Node3D) -> void:
tool_slots.show()
tool_container.displayStacks(_player.inventory.get_tool_item_stacks())
if _debug_npc_name != "":
_debug_npc = _game_scene.find_child(_debug_npc_name, true, false) as NonPlayerCharacter
game_menu_ui.hide()
func _process(_delta):
@ -82,15 +75,6 @@ func _process(_delta):
else:
_game_scene.build_system.is_active = false
if _debug_npc:
var _btplayer = _debug_npc.find_child("BTPlayer") as BTPlayer
if _btplayer:
var instance: BTInstance = _btplayer.get_bt_instance()
var data: BehaviorTreeData = BehaviorTreeData.create_from_bt_instance(instance)
behavior_debug_view.update_tree(data)
else:
behavior_debug_view.clear()
func _on_message_timer_timeout():
%MessagesContainer.visible = false

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=39 format=3 uid="uid://c73t0nbuqp68e"]
[gd_scene load_steps=40 format=3 uid="uid://c73t0nbuqp68e"]
[ext_resource type="Script" path="res://root_ui.gd" id="1_7fnkg"]
[ext_resource type="PackedScene" uid="uid://bo788o53t4rbq" path="res://scenes/startup_scene.tscn" id="2_1untt"]
@ -22,6 +22,7 @@
[ext_resource type="Script" path="res://ui/build_dialog.gd" id="15_x7ovi"]
[ext_resource type="Theme" uid="uid://c1m2rpljepv4t" path="res://ui/ui_theme_debug.tres" id="21_nsciq"]
[ext_resource type="Script" path="res://ui/debug/build_system.gd" id="22_g4j6a"]
[ext_resource type="Script" path="res://ui/debug/behaviour.gd" id="23_mv0pi"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1ume3"]
content_margin_left = 4.0
@ -895,7 +896,6 @@ text = "⚙️"
[node name="DebugTabContainer" type="TabContainer" parent="DebugUi"]
unique_name_in_owner = true
visible = false
layout_mode = 2
tab_alignment = 2
current_tab = 1
@ -951,6 +951,7 @@ layout_mode = 2
theme_override_constants/margin_left = 8
theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 8
script = ExtResource("23_mv0pi")
metadata/_tab_index = 1
[node name="Panel" type="Panel" parent="DebugUi/DebugTabContainer/Behaviour"]
@ -969,6 +970,23 @@ layout_mode = 2
text = "Behavior"
horizontal_alignment = 1
[node name="HBoxContainer" type="HBoxContainer" parent="DebugUi/DebugTabContainer/Behaviour/Panel/VBoxContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="DebugUi/DebugTabContainer/Behaviour/Panel/VBoxContainer/HBoxContainer"]
layout_mode = 2
text = "Name"
[node name="NPCNameEdit" type="LineEdit" parent="DebugUi/DebugTabContainer/Behaviour/Panel/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
placeholder_text = "NPC Name"
[node name="SearchButton" type="Button" parent="DebugUi/DebugTabContainer/Behaviour/Panel/VBoxContainer/HBoxContainer"]
layout_mode = 2
text = "Search"
[node name="BehaviorDebugView" type="BehaviorTreeView" parent="DebugUi/DebugTabContainer/Behaviour/Panel/VBoxContainer"]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 300)
@ -1067,3 +1085,5 @@ unique_name_in_owner = true
[connection signal="gui_input" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@354713" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@354713" method="_on_gui_input"]
[connection signal="mouse_entered" from="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@354713" to="GameUI/BuildDialog/Panel/MarginContainer/VBoxContainer/BuildItemResourcesContainer/@Panel@354713" method="_on_mouse_entered"]
[connection signal="toggled" from="DebugUi/ToggleDebugButton" to="." method="_on_toggle_debug_button_toggled"]
[connection signal="text_submitted" from="DebugUi/DebugTabContainer/Behaviour/Panel/VBoxContainer/HBoxContainer/NPCNameEdit" to="DebugUi/DebugTabContainer/Behaviour" method="_on_npc_name_edit_text_submitted"]
[connection signal="pressed" from="DebugUi/DebugTabContainer/Behaviour/Panel/VBoxContainer/HBoxContainer/SearchButton" to="DebugUi/DebugTabContainer/Behaviour" method="_on_search_button_pressed"]

31
ui/debug/behaviour.gd Normal file
View File

@ -0,0 +1,31 @@
extends MarginContainer
@onready var npc_name_edit: LineEdit = %NPCNameEdit
@onready var behavior_debug_view: BehaviorTreeView = %BehaviorDebugView
var _debug_bt_player:BTPlayer = null
func _process(_delta: float) -> void:
if _debug_bt_player == null:
return
var instance: BTInstance = _debug_bt_player.get_bt_instance()
var data: BehaviorTreeData = BehaviorTreeData.create_from_bt_instance(instance)
behavior_debug_view.update_tree(data)
func _on_search_button_pressed() -> void:
_on_npc_name_edit_text_submitted(npc_name_edit.text)
func _on_npc_name_edit_text_submitted(new_text: String) -> void:
npc_name_edit.release_focus()
var npc_node:NonPlayerCharacter = get_tree().root.find_child(new_text, true, false) as NonPlayerCharacter
if not is_instance_valid(npc_node):
push_error("Cannot show npc behavior: could not find node with name '%s'." % new_text)
return
_debug_bt_player = npc_node.find_child("BTPlayer") as BTPlayer
if _debug_bt_player == null:
behavior_debug_view.clear()
push_error("Cannot show npc behavior: no BTPlayer found.")

File diff suppressed because one or more lines are too long