feat: implemented patrol behaviour

This commit is contained in:
Sara Gerretsen 2026-03-18 15:07:56 +01:00
parent 425525e56f
commit 8dbc7fc4ac
23 changed files with 270 additions and 139 deletions

View file

@ -1,19 +1,19 @@
extends BehaviourAction
@export var anim_name := "jab_1"
@export var allow_interrupt := true
@export var face_target := 0.0
@export var wait_for_finish := true
@export var blend := 0.01
@export var anim_name : String = "jab_1"
@export var allow_interrupt : bool = true
@export var face_target : float = 0.0
@export var wait_for_finish : bool = true
@export var blend : float = 0.01
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
@onready var body : CharacterBody3D = get_behaviour_tree().get_parent() as CharacterBody3D
@onready var anim : AnimationPlayer = get_behaviour_tree().get_node("%AnimationPlayer") as AnimationPlayer
var target_position := Vector3()
var anim_started := false
var target_valid = false
var target_position : Vector3 = Vector3.ZERO
var anim_started : bool = false
var target_valid : bool = false
func _enter():
func _enter() -> int:
anim_started = false
anim.play(anim_name, blend)
anim.advance(0)

View file

@ -0,0 +1,13 @@
extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
@onready var anim := get_behaviour_tree().get_node("%AnimationPlayer") as AnimationPlayer
func _enter() -> int:
var full_angle := body.global_basis.z.signed_angle_to((body.global_position - body.target.global_position), Vector3.UP)
body.rotate_y(full_angle)
anim.play("run", .1)
if body.target == null or body.target.global_position.distance_to(body.global_position) > 1.2:
return Fail
else:
return Success

View file

@ -0,0 +1 @@
uid://cgcajnncoittb

View file

@ -0,0 +1,67 @@
[gd_scene format=3 uid="uid://cgkrqn4f7ko13"]
[ext_resource type="Script" uid="uid://cn8wlp7qayg1n" path="res://behaviours/check_weapon.gd" id="1_od7c4"]
[ext_resource type="Script" uid="uid://bp4utstetxnhr" path="res://behaviours/animate.gd" id="2_tes41"]
[ext_resource type="PackedScene" uid="uid://bei8dsmocqe8x" path="res://behaviours/branches/sequence_swing_chain.tscn" id="3_v5s0q"]
[ext_resource type="PackedScene" uid="uid://blpbabfwxdvfr" path="res://behaviours/branches/sequence_jab_chain.tscn" id="4_jd5ki"]
[sub_resource type="GDScript" id="GDScript_xqvpn"]
resource_name = "Wait"
script/source = "extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _enter() -> int:
$Timer.start()
return Running
func _execute() -> int:
return Success if $Timer.time_left == 0 else Running if not body.hurt_high else Fail
"
[node name="SelectorAttackAnimation" type="BehaviourSelector" unique_id=465551260]
[node name="SequenceSword" type="BehaviourSequence" parent="." unique_id=615709382]
[node name="HasSword" type="BehaviourAction" parent="SequenceSword" unique_id=127929802]
script = ExtResource("1_od7c4")
match_type = "sword"
[node name="PlayReady" type="BehaviourAction" parent="SequenceSword" unique_id=1222741719]
script = ExtResource("2_tes41")
anim_name = "ready_sword"
allow_interrupt = false
wait_for_finish = false
[node name="Wait" type="BehaviourAction" parent="SequenceSword" unique_id=842355284]
script = SubResource("GDScript_xqvpn")
[node name="Timer" type="Timer" parent="SequenceSword/Wait" unique_id=582826945]
wait_time = 0.2
one_shot = true
[node name="AlwaysSuccessSwings" type="BehaviourAlwaysSuccess" parent="SequenceSword" unique_id=915120373]
[node name="SequenceSwingChain" parent="SequenceSword/AlwaysSuccessSwings" unique_id=1852235271 instance=ExtResource("3_v5s0q")]
[node name="SequenceUnarmed" type="BehaviourSequence" parent="." unique_id=909023413]
[node name="IsUnarmed" type="BehaviourAction" parent="SequenceUnarmed" unique_id=67204301]
script = ExtResource("1_od7c4")
[node name="PlayReady" type="BehaviourAction" parent="SequenceUnarmed" unique_id=1398202486]
script = ExtResource("2_tes41")
anim_name = "ready_unarmed"
allow_interrupt = false
wait_for_finish = false
[node name="Wait" type="BehaviourAction" parent="SequenceUnarmed" unique_id=420527471]
script = SubResource("GDScript_xqvpn")
[node name="Timer" type="Timer" parent="SequenceUnarmed/Wait" unique_id=48948915]
wait_time = 0.2
one_shot = true
[node name="AlwaysSuccessJabs" type="BehaviourAlwaysSuccess" parent="SequenceUnarmed" unique_id=816001427]
[node name="SequenceJabChain" parent="SequenceUnarmed/AlwaysSuccessJabs" unique_id=376452224 instance=ExtResource("4_jd5ki")]

View file

@ -0,0 +1,24 @@
[gd_scene format=3 uid="uid://box61yo165gs6"]
[ext_resource type="Script" uid="uid://cn8wlp7qayg1n" path="res://behaviours/check_weapon.gd" id="1_ki4y0"]
[ext_resource type="Script" uid="uid://bavm4ks4nsdbe" path="res://behaviours/find_weapon.gd" id="2_5438c"]
[ext_resource type="Script" uid="uid://bs32j3j77txab" path="res://behaviours/equip_target.gd" id="3_62xhk"]
[ext_resource type="Script" uid="uid://66dkrpu2h7kw" path="res://behaviours/move_to_target.gd" id="3_5438c"]
[node name="SequenceFindWeapon" type="BehaviourSequence" unique_id=1379140695]
[node name="IsUnarmed" type="BehaviourAction" parent="." unique_id=1101513261]
script = ExtResource("1_ki4y0")
[node name="FindWeapon" type="BehaviourAction" parent="." unique_id=458518105]
script = ExtResource("2_5438c")
[node name="BehaviourAlwaysSuccess" type="BehaviourAlwaysSuccess" parent="." unique_id=631129208]
[node name="BehaviourSequence" type="BehaviourSequence" parent="BehaviourAlwaysSuccess" unique_id=545263859]
[node name="MoveToTarget" type="BehaviourAction" parent="BehaviourAlwaysSuccess/BehaviourSequence" unique_id=1081201512]
script = ExtResource("3_5438c")
[node name="PickupItem" type="BehaviourAction" parent="BehaviourAlwaysSuccess/BehaviourSequence" unique_id=2083134526]
script = ExtResource("3_62xhk")

View file

@ -0,0 +1,28 @@
[gd_scene format=3 uid="uid://bei8dsmocqe8x"]
[ext_resource type="Script" uid="uid://yhqui7k36cuo" path="res://behaviours/check_jab_requested.gd" id="1_1c6le"]
[ext_resource type="Script" uid="uid://ywfmsbsdc6s7" path="res://behaviours/select_target.gd" id="2_utc7g"]
[ext_resource type="Script" uid="uid://bp4utstetxnhr" path="res://behaviours/animate.gd" id="3_frkt0"]
[node name="SequenceSwingChain" type="BehaviourSequence" unique_id=1852235271]
[node name="SwingInput" type="BehaviourAction" parent="." unique_id=406871114]
script = ExtResource("1_1c6le")
[node name="BehaviourAlwaysSuccess" type="BehaviourAlwaysSuccess" parent="." unique_id=915424847]
[node name="SelectTarget" type="BehaviourAction" parent="BehaviourAlwaysSuccess" unique_id=761801166]
script = ExtResource("2_utc7g")
[node name="PlaySwing1" type="BehaviourAction" parent="." unique_id=788468945]
script = ExtResource("3_frkt0")
anim_name = "swing_1"
face_target = 20.0
[node name="SwingInput2" type="BehaviourAction" parent="." unique_id=1138420787]
script = ExtResource("1_1c6le")
[node name="PlaySwing2" type="BehaviourAction" parent="." unique_id=1140487171]
script = ExtResource("3_frkt0")
anim_name = "swing_2"
face_target = 20.0

View file

@ -0,0 +1,10 @@
extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _enter() -> int:
if body.target == null or not body.target is Area3D:
return Fail
else:
body.equip_weapon(body.target)
return Success

View file

@ -0,0 +1 @@
uid://bs32j3j77txab

View file

@ -0,0 +1,14 @@
extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
@onready var anim := get_behaviour_tree().get_node("%AnimationPlayer") as AnimationPlayer
func _execute() -> int:
var full_angle := body.global_basis.z.signed_angle_to((body.global_position - body.target.global_position), Vector3.UP)
body.rotate_y(full_angle)
anim.play("run", .1)
if body.target == null:
return Fail
elif body.target.global_position.distance_to(body.global_position) <= 1.2:
return Success
return Running

View file

@ -0,0 +1 @@
uid://66dkrpu2h7kw

View file

@ -0,0 +1,11 @@
extends BehaviourAction
@onready var body : CharacterBody3D = get_behaviour_tree().get_parent() as CharacterBody3D
func _enter() -> int:
if body.path.is_empty():
return Fail
if body.global_position.distance_to(body.path[body.patrol_target].global_position) <= 1:
body.patrol_target = wrapi(body.patrol_target + 1, 0, body.path.size())
body.target = body.path[body.patrol_target]
return Success

View file

@ -0,0 +1 @@
uid://c35gy667lpdwp

View file

@ -3,10 +3,10 @@
[ext_resource type="PackedScene" uid="uid://718xlgi5oj6s" path="res://behaviours/branches/sequence_dead.tscn" id="1_d53py"]
[ext_resource type="PackedScene" uid="uid://cpedp17gycei5" path="res://behaviours/branches/sequence_hit_high.tscn" id="1_jqoh2"]
[ext_resource type="Script" uid="uid://ywfmsbsdc6s7" path="res://behaviours/select_target.gd" id="2_1p4o0"]
[ext_resource type="Script" uid="uid://bp4utstetxnhr" path="res://behaviours/animate.gd" id="3_o2gvu"]
[ext_resource type="Script" uid="uid://cn8wlp7qayg1n" path="res://behaviours/check_weapon.gd" id="4_1fc8h"]
[ext_resource type="PackedScene" uid="uid://blpbabfwxdvfr" path="res://behaviours/branches/sequence_jab_chain.tscn" id="4_xqvpn"]
[ext_resource type="Script" uid="uid://bavm4ks4nsdbe" path="res://behaviours/find_weapon.gd" id="5_bmb0k"]
[ext_resource type="Script" uid="uid://c35gy667lpdwp" path="res://behaviours/select_patrol_target.gd" id="3_1fc8h"]
[ext_resource type="PackedScene" uid="uid://box61yo165gs6" path="res://behaviours/branches/sequence_find_weapon.tscn" id="4_d53py"]
[ext_resource type="PackedScene" uid="uid://cgkrqn4f7ko13" path="res://behaviours/branches/selector_attack_animation.tscn" id="7_bmb0k"]
[ext_resource type="Script" uid="uid://cgcajnncoittb" path="res://behaviours/approach_target.gd" id="7_tx7q7"]
[sub_resource type="GDScript" id="GDScript_xqvpn"]
resource_name = "Wait"
@ -22,23 +22,6 @@ func _execute() -> int:
return Success if $Timer.time_left == 0 else Running if not body.hurt_high else Fail
"
[sub_resource type="GDScript" id="GDScript_1p4o0"]
resource_name = "ApproachTarget"
script/source = "extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
@onready var anim := get_behaviour_tree().get_node(\"%AnimationPlayer\") as AnimationPlayer
func _enter() -> int:
var full_angle := body.global_basis.z.signed_angle_to((body.global_position - body.target.global_position), Vector3.UP)
body.rotate_y(full_angle)
anim.play(\"run\", .1)
if body.target == null or body.target.global_position.distance_to(body.global_position) > 1.2:
return Fail
else:
return Success
"
[sub_resource type="GDScript" id="GDScript_41oev"]
resource_name = "EnemyIdle"
script/source = "extends BehaviourAction
@ -46,7 +29,7 @@ script/source = "extends BehaviourAction
@onready var anim := get_behaviour_tree().get_node(\"%AnimationPlayer\") as AnimationPlayer
func _enter() -> int:
anim.play(\"ready_unarmed\", .1)
anim.play(\"RESET\", .1)
return Success
"
@ -77,57 +60,31 @@ script = ExtResource("2_1p4o0")
[node name="SelectorCombat" type="BehaviourSelector" parent="BehaviourRepeater/BehaviourSelector/CombatSequence" unique_id=460186240]
[node name="SequenceFindWeapon" type="BehaviourSequence" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat" unique_id=2110472996]
[node name="IsUnarmed" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/SequenceFindWeapon" unique_id=1668738825]
script = ExtResource("4_1fc8h")
[node name="FindWeapon" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/SequenceFindWeapon" unique_id=2113011800]
script = ExtResource("5_bmb0k")
[node name="BehaviourAlwaysSuccess" type="BehaviourAlwaysSuccess" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/SequenceFindWeapon" unique_id=734558409]
[node name="BehaviourSequence" type="BehaviourSequence" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/SequenceFindWeapon/BehaviourAlwaysSuccess" unique_id=356660420]
[node name="ApproachTarget" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/SequenceFindWeapon/BehaviourAlwaysSuccess/BehaviourSequence" unique_id=983176567]
script = SubResource("GDScript_1p4o0")
[node name="SequenceFindWeapon" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat" unique_id=1379140695 instance=ExtResource("4_d53py")]
[node name="AlwaysSuccessAttack" type="BehaviourAlwaysSuccess" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat" unique_id=1246764318]
[node name="AttackSequence" type="BehaviourSequence" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/AlwaysSuccessAttack" unique_id=560445563]
[node name="SequenceAttack" type="BehaviourSequence" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/AlwaysSuccessAttack" unique_id=560445563]
[node name="SelectTarget" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/AlwaysSuccessAttack/AttackSequence" unique_id=1912259269]
[node name="SelectTarget" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/AlwaysSuccessAttack/SequenceAttack" unique_id=1912259269]
script = ExtResource("2_1p4o0")
[node name="ApproachTarget" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/AlwaysSuccessAttack/AttackSequence" unique_id=2073752420]
script = SubResource("GDScript_1p4o0")
[node name="ApproachTarget" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/AlwaysSuccessAttack/SequenceAttack" unique_id=2073752420]
script = ExtResource("7_tx7q7")
[node name="PlayReady" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/AlwaysSuccessAttack/AttackSequence" unique_id=1015744062]
script = ExtResource("3_o2gvu")
anim_name = "ready_unarmed"
wait_for_finish = false
[node name="SelectorAttackAnimation" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/AlwaysSuccessAttack/SequenceAttack" unique_id=465551260 instance=ExtResource("7_bmb0k")]
[node name="Wait" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/AlwaysSuccessAttack/AttackSequence" unique_id=1130580040]
script = SubResource("GDScript_xqvpn")
[node name="PatrolSequence" type="BehaviourSequence" parent="BehaviourRepeater/BehaviourSelector" unique_id=92762658]
[node name="Timer" type="Timer" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/AlwaysSuccessAttack/AttackSequence/Wait" unique_id=332191936]
wait_time = 0.2
one_shot = true
[node name="SelectPatrolTarget" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/PatrolSequence" unique_id=1912480965]
script = ExtResource("3_1fc8h")
[node name="SequenceJabChain" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/SelectorCombat/AlwaysSuccessAttack/AttackSequence" unique_id=376452224 instance=ExtResource("4_xqvpn")]
[node name="BehaviourAlwaysSuccess" type="BehaviourAlwaysSuccess" parent="BehaviourRepeater/BehaviourSelector/PatrolSequence" unique_id=262177741]
[node name="ApproachTarget" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/PatrolSequence/BehaviourAlwaysSuccess" unique_id=1164066260]
script = ExtResource("7_tx7q7")
[node name="Idle" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector" unique_id=2051783162]
script = SubResource("GDScript_41oev")
[node name="SequenceFindWeapon" type="BehaviourSequence" parent="." unique_id=1390744936]
[node name="IsUnarmed" type="BehaviourAction" parent="SequenceFindWeapon" unique_id=1447353302]
script = ExtResource("4_1fc8h")
[node name="FindWeapon" type="BehaviourAction" parent="SequenceFindWeapon" unique_id=328604984]
script = ExtResource("5_bmb0k")
[node name="ApproachTarget" type="BehaviourAction" parent="SequenceFindWeapon" unique_id=1540477164]
script = SubResource("GDScript_1p4o0")
[editable path="BehaviourRepeater/BehaviourSelector/SequenceHitHigh"]

View file

@ -3,10 +3,8 @@
[ext_resource type="PackedScene" uid="uid://cpedp17gycei5" path="res://behaviours/branches/sequence_hit_high.tscn" id="1_frs2a"]
[ext_resource type="Script" uid="uid://cn8wlp7qayg1n" path="res://behaviours/check_weapon.gd" id="2_cqokf"]
[ext_resource type="PackedScene" uid="uid://blpbabfwxdvfr" path="res://behaviours/branches/sequence_jab_chain.tscn" id="2_lj7kj"]
[ext_resource type="Script" uid="uid://ywfmsbsdc6s7" path="res://behaviours/select_target.gd" id="3_frs2a"]
[ext_resource type="Script" uid="uid://bp4utstetxnhr" path="res://behaviours/animate.gd" id="4_ssybv"]
[ext_resource type="PackedScene" uid="uid://bei8dsmocqe8x" path="res://behaviours/branches/sequence_swing_chain.tscn" id="4_ii6hr"]
[ext_resource type="PackedScene" uid="uid://cct1k2som60e" path="res://behaviours/branches/sequence_sweep_attack.tscn" id="7_48bir"]
[ext_resource type="Script" uid="uid://yhqui7k36cuo" path="res://behaviours/check_jab_requested.gd" id="7_ii6hr"]
[ext_resource type="PackedScene" uid="uid://bydna58cavo7u" path="res://behaviours/branches/sequence_backstep.tscn" id="8_8uf5l"]
[ext_resource type="PackedScene" uid="uid://718xlgi5oj6s" path="res://behaviours/branches/sequence_dead.tscn" id="9_8uf5l"]
@ -71,28 +69,7 @@ match_type = "sword"
[node name="SelectorSword" type="BehaviourSelector" parent="BehaviourRepeater/BehaviourSelector/SequenceSword" unique_id=1145623645]
[node name="SequenceSwingChain" type="BehaviourSequence" parent="BehaviourRepeater/BehaviourSelector/SequenceSword/SelectorSword" unique_id=1933508085]
[node name="SwingInput" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/SequenceSword/SelectorSword/SequenceSwingChain" unique_id=268462513]
script = ExtResource("7_ii6hr")
[node name="BehaviourAlwaysSuccess" type="BehaviourAlwaysSuccess" parent="BehaviourRepeater/BehaviourSelector/SequenceSword/SelectorSword/SequenceSwingChain" unique_id=3437206]
[node name="SelectTarget" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/SequenceSword/SelectorSword/SequenceSwingChain/BehaviourAlwaysSuccess" unique_id=1387971371]
script = ExtResource("3_frs2a")
[node name="PlaySwing1" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/SequenceSword/SelectorSword/SequenceSwingChain" unique_id=799729208]
script = ExtResource("4_ssybv")
anim_name = "swing_1"
face_target = 20.0
[node name="SwingInput2" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/SequenceSword/SelectorSword/SequenceSwingChain" unique_id=2028335229]
script = ExtResource("7_ii6hr")
[node name="PlaySwing2" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/SequenceSword/SelectorSword/SequenceSwingChain" unique_id=255274801]
script = ExtResource("4_ssybv")
anim_name = "swing_2"
face_target = 20.0
[node name="SequenceSwingChain" parent="BehaviourRepeater/BehaviourSelector/SequenceSword/SelectorSword" unique_id=1852235271 instance=ExtResource("4_ii6hr")]
[node name="Movement" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/SequenceSword/SelectorSword" unique_id=1729772543]
script = SubResource("GDScript_ykyjo")