From 2199941bfab04e4ee1fcedb3d1263b6f6957aeb4 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sun, 19 Jan 2025 21:42:11 +0100 Subject: [PATCH] Added hostile behavior that attacks a player using a dash. --- ai/tasks/dash.gd | 10 ++++ ai/tasks/look_at_location.gd | 4 +- ai/trees/hostile.tres | 81 +++++++++++++++++++++++++++++++ objects/non_player_character.gd | 19 +++++++- objects/non_player_character.tscn | 26 +++++++++- game_ui.gd => ui/game_ui.gd | 0 world/level.tscn | 17 +++++-- 7 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 ai/tasks/dash.gd create mode 100644 ai/trees/hostile.tres rename game_ui.gd => ui/game_ui.gd (100%) diff --git a/ai/tasks/dash.gd b/ai/tasks/dash.gd new file mode 100644 index 0000000..6f0dfd3 --- /dev/null +++ b/ai/tasks/dash.gd @@ -0,0 +1,10 @@ +extends BTAction + +var _agent_npc:NonPlayerCharacter = null + +func _tick(_delta: float) -> Status: + _agent_npc = agent as NonPlayerCharacter + + _agent_npc.velocity = _agent_npc.global_transform.basis.z * 10 + + return SUCCESS diff --git a/ai/tasks/look_at_location.gd b/ai/tasks/look_at_location.gd index 892f08b..55dadd5 100644 --- a/ai/tasks/look_at_location.gd +++ b/ai/tasks/look_at_location.gd @@ -23,10 +23,10 @@ func _tick(delta: float) -> Status: if DebugSystem.debug_npc == _agent_npc: DebugDraw3D.draw_arrow(_agent_npc.global_position, target_position, Color.CRIMSON, 0.1, true) - if absf(_target_look_angle - _current_look_angle) < deg_to_rad(5): + if absf(_target_look_angle - _current_look_angle) < deg_to_rad(1) and _look_angle_damper.v < 0.1: return SUCCESS - return RUNNING + return FAILURE func clamp_current_look_angle() -> void: if _target_look_angle - _current_look_angle > PI: diff --git a/ai/trees/hostile.tres b/ai/trees/hostile.tres new file mode 100644 index 0000000..7639bc1 --- /dev/null +++ b/ai/trees/hostile.tres @@ -0,0 +1,81 @@ +[gd_resource type="BehaviorTree" load_steps=24 format=3 uid="uid://ci4c0hulhunya"] + +[ext_resource type="Script" path="res://ai/tasks/find_target_by_name.gd" id="1_tnvhr"] +[ext_resource type="Script" path="res://ai/tasks/get_target_location.gd" id="2_b5gty"] +[ext_resource type="Script" path="res://ai/tasks/calc_distance_to_location.gd" id="3_uare1"] +[ext_resource type="Script" path="res://ai/tasks/check_target_node_visible.gd" id="4_a08ij"] +[ext_resource type="Script" path="res://ai/tasks/look_at_location.gd" id="5_gmkjn"] +[ext_resource type="Script" path="res://ai/tasks/dash.gd" id="6_olvwy"] + +[sub_resource type="BlackboardPlan" id="BlackboardPlan_1scth"] + +[sub_resource type="BTAction" id="BTAction_djxii"] +script = ExtResource("1_tnvhr") +target_name = "Player" +output_var = &"player_node" + +[sub_resource type="BTAction" id="BTAction_j2c2h"] +script = ExtResource("2_b5gty") +max_distance = 1.0 +target_var = &"player_node" +output_var = &"player_location" + +[sub_resource type="BTAction" id="BTAction_m57e1"] +script = ExtResource("3_uare1") +target_location_var = &"player_location" +output_var = &"player_distance" + +[sub_resource type="BBVariant" id="BBVariant_qpc1d"] +type = 3 +saved_value = 3.0 +resource_name = "3" + +[sub_resource type="BTCheckVar" id="BTCheckVar_tckkb"] +variable = &"player_distance" +check_type = 2 +value = SubResource("BBVariant_qpc1d") + +[sub_resource type="BTAction" id="BTAction_nwvhw"] +script = ExtResource("4_a08ij") +target_node_var = &"player_node" + +[sub_resource type="BTAction" id="BTAction_jedr7"] +script = ExtResource("5_gmkjn") +target_location_var = &"player_location" + +[sub_resource type="BTWait" id="BTWait_ja5ae"] + +[sub_resource type="BBVariant" id="BBVariant_r47ls"] +type = 1 +saved_value = true +resource_name = "true" + +[sub_resource type="BTSetAgentProperty" id="BTSetAgentProperty_vbi0y"] +property = &"is_dash_active" +value = SubResource("BBVariant_r47ls") + +[sub_resource type="BTAction" id="BTAction_j3hob"] +script = ExtResource("6_olvwy") + +[sub_resource type="BTWait" id="BTWait_dxb8r"] + +[sub_resource type="BBVariant" id="BBVariant_dc6nt"] +type = 1 +saved_value = false +resource_name = "false" + +[sub_resource type="BTSetAgentProperty" id="BTSetAgentProperty_4wskw"] +property = &"is_dash_active" +value = SubResource("BBVariant_dc6nt") + +[sub_resource type="BTSequence" id="BTSequence_j6m67"] +custom_name = "Dash" +children = [SubResource("BTWait_ja5ae"), SubResource("BTSetAgentProperty_vbi0y"), SubResource("BTAction_j3hob"), SubResource("BTWait_dxb8r"), SubResource("BTSetAgentProperty_4wskw")] + +[sub_resource type="BTSequence" id="BTSequence_dqp20"] +custom_name = "AimAtPlayer" +children = [SubResource("BTAction_djxii"), SubResource("BTAction_j2c2h"), SubResource("BTAction_m57e1"), SubResource("BTCheckVar_tckkb"), SubResource("BTAction_nwvhw"), SubResource("BTAction_jedr7"), SubResource("BTSequence_j6m67")] + +[resource] +blackboard_plan = SubResource("BlackboardPlan_1scth") +root_task = SubResource("BTSequence_dqp20") diff --git a/objects/non_player_character.gd b/objects/non_player_character.gd index 28dee34..d67d93b 100644 --- a/objects/non_player_character.gd +++ b/objects/non_player_character.gd @@ -23,13 +23,23 @@ extends CharacterBody3D @onready var animation_player: AnimationPlayer = %AnimationPlayer @onready var navigation_agent: NavigationAgent3D = %NavigationAgent @onready var bt_player: BTPlayer = %BTPlayer +@onready var dash_collision_shape: CollisionShape3D = %DashCollisionShape +@onready var dash_detection_area: Area3D = %DashDetectionArea const SPEED = 2.0 const JUMP_VELOCITY = 4.5 +const VELOCITY_DAMPING = 20.0 var tool_damage:bool = false var tracking_node:Node3D = null var navigation_active:bool = false +var is_dash_active:bool = false: + set(value): + is_dash_active = value + dash_collision_shape.disabled = not is_dash_active + dash_detection_area.monitoring = is_dash_active + get: + return is_dash_active var navigation_query_parameters:NavigationPathQueryParameters3D = NavigationPathQueryParameters3D.new() var navigation_query_result:NavigationPathQueryResult3D = NavigationPathQueryResult3D.new() @@ -87,7 +97,11 @@ func _physics_process(delta: float) -> void: velocity = direction * SPEED * (minf(1.0, path_remainder * 0.9)) # print ("scale %f" % (path_remainder)) - move_and_slide() + move_and_slide() + + var speed = velocity.length() + if speed > 0: + velocity = velocity - (velocity) * min(VELOCITY_DAMPING * delta / speed, 1.0) func _on_player_detection_body_entered(body: Node3D) -> void: if body is Player: @@ -127,3 +141,6 @@ func is_navigation_finished() -> bool: func is_navigation_target_reached() -> bool: return navigation_agent.is_target_reached() + +func _on_dash_detection_area_body_entered(_body: Node3D) -> void: + print ("hitting player!") diff --git a/objects/non_player_character.tscn b/objects/non_player_character.tscn index e1ebbb0..d6e960a 100644 --- a/objects/non_player_character.tscn +++ b/objects/non_player_character.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=3 uid="uid://03eh1nglfg6t"] +[gd_scene load_steps=12 format=3 uid="uid://03eh1nglfg6t"] [ext_resource type="PackedScene" uid="uid://xykil2ydlxoc" path="res://assets/3rdparty/KayKit_Adventurers_1.0_EXTRA/Characters/gltf/Rogue_Hooded.glb" id="1_25fog"] [ext_resource type="Script" path="res://objects/non_player_character.gd" id="1_c2apr"] @@ -9,6 +9,9 @@ height = 0.8 radius = 0.2 +[sub_resource type="BoxShape3D" id="BoxShape3D_d611i"] +size = Vector3(1, 0.9, 0.6) + [sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_7ujep"] animation = &"rogue_animation_library/Idle" @@ -35,10 +38,27 @@ script = ExtResource("1_c2apr") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4, 0) shape = SubResource("CylinderShape3D_uynrb") +[node name="DashCollisionShape" type="CollisionShape3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.571, 0.15) +shape = SubResource("BoxShape3D_d611i") +disabled = true + +[node name="DashDetectionArea" type="Area3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.05) +collision_layer = 0 +collision_mask = 2 +input_ray_pickable = false +monitorable = false + +[node name="DashCollisionShape" type="CollisionShape3D" parent="DashDetectionArea"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.571, 0.15) +shape = SubResource("BoxShape3D_d611i") + [node name="DefaultGeometry" parent="." instance=ExtResource("1_25fog")] unique_name_in_owner = true transform = Transform3D(0.4, 0, 0, 0, 0.4, 0, 0, 0, 0.4, 0, 0, 0) -visible = false [node name="AnimationPlayer" type="AnimationPlayer" parent="."] unique_name_in_owner = true @@ -76,5 +96,7 @@ radius = 0.25 neighbor_distance = 10.0 time_horizon_obstacles = 0.3 +[connection signal="body_entered" from="DashDetectionArea" to="." method="_on_dash_detection_area_body_entered"] +[connection signal="body_exited" from="DashDetectionArea" to="." method="_on_dash_detection_area_body_exited"] [connection signal="body_entered" from="PlayerDetection" to="." method="_on_player_detection_body_entered"] [connection signal="body_exited" from="PlayerDetection" to="." method="_on_player_detection_body_exited"] diff --git a/game_ui.gd b/ui/game_ui.gd similarity index 100% rename from game_ui.gd rename to ui/game_ui.gd diff --git a/world/level.tscn b/world/level.tscn index 8b00701..6152375 100644 --- a/world/level.tscn +++ b/world/level.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=44 format=3 uid="uid://dmagdl5pi6jdj"] +[gd_scene load_steps=45 format=3 uid="uid://dmagdl5pi6jdj"] [ext_resource type="MeshLibrary" uid="uid://dcpuitbu16j1a" path="res://assets/mesh_library.tres" id="1_q0eym"] [ext_resource type="PackedScene" uid="uid://da5r82nvypfk4" path="res://objects/pickup_item.tscn" id="2_ccr0r"] @@ -29,6 +29,7 @@ [ext_resource type="Resource" uid="uid://mn4emvkkv3v4" path="res://dialogue/mage_missing_seeds.dialogue" id="25_5oc06"] [ext_resource type="PackedScene" uid="uid://bipsmw4v7oegd" path="res://objects/chest.tscn" id="25_fhfiw"] [ext_resource type="PackedScene" uid="uid://c56dnyb36mvit" path="res://assets/3rdparty/Quaternius/LowPoly Animated Animals/gltf/Pug.glb" id="29_mexqd"] +[ext_resource type="BehaviorTree" uid="uid://ci4c0hulhunya" path="res://ai/trees/hostile.tres" id="31_3pr5v"] [ext_resource type="PackedScene" uid="uid://dy8vjf760prhq" path="res://assets/characters/rogue.tscn" id="31_ybkxd"] [ext_resource type="BehaviorTree" uid="uid://b6heun7ylvwy4" path="res://ai/trees/follow_path.tres" id="32_o2fv2"] [ext_resource type="PackedScene" uid="uid://o6d18r0ior12" path="res://assets/scene_props/RockB.tscn" id="33_8eayx"] @@ -742,12 +743,20 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 15, 0, -7) [node name="Geometry" parent="Level/Quests/MissingPet/Timmy" instance=ExtResource("31_ybkxd")] transform = Transform3D(0.4, 0, 0, 0, 0.4, 0, 0, 0, 0.4, 0, 0, 0) -[node name="PugNPC2" parent="Level/Quests/MissingPet" instance=ExtResource("23_fjbgv")] +[node name="PatrolNPC" parent="Level/Quests/MissingPet" instance=ExtResource("23_fjbgv")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 13.5, 0, -29.5) behaviour = ExtResource("32_o2fv2") behaviour_blackboard_plan = SubResource("BlackboardPlan_jgxfv") -[node name="Geometry" parent="Level/Quests/MissingPet/PugNPC2" instance=ExtResource("29_mexqd")] +[node name="Geometry" parent="Level/Quests/MissingPet/PatrolNPC" instance=ExtResource("29_mexqd")] +transform = Transform3D(0.2, 0, 0, 0, 0.2, 0, 0, 0, 0.2, 0, 0, 0) + +[node name="DashNPC" parent="Level/Quests/MissingPet" instance=ExtResource("23_fjbgv")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 21, 0, -26.5) +behaviour = ExtResource("31_3pr5v") +behaviour_blackboard_plan = SubResource("BlackboardPlan_jgxfv") + +[node name="Geometry" parent="Level/Quests/MissingPet/DashNPC" instance=ExtResource("29_mexqd")] transform = Transform3D(0.2, 0, 0, 0, 0.2, 0, 0, 0, 0.2, 0, 0, 0) [node name="Water" type="MeshInstance3D" parent="Level"] @@ -832,5 +841,5 @@ transform = Transform3D(-2.82843, 0, 2.82843, 0, 4, 0, -2.82843, 0, -2.82843, -0 curve = SubResource("Curve3D_xbm4j") [node name="PathFollow3D" type="PathFollow3D" parent="PatrolPath01"] -transform = Transform3D(0.999059, -0.000127656, -0.043208, -0.000656565, 0.999827, -0.0181351, 0.0432032, 0.0181465, 0.998894, 12.4989, 0.0434885, -23.996) +transform = Transform3D(0.999058, -0.000127656, -0.043208, -0.000656564, 0.999827, -0.0181351, 0.0432032, 0.0181465, 0.998894, 12.4989, 0.0434885, -23.996) progress = 22.4482