feat: player animation integrations

This commit is contained in:
Sara Gerretsen 2026-04-29 11:06:03 +02:00
parent 058fc459a9
commit e1a200d3ee

View file

@ -1,49 +1,208 @@
[gd_scene format=3 uid="uid://8t87iy0t0igo"]
[ext_resource type="PackedScene" uid="uid://c1g1vy67lf550" path="res://assets/character/player/player.tscn" id="1_eqqp1"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_bxedw"]
radius = 0.6972656
radius = 0.4
[sub_resource type="CapsuleMesh" id="CapsuleMesh_eqqp1"]
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_1oybq"]
[sub_resource type="BoxMesh" id="BoxMesh_bxedw"]
size = Vector3(0.2, 0.2, 0.2)
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_eqqp1"]
animation = &"fall"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_ykyjo"]
animation = &"jump"
[sub_resource type="AnimationNodeBlendSpace1D" id="AnimationNodeBlendSpace1D_jbsc3"]
blend_point_0/node = SubResource("AnimationNodeAnimation_eqqp1")
blend_point_0/pos = -1.0
blend_point_0/name = &"jump"
blend_point_1/node = SubResource("AnimationNodeAnimation_ykyjo")
blend_point_1/pos = 1.0
blend_point_1/name = &"jump 2"
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_ykyjo"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_3rerk"]
animation = &"RESET"
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_uxov2"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_i825w"]
animation = &"run-start"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_3rfka"]
animation = &"run"
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_i8sra"]
switch_mode = 2
advance_mode = 2
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_4vq5b"]
advance_mode = 2
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_eqqp1"]
switch_mode = 1
advance_expression = "body.velocity.x == 0 && body.velocity.z == 0"
[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_3nfmf"]
reset_ends = true
states/run/node = SubResource("AnimationNodeAnimation_3rfka")
states/run/position = Vector2(603.5664, 100)
states/run-start/node = SubResource("AnimationNodeAnimation_i825w")
states/run-start/position = Vector2(439.96094, 100)
transitions = ["run-start", "run", SubResource("AnimationNodeStateMachineTransition_i8sra"), "Start", "run-start", SubResource("AnimationNodeStateMachineTransition_4vq5b"), "run", "End", SubResource("AnimationNodeStateMachineTransition_eqqp1")]
graph_offset = Vector2(-64.40625, 19.996094)
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_i8sra"]
animation = &"skid"
[sub_resource type="AnimationNodeTimeScale" id="AnimationNodeTimeScale_jbsc3"]
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_3rerk"]
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_nmc1l"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_uxov2"]
animation = &"grip"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_f46kd"]
animation = &"wallrun_left"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_nmc1l"]
animation = &"wallrun_right"
[sub_resource type="AnimationNodeBlend2" id="AnimationNodeBlend2_eqqp1"]
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_uxov2"]
graph_offset = Vector2(-1016.22144, 160.28812)
nodes/output/position = Vector2(520, 140)
nodes/RunStates/node = SubResource("AnimationNodeStateMachine_3nfmf")
nodes/RunStates/position = Vector2(-800, 320)
nodes/AirVelocity/node = SubResource("AnimationNodeBlendSpace1D_jbsc3")
nodes/AirVelocity/position = Vector2(-140, 480)
nodes/Air/node = SubResource("AnimationNodeBlend2_1oybq")
nodes/Air/position = Vector2(80, 140)
nodes/Speed/node = SubResource("AnimationNodeTimeScale_jbsc3")
nodes/Speed/position = Vector2(-560, 320)
nodes/Wall/node = SubResource("AnimationNodeBlend2_3rerk")
nodes/Wall/position = Vector2(300, 140)
nodes/WallAction/node = SubResource("AnimationNodeBlend2_nmc1l")
nodes/WallAction/position = Vector2(80, 680)
nodes/WallGripLoop/node = SubResource("AnimationNodeAnimation_uxov2")
nodes/WallGripLoop/position = Vector2(-140, 680)
nodes/WallRunLeftLoop/node = SubResource("AnimationNodeAnimation_f46kd")
nodes/WallRunLeftLoop/position = Vector2(-360, 860)
nodes/WallRunSide/node = SubResource("AnimationNodeBlend2_eqqp1")
nodes/WallRunSide/position = Vector2(-140, 860)
nodes/WallRunRightLoop/node = SubResource("AnimationNodeAnimation_nmc1l")
nodes/WallRunRightLoop/position = Vector2(-360, 1040)
nodes/SkidStopLoop/node = SubResource("AnimationNodeAnimation_i8sra")
nodes/SkidStopLoop/position = Vector2(-560, 500)
nodes/IdleLoop/node = SubResource("AnimationNodeAnimation_3rerk")
nodes/IdleLoop/position = Vector2(-340, 140)
nodes/Moving/node = SubResource("AnimationNodeBlend2_uxov2")
nodes/Moving/position = Vector2(-140, 140)
nodes/Decelerating/node = SubResource("AnimationNodeBlend2_ykyjo")
nodes/Decelerating/position = Vector2(-340, 320)
node_connections = [&"output", 0, &"Wall", &"Air", 0, &"Moving", &"Air", 1, &"AirVelocity", &"Speed", 0, &"RunStates", &"Wall", 0, &"Air", &"Wall", 1, &"WallAction", &"WallAction", 0, &"WallGripLoop", &"WallAction", 1, &"WallRunSide", &"WallRunSide", 0, &"WallRunLeftLoop", &"WallRunSide", 1, &"WallRunRightLoop", &"Moving", 0, &"IdleLoop", &"Moving", 1, &"Decelerating", &"Decelerating", 0, &"Speed", &"Decelerating", 1, &"SkidStopLoop"]
[sub_resource type="GDScript" id="GDScript_i825w"]
resource_name = "PlayerAnimationPlayer"
script/source = "extends AnimationTree
@onready var body := get_owner() as PlayerBody
@onready var behaviour_tree : PlayerBehaviourTree = $\"../../PlayerBehaviourTree\"
@export var default_blend_time : float
func property_move_toward(prop : String, target, speed):
var current = get(prop)
var diff = target - current
var dir = sign(diff)
if abs(diff) <= speed:
set(prop, target)
else:
set(prop, current + dir * speed)
func _process(delta: float) -> void:
var speed : float = abs(body.velocity.x) + abs(body.velocity.z)
set(\"parameters/Speed/scale\", clamp(speed / 15.0, 0.0, 1.0))
property_move_toward(\"parameters/Decelerating/blend_amount\", 0.0 if behaviour_tree.get_world_move_input().dot(body.velocity) > 0.0 else 1.0, delta * default_blend_time)
property_move_toward(\"parameters/Moving/blend_amount\", 1.0 if speed > 0.02 else 0.0, delta * default_blend_time)
property_move_toward(\"parameters/Air/blend_amount\", 0.0 if body.is_on_floor() else 1.0, delta * default_blend_time)
set(\"parameters/AirVelocity/blend_position\", body.velocity.y / 5.0)
"
[sub_resource type="GDScript" id="GDScript_f46kd"]
resource_name = "WallJumpAction"
script/source = "extends PlayerAction
@export var far_jump_normal_force : float
@export var far_jump_up_force : float
@export var far_jump_input_force : float
@export var high_jump_normal_force : float
@export var high_jump_up_force : float
func _enter() -> int:
if body.is_on_wall_only() and Input.is_action_just_pressed(\"jump\"):
var flat_wall := Vector3(body.get_wall_normal().x, 0.0, body.get_wall_normal().z).normalized()
var wall := body.get_wall_normal()
if wall.dot(blackboard.get_world_move_input().normalized()) > 0.75:
body.velocity = body.get_wall_normal() * 4
body.velocity.y = 6
var flat_velocity := Vector2(body.velocity.x, body.velocity.z)
if flat_velocity.is_zero_approx() or wall.dot(blackboard.get_world_move_input().normalized()) < -0.5:
body.velocity = flat_wall * high_jump_normal_force
body.velocity.y = high_jump_up_force
elif blackboard.get_world_move_input().normalized().dot(body.velocity.normalized()) >= 0.0:
body.velocity += flat_wall * high_jump_normal_force + blackboard.get_world_move_input() * far_jump_input_force
body.velocity.y = far_jump_up_force
else:
body.velocity += body.get_wall_normal() * 3
body.velocity.y = 4
blackboard.character.look_at(blackboard.character.global_position + Vector3(body.velocity.x, 0, body.velocity.y))
return Fail
blackboard.character.look_at(blackboard.character.global_position + Vector3(body.velocity.x, 0, body.velocity.z))
return Success
else:
return Fail
"
[sub_resource type="GDScript" id="GDScript_nmc1l"]
resource_name = "WallSlideAction"
resource_name = "WallGripAction"
script/source = "extends PlayerAction
@export var wall_drag : float
@export var max_y_velocity : float
func _enter() -> int:
if body.is_on_wall_only():
var flat_velocity := Vector2(body.velocity.x, body.velocity.z)
var input_into_wall := blackboard.get_world_move_input().normalized().dot(body.get_wall_normal()) < -0.5
if body.is_on_wall_only() and (flat_velocity.length() <= abs(body.velocity.y * 2.0) or input_into_wall):
var delta := get_process_delta_time()
var target_velocity := Vector3(0, min(body.velocity.y, 0.0), 0)
var target_velocity := Vector3(0, clamp(body.velocity.y, -max_y_velocity, 0.0), 0)
body.velocity = body.velocity.move_toward(target_velocity, wall_drag * delta) + (body.get_gravity() * 0.2 * delta)
blackboard.character.look_at(blackboard.character.global_position + body.get_wall_normal())
blackboard.anim.set(\"parameters/WallAction/blend_amount\", 0.0)
blackboard.anim.property_move_toward(\"parameters/Wall/blend_amount\", 1.0 if body.is_on_wall_only() else 0.0, delta * blackboard.anim.default_blend_time)
return Success
else:
return Fail
"
[sub_resource type="GDScript" id="GDScript_3rfka"]
resource_name = "PlayerWallRunAction"
script/source = "extends PlayerAction
func _enter() -> int:
if body.is_on_wall_only() and blackboard.get_world_move_input().normalized().dot(body.velocity.normalized()) >= 0.0:
body.velocity += body.get_gravity() * get_process_delta_time()
blackboard.character.look_at(blackboard.character.global_position + body.velocity)
blackboard.anim.set(\"parameters/WallAction/blend_amount\", 1.0)
blackboard.anim.property_move_toward(\"parameters/Wall/blend_amount\", 1.0, get_process_delta_time() * blackboard.anim.default_blend_time)
var dot : float = body.get_wall_normal().dot(blackboard.character.basis.x)
blackboard.anim.set(\"parameters/WallRunSide/blend_amount\", 0.0 if dot > 0 else 1.0)
return Success
else:
blackboard.anim.property_move_toward(\"parameters/Wall/blend_amount\", 0.0, get_process_delta_time() * blackboard.anim.default_blend_time)
return Fail
"
[sub_resource type="GDScript" id="GDScript_ykyjo"]
resource_name = "FallingAction"
script/source = "extends PlayerAction
@ -51,6 +210,10 @@ script/source = "extends PlayerAction
func _enter() -> int:
if not body.is_on_floor():
body.velocity += body.get_gravity() * get_process_delta_time()
var flat_velocity : Vector3 = body.velocity
flat_velocity.y = 0
if not flat_velocity.is_zero_approx():
blackboard.character.look_at(blackboard.character.global_position + flat_velocity)
return Success
else:
return Fail
@ -75,7 +238,7 @@ resource_name = "RunningAction"
script/source = "extends PlayerMovementAction
func _enter() -> int:
if Input.is_action_pressed(\"run\"):
if Input.is_action_pressed(\"run\") and not blackboard.move_input.is_zero_approx():
process_movement()
return Success
else:
@ -86,6 +249,17 @@ func _enter() -> int:
resource_name = "WalkAction"
script/source = "extends PlayerMovementAction
func _enter() -> int:
if blackboard.move_input.is_zero_approx():
return Fail
process_movement()
return Success
"
[sub_resource type="GDScript" id="GDScript_3rerk"]
resource_name = "PlayerIdleAction"
script/source = "extends PlayerMovementAction
func _enter() -> int:
process_movement()
return Success
@ -94,47 +268,68 @@ func _enter() -> int:
[node name="Player" type="PlayerBody" unique_id=591139793]
slide_on_ceiling = false
wall_min_slide_angle = 1.0471976
floor_max_angle = 0.17453292
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1143027860]
shape = SubResource("CapsuleShape3D_bxedw")
[node name="Character" type="Node3D" parent="." unique_id=1790276362]
unique_name_in_owner = true
[node name="PlayerModel" parent="." unique_id=1710695753 instance=ExtResource("1_eqqp1")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0)
[node name="MeshInstance3D" type="MeshInstance3D" parent="Character" unique_id=1058685291]
mesh = SubResource("CapsuleMesh_eqqp1")
skeleton = NodePath("../..")
[node name="MeshInstance3D2" type="MeshInstance3D" parent="Character" unique_id=1223918276]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.49871957)
mesh = SubResource("BoxMesh_bxedw")
[node name="AnimationTree" type="AnimationTree" parent="PlayerModel" unique_id=847372421]
tree_root = SubResource("AnimationNodeBlendTree_uxov2")
anim_player = NodePath("../AnimationPlayer")
parameters/AirVelocity/blend_position = 0.0
parameters/Air/blend_amount = 0.0
parameters/Speed/scale = 1.0
parameters/Wall/blend_amount = 0.0
parameters/WallAction/blend_amount = 0.0
parameters/WallRunSide/blend_amount = 0.0
parameters/Moving/blend_amount = 0.0
parameters/Decelerating/blend_amount = 0.0
script = SubResource("GDScript_i825w")
default_blend_time = 30.0
[node name="Camera3D" type="PlayerCamera" parent="." unique_id=709217818]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.3841858e-07, 1.3299754, 4.29688)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.3841858e-07, 0.81082594, 2.0684447)
fov = 71.84121
[node name="PlayerBehaviourTree" type="PlayerBehaviourTree" parent="." unique_id=1439326326]
[node name="PlayerBehaviourTree" type="PlayerBehaviourTree" parent="." unique_id=1439326326 node_paths=PackedStringArray("character")]
character = NodePath("../PlayerModel")
[node name="BehaviourRepeater" type="BehaviourRepeater" parent="PlayerBehaviourTree" unique_id=766320099]
[node name="ActionSelector" type="BehaviourSelector" parent="PlayerBehaviourTree/BehaviourRepeater" unique_id=433229675]
[node name="WallJumpAction" type="PlayerAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=1070446491]
[node name="WallJump" type="PlayerAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=1070446491]
script = SubResource("GDScript_f46kd")
far_jump_normal_force = 6.0
far_jump_up_force = 4.0
far_jump_input_force = 2.0
high_jump_normal_force = 4.0
high_jump_up_force = 6.0
[node name="WallSlideAction" type="PlayerAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=85039173]
[node name="WallGrip" type="PlayerAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=85039173]
script = SubResource("GDScript_nmc1l")
wall_drag = 5.0
max_y_velocity = 2.0
[node name="FallingAction" type="PlayerAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=570179125]
[node name="WallRun" type="PlayerAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=2090512639]
script = SubResource("GDScript_3rfka")
[node name="Fall" type="PlayerAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=570179125]
script = SubResource("GDScript_ykyjo")
[node name="JumpAction" type="PlayerAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=553747039]
[node name="Jump" type="PlayerAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=553747039]
script = SubResource("GDScript_eqqp1")
vertical_jump_velocity = 5.0
[node name="RunningAction" type="PlayerMovementAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=2080183164]
[node name="Run" type="PlayerMovementAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=2080183164]
target_speed = 10.0
script = SubResource("GDScript_bxedw")
[node name="WalkAction" type="PlayerMovementAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=1371791141]
[node name="Walk" type="PlayerMovementAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=1371791141]
script = SubResource("GDScript_uxov2")
[node name="Idle" type="PlayerMovementAction" parent="PlayerBehaviourTree/BehaviourRepeater/ActionSelector" unique_id=718383984]
script = SubResource("GDScript_3rerk")