diff --git a/project/objects/player.tscn b/project/objects/player.tscn index 4bd7d04e..3fe7bf3f 100644 --- a/project/objects/player.tscn +++ b/project/objects/player.tscn @@ -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")