feat: full ninja behaviour

This commit is contained in:
Sara Gerretsen 2026-03-20 19:42:36 +01:00
parent 524430003f
commit 512cf42822
7 changed files with 235 additions and 53 deletions

View file

@ -4,7 +4,7 @@
[sub_resource type="CylinderShape3D" id="CylinderShape3D_uxov2"]
height = 1.296875
radius = 3.2675781
radius = 2.2871094
[node name="AwarenessArea" type="Area3D" unique_id=986494999]
collision_layer = 0

View file

@ -0,0 +1,45 @@
[gd_scene format=3 uid="uid://ljmtmtljlyoc"]
[sub_resource type="GDScript" id="GDScript_3hb37"]
resource_name = "DebugLabel"
script/source = "extends Label3D
var new_text : String = \"\"
func _behaviour_changed(behaviour : BehaviourNode):
if not new_text.is_empty():
new_text += \"\\n\"
for i in $\"../BehaviourTree\".get_path_to(behaviour).get_name_count() - 2:
new_text += \"| \"
new_text += \"- > \"
new_text += behaviour.get_name()
if behaviour is BehaviourAction:
match behaviour.get_status():
BehaviourNode.Fail:
new_text += \" (FAIL)\"
BehaviourNode.Success:
new_text += \" (SUCCESS)\"
BehaviourNode.Running:
new_text += \" (RUNNING)\"
func _ready():
$\"../BehaviourTree\".current_behaviour_changed.connect(_behaviour_changed)
func _process(_delta):
if not new_text.is_empty():
text = new_text
new_text = \"\"
"
[node name="DebugLabel" type="Label3D" unique_id=1911478572]
process_mode = 3
pixel_size = 0.0005
billboard = 1
fixed_size = true
render_priority = 10
text = "SOMETHING WENT WRONG!!!"
horizontal_alignment = 0
vertical_alignment = 2
autowrap_trim_flags = 0
justification_flags = 0
script = SubResource("GDScript_3hb37")

View file

@ -4,6 +4,7 @@
[ext_resource type="Script" uid="uid://csqsliec0twij" path="res://scripts/damage_area.gd" id="2_41oev"]
[ext_resource type="Script" uid="uid://cfr2fxpk46n0b" path="res://scripts/weapon_parent.gd" id="3_3hb37"]
[ext_resource type="PackedScene" uid="uid://bjrst6dj2vtud" path="res://behaviours/trees/enemy_behaviours.tscn" id="3_we7g8"]
[ext_resource type="PackedScene" uid="uid://ljmtmtljlyoc" path="res://objects/debug_label.tscn" id="4_2ld5k"]
[ext_resource type="PackedScene" uid="uid://deuif6d8spece" path="res://objects/awareness_area.tscn" id="4_we7g8"]
[sub_resource type="GDScript" id="GDScript_882u1"]
@ -18,6 +19,10 @@ signal damaged(amount : int, source : Node3D)
var hurt_high : bool = false
var target : Node3D = null
var patrol_target : int = 0
var blinded : int = 0
func set_blinded(value : bool):
blinded += 1 if value else -1
func _ready():
damaged.connect(_damaged)
@ -42,13 +47,13 @@ func get_current_weapon_type() -> String:
return \"\" if %WeaponParent.weapon == null else %WeaponParent.weapon.animations
func find_targets() -> Array[Node3D]:
return $AwarenessArea.aware
return $AwarenessArea.aware if blinded == 0 else Array([], TYPE_OBJECT, \"Node3D\", Node3D)
func weapon_filter(node : Node3D):
return node.can_interact()
func find_weapons() -> Array[Node3D]:
return $ItemAwareness.aware.filter(weapon_filter)
return $ItemAwareness.aware.filter(weapon_filter) if blinded == 0 else []
func wants_jab_attack() -> bool:
return target and target.global_position.distance_to(global_position) < 1.5
@ -63,37 +68,6 @@ size = Vector3(0.33496094, 0.5253906, 0.26367188)
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_882u1"]
radius = 0.2133789
[sub_resource type="GDScript" id="GDScript_3hb37"]
resource_name = "DebugLabel"
script/source = "extends Label3D
var new_text : String = \"\"
func _behaviour_changed(behaviour : BehaviourNode):
if not new_text.is_empty():
new_text += \"\\n\"
for i in $\"../BehaviourTree\".get_path_to(behaviour).get_name_count() - 2:
new_text += \"| \"
new_text += \"- > \"
new_text += behaviour.get_name()
if behaviour is BehaviourAction:
match behaviour.get_status():
BehaviourNode.Fail:
new_text += \" (FAIL)\"
BehaviourNode.Success:
new_text += \" (SUCCESS)\"
BehaviourNode.Running:
new_text += \" (RUNNING)\"
func _ready():
$\"../BehaviourTree\".current_behaviour_changed.connect(_behaviour_changed)
func _process(_delta):
if not new_text.is_empty():
text = new_text
new_text = \"\"
"
[sub_resource type="CylinderShape3D" id="CylinderShape3D_we7g8"]
height = 3.3642578
radius = 9.955078
@ -158,19 +132,8 @@ root_motion_track = NodePath("Character/Skeleton3D:root")
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("CapsuleShape3D_882u1")
[node name="Label3D" type="Label3D" parent="." index="3" unique_id=1185308080]
process_mode = 3
[node name="DebugLabel" parent="." index="3" unique_id=1911478572 instance=ExtResource("4_2ld5k")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.2257917, 0)
pixel_size = 0.0005
billboard = 1
fixed_size = true
render_priority = 10
text = "SOMETHING WENT WRONG!!!"
horizontal_alignment = 0
vertical_alignment = 2
autowrap_trim_flags = 0
justification_flags = 0
script = SubResource("GDScript_3hb37")
[node name="BehaviourTree" parent="." index="4" unique_id=82050956 instance=ExtResource("3_we7g8")]

View file

@ -2,7 +2,7 @@
[sub_resource type="CylinderShape3D" id="CylinderShape3D_b3nq0"]
height = 1.0986328
radius = 0.6591797
radius = 2.0
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_5kkkq"]
transparency = 3
@ -17,6 +17,8 @@ height = 3.0
[node name="Bush" type="Node3D" unique_id=2000109671]
[node name="HidingSpot2" type="Area3D" parent="." unique_id=1348668493 groups=["HidingSpot"]]
collision_layer = 2
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="HidingSpot2" unique_id=807995647]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.4506836, 0)

View file

@ -1,9 +1,12 @@
[gd_scene format=3 uid="uid://cu1nh3rbcnn3w"]
[ext_resource type="PackedScene" uid="uid://hirlnhjbqv2u" path="res://assets/characters/bot.blend" id="1_fssyu"]
[ext_resource type="Script" uid="uid://66dkrpu2h7kw" path="res://behaviours/move_to_target.gd" id="2_exeof"]
[ext_resource type="Script" uid="uid://bm6unenoiyy5h" path="res://behaviours/follow_target.gd" id="2_klwnj"]
[ext_resource type="Script" uid="uid://bp4utstetxnhr" path="res://behaviours/animate.gd" id="3_klwnj"]
[ext_resource type="PackedScene" uid="uid://deuif6d8spece" path="res://objects/awareness_area.tscn" id="3_tpgvx"]
[ext_resource type="PackedScene" uid="uid://dplnyssh3gglv" path="res://objects/smokebomb.tscn" id="4_obqat"]
[ext_resource type="PackedScene" uid="uid://ljmtmtljlyoc" path="res://objects/debug_label.tscn" id="5_jh7vn"]
[sub_resource type="GDScript" id="GDScript_klwnj"]
resource_name = "NinjaBody"
@ -11,6 +14,7 @@ script/source = "extends CharacterBody3D
@export var player : Node3D
var hurt_high : bool = false
var target : Node3D
func _physics_process(delta : float):
@ -18,6 +22,9 @@ func _physics_process(delta : float):
velocity = motion.x * global_basis.x + motion.z * global_basis.z + velocity.y * Vector3.UP
velocity += get_gravity() * delta
move_and_slide()
func get_hiding_spot():
return null if %HidingSpotAwareness.aware.is_empty() else %HidingSpotAwareness.aware[0]
"
[sub_resource type="GDScript" id="GDScript_jh7vn"]
@ -27,24 +34,70 @@ script/source = "extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _enter() -> int:
return Fail if body.find_targets().is_empty() else Success
return Success if body.player.target and body.player.target.is_in_group(\"EnemyHitbox\") else Fail
"
[sub_resource type="GDScript" id="GDScript_exeof"]
resource_name = "SelectHidingSpot"
script/source = "extends BehaviourAction
var body := get_behaviour_tree().get_parent() as CharacterBody3D
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _enter() -> int:
var spot : Node3D = body.get_hiding_spot()
if spot:
body.target = spot
body.target = body.get_hiding_spot()
if body.target != null:
return Success
else:
return Fail
"
[sub_resource type="GDScript" id="GDScript_obqat"]
resource_name = "SelectEnemy"
script/source = "extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _enter() -> int:
if body.player.target and body.player.target.is_in_group(\"EnemyHitbox\"):
body.target = body.player.target
return Success
else:
return Fail
"
[sub_resource type="GDScript" id="GDScript_tyg5v"]
resource_name = "ThrowSmokeBomb"
script/source = "extends BehaviourAction
@export var smoke_bomb : PackedScene
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _enter() -> int:
if not body.target or not smoke_bomb:
return Fail
var instance := smoke_bomb.instantiate() as Node3D
if not instance:
push_error(\"what? (invalid smoke bomb scene, ensure root is Node3D derived)\")
return Fail
instance.position = body.target.global_position
get_tree().current_scene.add_child(instance)
return Success
"
[sub_resource type="GDScript" id="GDScript_o1uh3"]
resource_name = "WaitForSafety"
script/source = "extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _enter() -> int:
return Running
func _execute() -> int:
return Running if body.player.target and body.player.target.is_in_group(\"EnemyHitbox\") else Success
"
[sub_resource type="GDScript" id="GDScript_tpgvx"]
resource_name = "SelectPlayer"
script/source = "extends BehaviourAction
@ -62,7 +115,13 @@ albedo_color = Color(0.4745098, 0.16862746, 0.61960787, 1)
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_lyptg"]
radius = 0.30273438
[sub_resource type="CylinderShape3D" id="CylinderShape3D_exeof"]
height = 6.5117188
radius = 13.45459
[node name="Ninja" unique_id=1341242765 instance=ExtResource("1_fssyu")]
collision_layer = 2
collision_mask = 3
script = SubResource("GDScript_klwnj")
[node name="BehaviourTree" type="BehaviourTree" parent="." index="0" unique_id=1843075231]
@ -79,6 +138,24 @@ script = SubResource("GDScript_jh7vn")
[node name="SelectHidingSpot" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceCombat" index="1" unique_id=1743644615]
script = SubResource("GDScript_exeof")
[node name="MoveToHide" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceCombat" index="2" unique_id=1071198062]
script = ExtResource("2_exeof")
[node name="PlayHide" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceCombat" index="3" unique_id=1052844547]
script = ExtResource("3_klwnj")
anim_name = "duck"
wait_for_finish = false
[node name="SelectAttacker" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceCombat" index="4" unique_id=520574199]
script = SubResource("GDScript_obqat")
[node name="ThrowSmokeBomb" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceCombat" index="5" unique_id=1944021610]
script = SubResource("GDScript_tyg5v")
smoke_bomb = ExtResource("4_obqat")
[node name="WaitForSafety" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceCombat" index="6" unique_id=622297891]
script = SubResource("GDScript_o1uh3")
[node name="SequenceFollowPlayer" type="BehaviourSequence" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector" index="1" unique_id=1977466711]
[node name="SelectPlayer" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceFollowPlayer" index="0" unique_id=92830272]
@ -111,4 +188,10 @@ unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.92650235, 0)
target_group = "HidingSpot"
[node name="CollisionShape3D" parent="HidingSpotAwareness" index="0" unique_id=2035583636]
shape = SubResource("CylinderShape3D_exeof")
[node name="DebugLabel" parent="." index="5" unique_id=1911478572 instance=ExtResource("5_jh7vn")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.1390142, 0)
[editable path="HidingSpotAwareness"]

View file

@ -0,0 +1,89 @@
[gd_scene format=3 uid="uid://dplnyssh3gglv"]
[sub_resource type="GDScript" id="GDScript_itny3"]
resource_name = "SmokeBomb"
script/source = "extends Node3D
var ttl : float = 5
func _process(delta : float):
position.y += delta
ttl -= delta
if ttl < 0:
queue_free()
"
[sub_resource type="GDScript" id="GDScript_g3kfb"]
resource_name = "BlindingArea"
script/source = "extends Area3D
func _body_entered(node : Node3D):
if node.has_method(\"set_blinded\"):
node.set_blinded(true)
func _body_exited(node : Node3D):
if node.has_method(\"set_blinded\"):
node.set_blinded(false)
func _ready():
body_entered.connect(_body_entered)
body_exited.connect(_body_exited)
"
[sub_resource type="SphereShape3D" id="SphereShape3D_g3kfb"]
radius = 4.8821044
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_g3kfb"]
transparency = 3
alpha_hash_scale = 0.1
alpha_antialiasing_mode = 0
cull_mode = 2
shading_mode = 0
diffuse_mode = 3
specular_mode = 2
disable_specular_occlusion = true
albedo_color = Color(0, 0, 0, 0.7137255)
[sub_resource type="SphereMesh" id="SphereMesh_g3kfb"]
radius = 5.0
height = 10.0
[sub_resource type="SphereMesh" id="SphereMesh_itny3"]
radius = 4.5
height = 9.0
[sub_resource type="SphereMesh" id="SphereMesh_qhsiq"]
radius = 3.0
height = 6.0
[sub_resource type="SphereMesh" id="SphereMesh_ej7fq"]
radius = 1.0
height = 2.0
[node name="Smokebomb" type="Node3D" unique_id=1624127579]
script = SubResource("GDScript_itny3")
[node name="BlindingArea" type="Area3D" parent="." unique_id=1563830988]
collision_layer = 0
collision_mask = 2
script = SubResource("GDScript_g3kfb")
[node name="CollisionShape3D" type="CollisionShape3D" parent="BlindingArea" unique_id=1316931580]
shape = SubResource("SphereShape3D_g3kfb")
debug_color = Color(1, 1, 1, 0.41960785)
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=454136629]
material_override = SubResource("StandardMaterial3D_g3kfb")
mesh = SubResource("SphereMesh_g3kfb")
[node name="MeshInstance3D2" type="MeshInstance3D" parent="." unique_id=1574435532]
material_override = SubResource("StandardMaterial3D_g3kfb")
mesh = SubResource("SphereMesh_itny3")
[node name="MeshInstance3D3" type="MeshInstance3D" parent="." unique_id=1913531178]
material_override = SubResource("StandardMaterial3D_g3kfb")
mesh = SubResource("SphereMesh_qhsiq")
[node name="MeshInstance3D4" type="MeshInstance3D" parent="." unique_id=1108186863]
material_override = SubResource("StandardMaterial3D_g3kfb")
mesh = SubResource("SphereMesh_ej7fq")

View file

@ -5,7 +5,7 @@ extends Area3D
var aware : Array[Node3D]
func _entered(node : Node3D):
if node.is_in_group(target_group):
if node and node.is_in_group(target_group):
aware.push_back(node)
func _exited(node : Node3D):