feat: implemented basic enemy

This commit is contained in:
Sara Gerretsen 2026-03-15 17:18:49 +01:00
parent 03d94552d7
commit 764b6a5072
29 changed files with 12932 additions and 139 deletions

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,21 +1,36 @@
extends BehaviourAction
@export var attack_name := "jab_1"
@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
@onready var body := owner
@onready var body := 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
func _enter():
anim_started = false
anim.play(attack_name, .0)
anim.play(anim_name, blend)
anim.advance(0)
return Running
target_valid = body.target != null
if target_valid:
target_position = body.target.global_position
return Running if wait_for_finish else Success
func _execute() -> int:
if anim.current_animation == attack_name:
anim_started = true
elif anim_started:
if wait_for_finish:
if face_target > 0.0 and target_valid:
var max_angle := body.global_basis.z.signed_angle_to(body.global_position - target_position, Vector3.UP)
body.rotate_y(clampf(max_angle, -face_target * get_process_delta_time(), face_target * get_process_delta_time()))
if anim.current_animation == anim_name:
anim_started = true
elif anim_started:
return Success
return Fail if allow_interrupt and body.hurt_high else Running
else:
return Success
return Running

View file

@ -0,0 +1,27 @@
[gd_scene format=3 uid="uid://cpedp17gycei5"]
[ext_resource type="Script" uid="uid://bp4utstetxnhr" path="res://behaviours/animate.gd" id="1_kltr5"]
[sub_resource type="GDScript" id="GDScript_nmc1l"]
script/source = "extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _execute() -> int:
if body.hurt_high:
body.hurt_high = false
return Success
else:
return Fail
"
[node name="SequenceHitHigh" type="BehaviourSequence" unique_id=1573780476]
[node name="WasHurt" type="BehaviourAction" parent="." unique_id=1958671333]
script = SubResource("GDScript_nmc1l")
[node name="StaggerHighAnim" type="BehaviourAction" parent="." unique_id=809148281]
script = ExtResource("1_kltr5")
anim_name = "stagger_high"
face_target = 30.0
blend = 0.03

View file

@ -0,0 +1,35 @@
[gd_scene format=3 uid="uid://blpbabfwxdvfr"]
[ext_resource type="Script" uid="uid://yhqui7k36cuo" path="res://behaviours/check_attack_possible.gd" id="1_kk63v"]
[ext_resource type="Script" uid="uid://ywfmsbsdc6s7" path="res://behaviours/select_target.gd" id="2_tlqqd"]
[ext_resource type="Script" uid="uid://bp4utstetxnhr" path="res://behaviours/animate.gd" id="3_4aw38"]
[node name="SequenceJabChain" type="BehaviourSequence" unique_id=376452224]
[node name="JabInput" type="BehaviourAction" parent="." unique_id=1443020388]
script = ExtResource("1_kk63v")
[node name="BehaviourAlwaysSuccess" type="BehaviourAlwaysSuccess" parent="." unique_id=516110125]
[node name="SelectTarget" type="BehaviourAction" parent="BehaviourAlwaysSuccess" unique_id=877812137]
script = ExtResource("2_tlqqd")
[node name="PlayJab1" type="BehaviourAction" parent="." unique_id=1728135061]
script = ExtResource("3_4aw38")
face_target = 25.0
[node name="JabInput2" type="BehaviourAction" parent="." unique_id=1524082262]
script = ExtResource("1_kk63v")
[node name="PlayJab2" type="BehaviourAction" parent="." unique_id=670555475]
script = ExtResource("3_4aw38")
anim_name = "jab_2"
face_target = 25.0
[node name="JabInput3" type="BehaviourAction" parent="." unique_id=775472176]
script = ExtResource("1_kk63v")
[node name="PlayHook1" type="BehaviourAction" parent="." unique_id=636596422]
script = ExtResource("3_4aw38")
anim_name = "hook_1"
face_target = 25.0

View file

@ -0,0 +1,9 @@
extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _enter() -> int:
if body.attack_possible():
return Success
else:
return Fail

View file

@ -1,10 +0,0 @@
extends BehaviourAction
@onready var body := owner
func _enter() -> int:
if body.attack_queued:
body.attack_queued = false
return Success
else:
return Fail

View file

@ -0,0 +1,12 @@
extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _enter():
var targets : Array[Node3D] = body.find_targets()
if targets.is_empty():
body.target = null
return Fail
else:
body.target = body.find_targets()[0]
return Success

View file

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

View file

@ -0,0 +1,143 @@
[gd_scene format=3 uid="uid://bjrst6dj2vtud"]
[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="PackedScene" uid="uid://blpbabfwxdvfr" path="res://behaviours/branches/sequence_jab_chain.tscn" id="4_xqvpn"]
[sub_resource type="GDScript" id="GDScript_d53py"]
resource_name = "CheckIsDead"
script/source = "extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _enter() -> int:
return Success if body.health <= 0 else Fail
"
[sub_resource type="GDScript" id="GDScript_1fc8h"]
resource_name = "RepeatForever"
script/source = "extends BehaviourAction
func _enter() -> int: return Running
func _execute() -> int: return Running
"
[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
"
[sub_resource type="GDScript" id="GDScript_o2gvu"]
resource_name = "AtPlayer"
script/source = "extends BehaviourAction
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func _enter() -> int:
if body.target == null or body.target.global_position.distance_to(body.global_position) > 1.5:
return Fail
return Success
"
[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)
return Success
"
[sub_resource type="GDScript" id="GDScript_41oev"]
resource_name = "EnemyIdle"
script/source = "extends BehaviourAction
@onready var anim := get_behaviour_tree().get_node(\"%AnimationPlayer\") as AnimationPlayer
func _enter() -> int:
anim.play(\"ready_unarmed\", .1)
return Success
"
[node name="BehaviourTree" type="BehaviourTree" unique_id=82050956]
[node name="BehaviourRepeater" type="BehaviourRepeater" parent="." unique_id=1340157903]
[node name="BehaviourSelector" type="BehaviourSelector" parent="BehaviourRepeater" unique_id=187196594]
[node name="BehaviourSequence" type="BehaviourSequence" parent="BehaviourRepeater/BehaviourSelector" unique_id=1884612259]
[node name="CheckIsDead" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/BehaviourSequence" unique_id=618322261]
script = SubResource("GDScript_d53py")
[node name="PlayKOHigh" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/BehaviourSequence" unique_id=1625230778]
script = ExtResource("3_o2gvu")
anim_name = "ko_high"
allow_interrupt = false
[node name="RepeatForever" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/BehaviourSequence" unique_id=752877367]
script = SubResource("GDScript_1fc8h")
[node name="SequenceHitHigh" parent="BehaviourRepeater/BehaviourSelector" unique_id=1573780476 instance=ExtResource("1_jqoh2")]
[node name="Wait" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/SequenceHitHigh" unique_id=481327400]
script = SubResource("GDScript_xqvpn")
[node name="Timer" type="Timer" parent="BehaviourRepeater/BehaviourSelector/SequenceHitHigh/Wait" unique_id=1997241537]
wait_time = 0.1
one_shot = true
[node name="CombatSequence" type="BehaviourSequence" parent="BehaviourRepeater/BehaviourSelector" unique_id=611769881]
[node name="SelectTarget" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence" unique_id=56930655]
script = ExtResource("2_1p4o0")
[node name="BehaviourAlwaysSuccess" type="BehaviourAlwaysSuccess" parent="BehaviourRepeater/BehaviourSelector/CombatSequence" unique_id=1246764318]
[node name="BehaviourSequence" type="BehaviourSequence" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/BehaviourAlwaysSuccess" unique_id=560445563]
[node name="BehaviourSelector" type="BehaviourSelector" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/BehaviourAlwaysSuccess/BehaviourSequence" unique_id=1389418648]
[node name="AtPlayer" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/BehaviourAlwaysSuccess/BehaviourSequence/BehaviourSelector" unique_id=1884043694]
script = SubResource("GDScript_o2gvu")
[node name="ApproachTarget" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/BehaviourAlwaysSuccess/BehaviourSequence/BehaviourSelector" unique_id=2073752420]
script = SubResource("GDScript_1p4o0")
[node name="AtPlayer" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/BehaviourAlwaysSuccess/BehaviourSequence" unique_id=1885476200]
script = SubResource("GDScript_o2gvu")
[node name="PlayReady" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/BehaviourAlwaysSuccess/BehaviourSequence" unique_id=1015744062]
script = ExtResource("3_o2gvu")
anim_name = "ready_unarmed"
wait_for_finish = false
[node name="Wait" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/BehaviourAlwaysSuccess/BehaviourSequence" unique_id=1130580040]
script = SubResource("GDScript_xqvpn")
[node name="Timer" type="Timer" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/BehaviourAlwaysSuccess/BehaviourSequence/Wait" unique_id=332191936]
wait_time = 0.1
one_shot = true
[node name="SequenceJabChain" parent="BehaviourRepeater/BehaviourSelector/CombatSequence/BehaviourAlwaysSuccess/BehaviourSequence" unique_id=376452224 instance=ExtResource("4_xqvpn")]
[node name="Idle" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector" unique_id=2051783162]
script = SubResource("GDScript_41oev")
[editable path="BehaviourRepeater/BehaviourSelector/SequenceHitHigh"]

View file

@ -0,0 +1,65 @@
[gd_scene format=3 uid="uid://cex7kfgjqwnl7"]
[ext_resource type="PackedScene" uid="uid://cpedp17gycei5" path="res://behaviours/branches/sequence_hit_high.tscn" id="1_frs2a"]
[ext_resource type="PackedScene" uid="uid://blpbabfwxdvfr" path="res://behaviours/branches/sequence_jab_chain.tscn" id="2_lj7kj"]
[sub_resource type="GDScript" id="GDScript_ykyjo"]
resource_name = "PlayerMovement"
script/source = "extends BehaviourAction
var max_rotation_per_second : float = 15
var input : Vector2 = Vector2()
@onready var body : CharacterBody3D = get_behaviour_tree().get_parent() as CharacterBody3D
@onready var anim := get_behaviour_tree().get_node(\"%AnimationPlayer\") as AnimationPlayer
func _unhandled_input(event : InputEvent):
if event.is_action(\"move_forward\") or event.is_action(\"move_back\"):
input.y = Input.get_axis(\"move_forward\", \"move_back\")
get_viewport().set_input_as_handled()
elif event.is_action(\"move_left\") or event.is_action(\"move_right\"):
input.x = Input.get_axis(\"move_left\", \"move_right\")
get_viewport().set_input_as_handled()
func _enter() -> int:
if input.is_zero_approx():
return Fail
var camera_basis : Basis = get_viewport().get_camera_3d().global_basis
var flat_x := Vector3(camera_basis.x.x, 0, camera_basis.x.z).normalized()
var flat_z := Vector3(camera_basis.z.x, 0, camera_basis.z.z).normalized()
var direction := flat_x * input.x + flat_z * input.y;
var total_delta := body.global_basis.z.signed_angle_to(-direction, Vector3.UP)
var max_rotation := get_process_delta_time() * max_rotation_per_second
body.rotate_y(clampf(total_delta, -max_rotation, max_rotation))
anim.play(\"run\", .1)
return Success
"
[sub_resource type="GDScript" id="GDScript_uxov2"]
resource_name = "PlayerIdle"
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:
anim.play(\"ready_unarmed\", .1)
body.velocity = Vector3()
return Success
"
[node name="BehaviourTree" type="BehaviourTree" unique_id=2061972400]
[node name="BehaviourRepeater" type="BehaviourRepeater" parent="." unique_id=126839278]
[node name="BehaviourSelector" type="BehaviourSelector" parent="BehaviourRepeater" unique_id=1131993986]
[node name="SequenceHitHigh" parent="BehaviourRepeater/BehaviourSelector" unique_id=1573780476 instance=ExtResource("1_frs2a")]
[node name="SequenceJabChain" parent="BehaviourRepeater/BehaviourSelector" unique_id=376452224 instance=ExtResource("2_lj7kj")]
[node name="Movement" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector" unique_id=532637433]
script = SubResource("GDScript_ykyjo")
[node name="Idle" type="BehaviourAction" parent="BehaviourRepeater/BehaviourSelector" unique_id=1909318122]
script = SubResource("GDScript_uxov2")

View file

@ -0,0 +1,17 @@
[gd_scene format=3 uid="uid://deuif6d8spece"]
[ext_resource type="Script" uid="uid://c8d8mj6dy26ur" path="res://scripts/awareness_area.gd" id="1_ibr75"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_uxov2"]
height = 1.296875
radius = 4.459961
[node name="AwarenessArea" type="Area3D" unique_id=986494999]
collision_layer = 0
collision_mask = 2
monitorable = false
script = ExtResource("1_ibr75")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=2035583636]
shape = SubResource("CylinderShape3D_uxov2")
debug_color = Color(0.5434826, 0.40605906, 1, 0.41960785)

116
project/objects/enemy.tscn Normal file
View file

@ -0,0 +1,116 @@
[gd_scene format=3 uid="uid://1s2obm2l4f1a"]
[ext_resource type="PackedScene" uid="uid://hirlnhjbqv2u" path="res://assets/characters/bot.blend" id="1_882u1"]
[ext_resource type="Script" uid="uid://csqsliec0twij" path="res://scripts/damage_area.gd" id="2_41oev"]
[ext_resource type="PackedScene" uid="uid://bjrst6dj2vtud" path="res://behaviours/trees/enemy_behaviours.tscn" id="3_we7g8"]
[ext_resource type="PackedScene" uid="uid://deuif6d8spece" path="res://objects/awareness_area.tscn" id="4_we7g8"]
[sub_resource type="GDScript" id="GDScript_882u1"]
resource_name = "EnemyBody"
script/source = "extends CharacterBody3D
signal damaged(amount : int, source : Node3D)
@export var health : int = 6
var hurt_high : bool = false
@onready var anim := %AnimationPlayer as AnimationPlayer
var target : Node3D = null
func _ready():
damaged.connect(_damaged)
func _damaged(amount : int, source : Node3D):
hurt_high = true
target = source
health -= amount
func _physics_process(delta : float):
var motion := anim.get_root_motion_position()
velocity = (motion.x * global_basis.x + motion.z * global_basis.z) / delta
move_and_slide()
func find_targets() -> Array[Node3D]:
return $AwarenessArea.aware
func attack_possible() -> bool:
return target and target.global_position.distance_to(global_position) < 1.5
"
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_41oev"]
albedo_color = Color(0.36862746, 0.5686275, 1, 1)
[sub_resource type="BoxShape3D" id="BoxShape3D_we7g8"]
size = Vector3(0.33496094, 0.23144531, 0.26367188)
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_882u1"]
radius = 0.33984375
[sub_resource type="CylinderShape3D" id="CylinderShape3D_we7g8"]
height = 1.296875
radius = 5.7021484
[node name="bot" unique_id=250133973 groups=["EnemyHitbox"] instance=ExtResource("1_882u1")]
collision_layer = 2
collision_mask = 3
script = SubResource("GDScript_882u1")
[node name="Mesh" parent="Character/Skeleton3D" parent_id_path=PackedInt32Array(706042794) index="0" unique_id=1499137314]
material_override = SubResource("StandardMaterial3D_41oev")
[node name="HandR" type="BoneAttachment3D" parent="Character/Skeleton3D" parent_id_path=PackedInt32Array(706042794) index="1" unique_id=957498611]
transform = Transform3D(0.015967373, -0.083946444, 0.9963424, -0.17989334, -0.98045003, -0.07972447, 0.9835564, -0.17796235, -0.030756809, 0.27221423, 0.7951686, 0.024477992)
bone_name = "hand.r"
bone_idx = 10
[node name="DamageAreaR" type="Area3D" parent="Character/Skeleton3D/HandR" index="0" unique_id=999461654 node_paths=PackedStringArray("source")]
collision_layer = 0
collision_mask = 2
monitoring = false
monitorable = false
script = ExtResource("2_41oev")
source = NodePath("../../../..")
damage_group = "PlayerHitbox"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Character/Skeleton3D/HandR/DamageAreaR" index="0" unique_id=1459089003]
transform = Transform3D(1.0000031, -3.5762787e-07, 1.4210855e-14, -1.1920929e-07, 1.0000023, -1.49011585e-08, -5.5879497e-09, 4.917384e-07, 1, 9.4322706e-05, 0.101888776, -0.010492921)
shape = SubResource("BoxShape3D_we7g8")
debug_color = Color(0.9966913, 0, 0.17880186, 1)
[node name="HandL" type="BoneAttachment3D" parent="Character/Skeleton3D" parent_id_path=PackedInt32Array(706042794) index="2" unique_id=1761081841]
transform = Transform3D(-0.039434362, 0.07924447, -0.9960749, 0.12679999, -0.9883944, -0.083653376, -0.99114394, -0.12960118, 0.028928574, -0.2710728, 0.7714727, 0.0945672)
bone_name = "hand.l"
bone_idx = 7
[node name="DamageAreaL" type="Area3D" parent="Character/Skeleton3D/HandL" index="0" unique_id=607683055 node_paths=PackedStringArray("source")]
collision_layer = 0
collision_mask = 2
monitoring = false
monitorable = false
script = ExtResource("2_41oev")
source = NodePath("../../../..")
damage_group = "PlayerHitbox"
[node name="CollisionShape3D" type="CollisionShape3D" parent="Character/Skeleton3D/HandL/DamageAreaL" index="0" unique_id=2069345419]
transform = Transform3D(1.0000169, -1.5795231e-06, -3.874302e-07, 8.046627e-07, 1.0000216, -3.7252903e-07, -8.046627e-07, 8.046627e-07, 1.0000148, -4.8220158e-05, 0.101875365, -0.010286808)
shape = SubResource("BoxShape3D_we7g8")
debug_color = Color(0.9966913, 0, 0.17880186, 1)
[node name="AnimationPlayer" parent="." index="1" unique_id=445797329]
unique_name_in_owner = true
root_motion_track = NodePath("Character/Skeleton3D:root")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." index="2" unique_id=283680831]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("CapsuleShape3D_882u1")
[node name="BehaviourTree" parent="." index="3" unique_id=82050956 instance=ExtResource("3_we7g8")]
[node name="AwarenessArea" parent="." index="4" unique_id=986494999 instance=ExtResource("4_we7g8")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0324535, 0)
[node name="CollisionShape3D" parent="AwarenessArea" index="0" unique_id=2035583636]
shape = SubResource("CylinderShape3D_we7g8")
[editable path="AwarenessArea"]

View file

@ -1,14 +1,25 @@
[gd_scene format=3 uid="uid://d0yivm54mjib2"]
[ext_resource type="PackedScene" uid="uid://hirlnhjbqv2u" path="res://assets/characters/bot.blend" id="1_eqqp1"]
[ext_resource type="Script" uid="uid://yhqui7k36cuo" path="res://behaviours/consume_jab.gd" id="2_uxov2"]
[ext_resource type="Script" uid="uid://bp4utstetxnhr" path="res://behaviours/animate.gd" id="2_ykyjo"]
[ext_resource type="PackedScene" uid="uid://cex7kfgjqwnl7" path="res://behaviours/trees/player_behaviours.tscn" id="2_uxov2"]
[ext_resource type="PackedScene" uid="uid://deuif6d8spece" path="res://objects/awareness_area.tscn" id="4_f46kd"]
[ext_resource type="Script" uid="uid://csqsliec0twij" path="res://scripts/damage_area.gd" id="4_nmc1l"]
[sub_resource type="GDScript" id="GDScript_eqqp1"]
script/source = "extends CharacterBody3D
signal damaged(amount : int, source : Node3D)
var attack_queued : bool = false
var hurt_high : bool = false
var target : Node3D = null
func _ready():
damaged.connect(_damaged)
func _damaged(_amount : int, source : Node3D):
hurt_high = true
target = source
func _physics_process(delta: float):
var root_velocity : Vector3 = %AnimationPlayer.get_root_motion_position() / delta
@ -19,150 +30,121 @@ func _unhandled_input(event : InputEvent):
if event.is_action_pressed(\"jab\"):
attack_queued = true
get_viewport().set_input_as_handled()
"
[sub_resource type="GDScript" id="GDScript_nmc1l"]
script/source = "extends BehaviourAction
func is_valid_target(node : Node3D) -> bool:
return node.health > 0
@onready var body := get_behaviour_tree().get_parent() as CharacterBody3D
func find_targets() -> Array[Node3D]:
return $AwarenessArea.aware.filter(is_valid_target)
func _execute() -> int:
if body.hurt_high:
body.hurt_high = false
return Success
else:
return Fail
"
[sub_resource type="GDScript" id="GDScript_ykyjo"]
resource_name = "PlayerMovement"
script/source = "extends BehaviourAction
var max_rotation_per_second : float = 15
var input : Vector2 = Vector2()
@onready var body : CharacterBody3D = get_behaviour_tree().get_parent() as CharacterBody3D
@onready var anim := get_behaviour_tree().get_node(\"%AnimationPlayer\") as AnimationPlayer
func _unhandled_input(event : InputEvent):
if event.is_action(\"move_forward\") or event.is_action(\"move_back\"):
input.y = Input.get_axis(\"move_forward\", \"move_back\")
get_viewport().set_input_as_handled()
elif event.is_action(\"move_left\") or event.is_action(\"move_right\"):
input.x = Input.get_axis(\"move_left\", \"move_right\")
get_viewport().set_input_as_handled()
func _enter() -> int:
if input.is_zero_approx():
return Fail
var camera_basis : Basis = get_viewport().get_camera_3d().global_basis
var flat_x := Vector3(camera_basis.x.x, 0, camera_basis.x.z).normalized()
var flat_z := Vector3(camera_basis.z.x, 0, camera_basis.z.z).normalized()
var direction := flat_x * input.x + flat_z * input.y;
var total_delta := body.global_basis.z.signed_angle_to(-direction, Vector3.UP)
var max_rotation := get_process_delta_time() * max_rotation_per_second
body.rotate_y(clampf(total_delta, -max_rotation, max_rotation))
anim.play(\"run\", .1)
return Success
"
[sub_resource type="GDScript" id="GDScript_uxov2"]
resource_name = "PlayerIdle"
script/source = "extends BehaviourAction
func _enter() -> int:
get_behaviour_tree().get_node(\"%AnimationPlayer\").play(\"ready\", .1)
(owner as CharacterBody3D).velocity = Vector3()
return Success
func attack_possible() -> bool:
if attack_queued:
attack_queued = false
return true
return false
"
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_eqqp1"]
radius = 0.30371094
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_uxov2"]
albedo_color = Color(0.5254902, 0.69411767, 1, 1)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_f46kd"]
albedo_color = Color(0.8666667, 0.22352941, 0.41568628, 1)
[sub_resource type="BoxShape3D" id="BoxShape3D_uxov2"]
size = Vector3(0.33496094, 0.4033203, 0.26367188)
size = Vector3(0.33496094, 0.19042969, 0.26367188)
[node name="bot" unique_id=1222178058 instance=ExtResource("1_eqqp1")]
[sub_resource type="GDScript" id="GDScript_nmc1l"]
resource_name = "CameraPivot"
script/source = "extends Node3D
var input : Vector2 = Vector2.ZERO
@onready var stored_rotation : Vector3 = global_rotation
func _ready():
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _unhandled_input(event : InputEvent):
if event is InputEventMouseMotion:
input = event.relative * 0.002
func _process(_delta):
stored_rotation.y = wrapf(stored_rotation.y - input.x, 0, PI * 2.0)
stored_rotation.x = clampf(stored_rotation.x - input.y, -PI / 4.0, PI / 4.0)
global_rotation = stored_rotation
input = Vector2.ZERO
"
[sub_resource type="SphereShape3D" id="SphereShape3D_nmc1l"]
radius = 0.3
[node name="bot" unique_id=1726366668 groups=["PlayerHitbox"] instance=ExtResource("1_eqqp1")]
collision_layer = 2
collision_mask = 3
script = SubResource("GDScript_eqqp1")
[node name="BehaviourTree" type="BehaviourTree" parent="." index="0" unique_id=2108584329]
[node name="BehaviourRepeater" type="BehaviourRepeater" parent="BehaviourTree" index="0" unique_id=2061538109]
[node name="BehaviourSelector" type="BehaviourSelector" parent="BehaviourTree/BehaviourRepeater" index="0" unique_id=1931421694]
[node name="SequenceHitHigh" type="BehaviourSequence" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector" index="0" unique_id=649050605]
[node name="WasHurt" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceHitHigh" index="0" unique_id=1391609239]
script = SubResource("GDScript_nmc1l")
[node name="HurtHighAnim" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceHitHigh" index="1" unique_id=425114947]
script = ExtResource("2_ykyjo")
attack_name = "stagger_high"
[node name="SequenceJabChain" type="BehaviourSequence" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector" index="1" unique_id=637026832]
[node name="JabInput" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceJabChain" index="0" unique_id=215816583]
script = ExtResource("2_uxov2")
[node name="Jab1Anim" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceJabChain" index="1" unique_id=486339280]
script = ExtResource("2_ykyjo")
[node name="JabInput2" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceJabChain" index="2" unique_id=1083914312]
script = ExtResource("2_uxov2")
[node name="Jab2Anim" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceJabChain" index="3" unique_id=1010781881]
script = ExtResource("2_ykyjo")
attack_name = "jab_2"
[node name="JabInput3" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceJabChain" index="4" unique_id=583017375]
script = ExtResource("2_uxov2")
[node name="Hook1Anim" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector/SequenceJabChain" index="5" unique_id=217672683]
script = ExtResource("2_ykyjo")
attack_name = "hook_1"
[node name="Movement" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector" index="2" unique_id=838466796]
script = SubResource("GDScript_ykyjo")
[node name="Idle" type="BehaviourAction" parent="BehaviourTree/BehaviourRepeater/BehaviourSelector" index="3" unique_id=878625744]
script = SubResource("GDScript_uxov2")
[node name="PlayerBehaviours" parent="." index="0" unique_id=2061972400 instance=ExtResource("2_uxov2")]
[node name="PhysicsShape" type="CollisionShape3D" parent="." index="1" unique_id=1611683515]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("CapsuleShape3D_eqqp1")
debug_color = Color(0, 0.6, 0.69803923, 1)
[node name="Mesh" parent="Character/Skeleton3D" parent_id_path=PackedInt32Array(1717786181) index="0" unique_id=154641310]
surface_material_override/0 = SubResource("StandardMaterial3D_uxov2")
[node name="AwarenessArea" parent="." index="2" unique_id=986494999 instance=ExtResource("4_f46kd")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0963671, 0)
target_group = "EnemyHitbox"
[node name="HandR" type="BoneAttachment3D" parent="Character/Skeleton3D" parent_id_path=PackedInt32Array(1717786181) index="1" unique_id=385862689]
[node name="Mesh" parent="Character/Skeleton3D" parent_id_path=PackedInt32Array(1931156214) index="0" unique_id=613701145]
material_override = SubResource("StandardMaterial3D_f46kd")
[node name="HandR" type="BoneAttachment3D" parent="Character/Skeleton3D" parent_id_path=PackedInt32Array(1931156214) index="1" unique_id=385862689]
transform = Transform3D(0.015967373, -0.083946444, 0.9963424, -0.17989334, -0.98045003, -0.07972447, 0.9835564, -0.17796235, -0.030756809, 0.27221423, 0.7951686, 0.024477992)
bone_name = "hand.r"
bone_idx = 10
[node name="Area3D" type="Area3D" parent="Character/Skeleton3D/HandR" index="0" unique_id=1170013417]
[node name="DamageAreaR" type="Area3D" parent="Character/Skeleton3D/HandR" index="0" unique_id=1170013417 node_paths=PackedStringArray("source")]
collision_layer = 0
collision_mask = 2
monitoring = false
monitorable = false
script = ExtResource("4_nmc1l")
source = NodePath("../../../..")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Character/Skeleton3D/HandR/Area3D" index="0" unique_id=580766922]
transform = Transform3D(1.0000031, -3.5762787e-07, 1.4210855e-14, -1.1920929e-07, 1.0000023, -1.49011585e-08, -5.5879497e-09, 4.917384e-07, 1, 9.4322706e-05, 0.101888776, -0.010492921)
[node name="CollisionShape3D" type="CollisionShape3D" parent="Character/Skeleton3D/HandR/DamageAreaR" index="0" unique_id=580766922]
transform = Transform3D(1.0000031, -4.61936e-07, -8.940697e-08, -1.1920929e-07, 1.0000024, 1.3969839e-09, -7.264316e-08, 4.703179e-07, 1, 9.433925e-05, 0.10188866, -0.010492891)
shape = SubResource("BoxShape3D_uxov2")
debug_color = Color(0.9966913, 0, 0.17880186, 1)
[node name="HandL" type="BoneAttachment3D" parent="Character/Skeleton3D" parent_id_path=PackedInt32Array(1717786181) index="2" unique_id=279793409]
[node name="HandL" type="BoneAttachment3D" parent="Character/Skeleton3D" parent_id_path=PackedInt32Array(1931156214) index="2" unique_id=279793409]
transform = Transform3D(-0.039434362, 0.07924447, -0.9960749, 0.12679999, -0.9883944, -0.083653376, -0.99114394, -0.12960118, 0.028928574, -0.2710728, 0.7714727, 0.0945672)
bone_name = "hand.l"
bone_idx = 7
[node name="Area3D" type="Area3D" parent="Character/Skeleton3D/HandL" index="0" unique_id=552609571]
[node name="DamageAreaL" type="Area3D" parent="Character/Skeleton3D/HandL" index="0" unique_id=552609571 node_paths=PackedStringArray("source")]
collision_layer = 0
collision_mask = 2
monitoring = false
monitorable = false
script = ExtResource("4_nmc1l")
source = NodePath("../../../..")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Character/Skeleton3D/HandL/Area3D" index="0" unique_id=513165671]
[node name="CollisionShape3D" type="CollisionShape3D" parent="Character/Skeleton3D/HandL/DamageAreaL" index="0" unique_id=513165671]
transform = Transform3D(1.0000169, -1.5944242e-06, -4.04194e-07, 6.556511e-07, 1.0000216, -4.172325e-07, -2.7939663e-08, 8.046625e-07, 1.0000148, -4.8151425e-05, 0.101875424, -0.010286927)
shape = SubResource("BoxShape3D_uxov2")
debug_color = Color(0.9966913, 0, 0.17880186, 1)
[node name="AnimationPlayer" parent="." index="3" unique_id=1369805121]
[node name="AnimationPlayer" parent="." index="4" unique_id=951425454]
unique_name_in_owner = true
root_motion_track = NodePath("Character/Skeleton3D:root")
[node name="CameraPivot" type="Node3D" parent="." index="5" unique_id=1714065679]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.3769674, 0)
script = SubResource("GDScript_nmc1l")
[node name="SpringArm3D" type="SpringArm3D" parent="CameraPivot" index="0" unique_id=1656112632]
transform = Transform3D(0.9698174, 0, 0.24383235, 0, 1, 0, -0.24383235, 0, 0.9698174, 0.06544638, 0.66225195, 0)
shape = SubResource("SphereShape3D_nmc1l")
spring_length = 3.0
[node name="Camera3D" type="Camera3D" parent="CameraPivot/SpringArm3D" index="0" unique_id=552400396]
transform = Transform3D(0.9664448, 0.056318317, -0.25062487, 0, 0.97567, 0.2192444, 0.25687462, -0.21188758, 0.9429312, 0, 0, 0)
fov = 52.5

View file

@ -10,6 +10,7 @@ config_version=5
[animation]
warnings/check_invalid_track_paths=false
compatibility/default_parent_skeleton_in_mesh_instance_3d=true
[application]
@ -19,6 +20,11 @@ run/main_scene="uid://dnm5d16scmirb"
config/features=PackedStringArray("4.7", "Forward Plus")
config/icon="res://icon.svg"
[global_group]
PlayerHitbox=""
EnemyHitbox=""
[input]
move_left={
@ -43,10 +49,15 @@ move_back={
}
jab={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":74,"key_label":0,"unicode":106,"location":0,"echo":false,"script":null)
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(108.19922, 27.601563),"global_position":Vector2(117.19922, 75.60156),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
]
}
[layer_names]
3d_physics/layer_1="General"
3d_physics/layer_2="Hitboxes"
[physics]
3d/physics_engine="Jolt Physics"

View file

@ -1,6 +1,7 @@
[gd_scene format=3 uid="uid://dnm5d16scmirb"]
[ext_resource type="PackedScene" uid="uid://d0yivm54mjib2" path="res://objects/player.tscn" id="1_upt1h"]
[ext_resource type="PackedScene" uid="uid://1s2obm2l4f1a" path="res://objects/enemy.tscn" id="2_w0s2s"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_upt1h"]
sky_horizon_color = Color(0.66224277, 0.6717428, 0.6867428, 1)
@ -23,14 +24,17 @@ environment = SubResource("Environment_4r7d4")
transform = Transform3D(0.2302671, 0.8427532, -0.48656374, 4.2118103e-08, 0.5, 0.8660255, 0.97312754, -0.19941717, 0.11513353, 0, 0, 0)
shadow_enabled = true
[node name="Camera3D" type="Camera3D" parent="." unique_id=473807903]
transform = Transform3D(1, 0, 0, 0, 0.9036031, 0.42837068, 0, -0.42837068, 0.9036031, 1.9073486e-06, 9.186176, 19.605062)
fov = 24.81873
[node name="bot" parent="." unique_id=969338301 instance=ExtResource("1_upt1h")]
[node name="CSGCombiner3D" type="CSGCombiner3D" parent="." unique_id=1773598072]
[node name="CSGBox3D" type="CSGBox3D" parent="CSGCombiner3D" unique_id=624831705]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.121719554, 0)
size = Vector3(10.588867, 0.25, 12.052734)
[node name="bot" parent="." unique_id=1120032835 instance=ExtResource("1_upt1h")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.035994053, 0, -0.025122881)
[node name="bot2" parent="." unique_id=1748234506 instance=ExtResource("2_w0s2s")]
transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0, 0, -3)
[node name="bot3" parent="." unique_id=2120168079 instance=ExtResource("2_w0s2s")]
transform = Transform3D(0.3496833, 0, -0.93686795, 0, 1, 0, 0.93686795, 0, 0.3496833, -5.7783833, 0, 3.5097082)

View file

@ -0,0 +1,16 @@
extends Area3D
@export var target_group := "PlayerHitbox"
var aware : Array[Node3D]
func _body_entered(node : Node3D):
if node.is_in_group(target_group):
aware.push_back(node)
func _body_exited(node : Node3D):
aware.erase(node)
func _ready():
body_entered.connect(_body_entered)
body_exited.connect(_body_exited)

View file

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

View file

@ -0,0 +1,12 @@
extends Area3D
@export var source : Node3D
@export var damage_group : String = "EnemyHitbox"
@export var damage : int = 1
func _body_entered(node : Node):
if node.is_in_group(damage_group):
node.damaged.emit(damage, (source if source != null else owner) as Node3D)
func _ready():
body_entered.connect(_body_entered)

View file

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