Changes to the player
- Made the character inherit from StairsCharacter3D (Plugin) - Made the players head smoothly adjust when stepping. - Reintroduced the previously broken headbobbing. - Adjusted collisions.
This commit is contained in:
parent
31363b1d52
commit
a4100e3026
@ -1,5 +1,5 @@
|
||||
class_name Character3D
|
||||
extends CharacterBody3D
|
||||
extends StairsCharacter3D
|
||||
|
||||
@export var movement: CharacterMovement
|
||||
@export var speed_scale: float = 1.0
|
||||
@ -12,11 +12,11 @@ var air_control: float = 1.0
|
||||
var freeze_air_control: bool = false
|
||||
var last_platform_velocity := Vector3.ZERO
|
||||
var _was_on_floor: bool = false
|
||||
var _previous_velocity: Vector3
|
||||
var previous_velocity: Vector3
|
||||
|
||||
|
||||
func move(direction: Vector3, delta: float) -> void:
|
||||
direction *= (speed * speed_scale)
|
||||
direction *= speed * speed_scale
|
||||
|
||||
var on_floor: bool = is_on_floor()
|
||||
|
||||
@ -56,9 +56,9 @@ func move(direction: Vector3, delta: float) -> void:
|
||||
velocity = velocity.move_toward(direction, speed_change * delta)
|
||||
|
||||
await get_tree().physics_frame
|
||||
_previous_velocity = velocity
|
||||
previous_velocity = velocity
|
||||
#DebugDraw3D.draw_arrow(global_position, global_position + velocity, Color.BLUE, 0.5, true)
|
||||
#SPrint.print_msg("%s Velocity: %s" %[self , velocity], 0.02)
|
||||
#SPrint.print_msg("%s Velocity: %s" % [self , velocity], 0.02)
|
||||
|
||||
|
||||
## @tutorial: https://gmtk.itch.io/platformer-toolkit/devlog/395523/behind-the-code
|
||||
@ -67,13 +67,13 @@ func apply_gravity(delta: float) -> void:
|
||||
var gravity_multiplier: float = 1.0
|
||||
|
||||
if velocity.y < -margin:
|
||||
#SPrint.print_msg("Falling\n%s" %velocity.y, 0.02)
|
||||
#SPrint.print_msg("Falling\n%s" % velocity.y, 0.02)
|
||||
gravity_multiplier = movement.fall_gravity_multiplier
|
||||
elif velocity.y > margin:
|
||||
#SPrint.print_msg("Rising\n%s" %velocity.y, 0.02)
|
||||
#SPrint.print_msg("Rising\n%s" % velocity.y, 0.02)
|
||||
gravity_multiplier = movement.rise_gravity_multiplier
|
||||
else:
|
||||
#SPrint.print_msg("Peaking\n%s" %velocity.y, 0.02)
|
||||
#SPrint.print_msg("Peaking\n%s" % velocity.y, 0.02)
|
||||
gravity_multiplier = movement.peak_gravity_multiplier
|
||||
|
||||
velocity.y -= (movement.get_gravity() * gravity_multiplier) * delta
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class_name GameCamera3D
|
||||
class_name PlayerHead
|
||||
extends Node3D
|
||||
|
||||
const ACTION_CAMERA_UP: StringName = &"camera_up"
|
||||
@ -38,13 +38,24 @@ const CONTROLLER_INVERT_Y_PATH: StringName = &"game/input/camera_controller_inve
|
||||
@export var headbob_frequency: float = 0.5
|
||||
@export var headbob_multiplier: float = 1.0
|
||||
@export var headbob_character: Character3D
|
||||
@export var headbob_target: Node3D
|
||||
|
||||
@export_group("Step Smoothing", "step_")
|
||||
@export var step_smoothing_target: Node3D
|
||||
@export var step_speed: float = 8.0
|
||||
|
||||
var rotational_direction: Vector2
|
||||
var rotational_velocity: Vector2
|
||||
var input_event: InputEvent
|
||||
var using_controller: bool = false
|
||||
# Headbobbing
|
||||
var headbob_time: float = 0.0
|
||||
var headbob_enabled: bool = true
|
||||
# Stair smooting
|
||||
var stair_camera_offset_height: float = 0.0
|
||||
var _previous_position: Vector3
|
||||
var _stair_camera_target_height: float = 0.0
|
||||
var _stair_camera_step_smoothing: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -62,18 +73,23 @@ func _ready() -> void:
|
||||
ProjectSettings.settings_changed.connect(_update_settings)
|
||||
_update_settings.call()
|
||||
|
||||
_setup_step_smoothing()
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if not GameGlobals.in_cutscene:
|
||||
_process_input(delta)
|
||||
_perform_head_bob(delta)
|
||||
|
||||
_process_step_smoothing(delta)
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseMotion or event is InputEventJoypadMotion:
|
||||
input_event = event
|
||||
|
||||
|
||||
#region Mouse/Controller rotation
|
||||
func apply_rotation(rot: Vector2) -> void:
|
||||
rotate_y(-rot.x)
|
||||
rotation.x = rotation.x - rot.y
|
||||
@ -156,12 +172,14 @@ func _process_controller(delta: float) -> void:
|
||||
|
||||
func _lerp_rotational_velocity(sensitivity: float, friction: float, delta: float) -> Vector2:
|
||||
return rotational_velocity.lerp(rotational_direction * sensitivity, friction * delta)
|
||||
#endregion
|
||||
|
||||
|
||||
#region Headbobbing
|
||||
func _perform_head_bob(delta: float) -> void:
|
||||
if not headbob_enabled:
|
||||
camera.position = Vector3.ZERO
|
||||
camera.rotation.z = 0.0
|
||||
headbob_target.position = Vector3.ZERO
|
||||
headbob_target.rotation.z = 0.0
|
||||
headbob_time = 0.0
|
||||
return
|
||||
|
||||
@ -172,7 +190,38 @@ func _perform_head_bob(delta: float) -> void:
|
||||
headbob_time += delta * headbob_speed * headbob_multiplier
|
||||
headbob_time = fposmod(headbob_time, TAU)
|
||||
|
||||
camera.position.y = sin(headbob_time * headbob_frequency) * headbob_range
|
||||
camera.position.x = cos(headbob_time * headbob_frequency / 2) * headbob_range
|
||||
camera.rotation.z = deg_to_rad(lerp(camera.position.x, camera.position.y, 0.5)) * TAU
|
||||
SPrint.print_msgf(str("Head Z-Rotation: ", camera.rotation.z), true)
|
||||
headbob_target.position.y = sin(headbob_time * headbob_frequency) * headbob_range
|
||||
headbob_target.position.x = cos(headbob_time * headbob_frequency / 2) * headbob_range
|
||||
headbob_target.rotation.z = deg_to_rad(lerp(headbob_target.position.x, headbob_target.position.y, 0.5)) * TAU
|
||||
SPrint.print_msgf(str("Head Z-Rotation: ", headbob_target.rotation.z), true)
|
||||
#endregion
|
||||
|
||||
|
||||
#region Step Smoothing
|
||||
func smooth_step(height_change: float) -> void:
|
||||
_stair_camera_target_height -= height_change
|
||||
_stair_camera_step_smoothing = true
|
||||
|
||||
|
||||
func _setup_step_smoothing() -> void:
|
||||
headbob_character.on_stair_step.connect(_on_stair_step)
|
||||
stair_camera_offset_height = step_smoothing_target.position.y
|
||||
|
||||
|
||||
func _on_stair_step() -> void:
|
||||
smooth_step(global_position.y - _previous_position.y)
|
||||
|
||||
|
||||
func _process_step_smoothing(delta: float) -> void:
|
||||
if _stair_camera_step_smoothing and is_instance_valid(step_smoothing_target):
|
||||
_stair_camera_target_height = lerp(_stair_camera_target_height, 0.0, step_speed * delta)
|
||||
|
||||
if absf(_stair_camera_target_height) < 0.0025:
|
||||
_stair_camera_target_height = 0.0
|
||||
_stair_camera_step_smoothing = false
|
||||
|
||||
var target_pos := Vector3.UP * (stair_camera_offset_height + _stair_camera_target_height)
|
||||
step_smoothing_target.position = target_pos.rotated(Vector3.LEFT, rotation.x)
|
||||
|
||||
_previous_position = global_position
|
||||
#endregion
|
||||
|
||||
@ -25,9 +25,10 @@ var has_control: bool = true
|
||||
var is_crouching: bool = false
|
||||
var crouch_speed_affection: float = 0.0
|
||||
|
||||
@onready var head: GameCamera3D = $Head
|
||||
@onready var collision_shape: CollisionShape3D = $CollisionShape3D
|
||||
@onready var head: PlayerHead = $Head
|
||||
@onready var collision_shape: CollisionShape3D = $CylinderCollider
|
||||
@onready var standup_checker: Area3D = $StandupChecker
|
||||
@onready var stair_stepper: StairStepper = $StairStepper
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@ -51,12 +52,15 @@ func _physics_process(delta: float) -> void:
|
||||
if not is_on_floor():
|
||||
apply_gravity(delta)
|
||||
elif not _was_on_floor:
|
||||
if _previous_velocity.y <= -2.0:
|
||||
if previous_velocity.y <= -2.0:
|
||||
head.camera.shake(0.025, 0.175)
|
||||
|
||||
if not has_control:
|
||||
move(Vector3.ZERO, delta)
|
||||
move_and_slide()
|
||||
move_and_stair_step()
|
||||
|
||||
#if is_on_floor():
|
||||
#stair_stepper.handle_step_climbing()
|
||||
return
|
||||
|
||||
# Handle jump.
|
||||
@ -78,8 +82,15 @@ func _physics_process(delta: float) -> void:
|
||||
speed *= remap(crouch_speed_affection, 0.0, 1.0, 1.0, standup_speed_affection)
|
||||
|
||||
move(movement_direction, delta)
|
||||
move_and_stair_step()
|
||||
|
||||
move_and_slide()
|
||||
SPrint.print_msgf(
|
||||
"Player Horizontal-Velocity: %s\nPlayer Vertical-Velocity: %s"
|
||||
% [(velocity * Utils.VEC3_HOR).length(), velocity.y], true
|
||||
)
|
||||
|
||||
#if is_on_floor():
|
||||
#stair_stepper.handle_step_climbing()
|
||||
|
||||
|
||||
func apply_gravity(delta: float) -> void:
|
||||
@ -119,4 +130,8 @@ func handle_crouching(delta: float) -> void:
|
||||
head.position.y = lerp(head.position.y, target_camera_height, weight)
|
||||
|
||||
crouch_speed_affection = lerp(crouch_speed_affection, float(is_crouching), weight * standup_speed_affection_speed_multiplier if not is_crouching else 1.0)
|
||||
SPrint.print_msgf("Crouching Speed Affection: %s\n%s" % [crouch_speed_affection, is_crouching], true)
|
||||
|
||||
if crouch_speed_affection <= 0.05:
|
||||
crouch_speed_affection = 0.0
|
||||
|
||||
SPrint.print_msgf("Crouching Speed Affection: %s\nIs Crouching: %s" % [crouch_speed_affection, is_crouching], true)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=9 format=3 uid="uid://clhy3kiceqf2o"]
|
||||
[gd_scene load_steps=10 format=3 uid="uid://clhy3kiceqf2o"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://day6rhxicaxqf" path="res://src/gameplay/characters/player/player_character.gd" id="1_hqu6r"]
|
||||
[ext_resource type="Script" uid="uid://dsjlv8midt2g2" path="res://src/gameplay/characters/character_movement.gd" id="2_1ixuj"]
|
||||
@ -13,14 +13,24 @@ max_turning_speed = 70.0
|
||||
peak_gravity_multiplier = 0.3
|
||||
metadata/_custom_type_script = "uid://dsjlv8midt2g2"
|
||||
|
||||
[sub_resource type="CylinderShape3D" id="CylinderShape3D_fjt7c"]
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_bdj5f"]
|
||||
margin = 0.01
|
||||
radius = 0.46
|
||||
height = 1.8
|
||||
|
||||
[sub_resource type="CylinderShape3D" id="CylinderShape3D_gy1j0"]
|
||||
height = 1.59
|
||||
radius = 0.49
|
||||
[sub_resource type="CylinderShape3D" id="CylinderShape3D_bdj5f"]
|
||||
margin = 0.01
|
||||
height = 1.8
|
||||
radius = 0.46
|
||||
|
||||
[node name="PlayerCharacter" type="CharacterBody3D"]
|
||||
[sub_resource type="CylinderShape3D" id="CylinderShape3D_ntkcp"]
|
||||
height = 1.59
|
||||
radius = 0.45
|
||||
|
||||
[node name="PlayerCharacter" type="StairsCharacter3D"]
|
||||
collider = NodePath("CylinderCollider")
|
||||
step_height_up = 0.7
|
||||
step_height_down = 0.7
|
||||
collision_layer = 2
|
||||
script = ExtResource("1_hqu6r")
|
||||
standup_speed_affection = 0.15
|
||||
@ -28,30 +38,43 @@ standup_speed_affection_speed_multiplier = 0.5
|
||||
movement = SubResource("Resource_vq0uu")
|
||||
metadata/_custom_type_script = "uid://day6rhxicaxqf"
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
[node name="CapsuleCollider" type="CollisionShape3D" parent="."]
|
||||
process_mode = 4
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0)
|
||||
shape = SubResource("CylinderShape3D_fjt7c")
|
||||
visible = false
|
||||
shape = SubResource("CapsuleShape3D_bdj5f")
|
||||
disabled = true
|
||||
|
||||
[node name="Head" type="Node3D" parent="." node_paths=PackedStringArray("camera", "headbob_character")]
|
||||
[node name="CylinderCollider" type="CollisionShape3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0)
|
||||
shape = SubResource("CylinderShape3D_bdj5f")
|
||||
|
||||
[node name="Head" type="Node3D" parent="." node_paths=PackedStringArray("camera", "headbob_character", "headbob_target", "step_smoothing_target")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
|
||||
script = ExtResource("2_fjt7c")
|
||||
camera = NodePath("ShakingCamera")
|
||||
camera = NodePath("Headbobbing/StairStepping/ShakingCamera")
|
||||
headbob_range = 0.05
|
||||
headbob_frequency = 2.0
|
||||
headbob_character = NodePath("..")
|
||||
headbob_target = NodePath("Headbobbing")
|
||||
step_smoothing_target = NodePath("Headbobbing/StairStepping")
|
||||
|
||||
[node name="ShakingCamera" type="Camera3D" parent="Head"]
|
||||
[node name="Headbobbing" type="Node3D" parent="Head"]
|
||||
|
||||
[node name="StairStepping" type="Node3D" parent="Head/Headbobbing"]
|
||||
|
||||
[node name="ShakingCamera" type="Camera3D" parent="Head/Headbobbing/StairStepping"]
|
||||
current = true
|
||||
fov = 85.0
|
||||
script = ExtResource("4_ci1ud")
|
||||
metadata/_custom_type_script = "uid://44s0v8mukxk4"
|
||||
|
||||
[node name="FootstepComponent" type="Node" parent="." node_paths=PackedStringArray("character")]
|
||||
script = ExtResource("4_vq0uu")
|
||||
character = NodePath("..")
|
||||
|
||||
[node name="StandupChecker" type="Area3D" parent="."]
|
||||
input_ray_pickable = false
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="StandupChecker"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.99, 0)
|
||||
shape = SubResource("CylinderShape3D_gy1j0")
|
||||
shape = SubResource("CylinderShape3D_ntkcp")
|
||||
|
||||
[node name="FootstepComponent" type="Node" parent="."]
|
||||
script = ExtResource("4_vq0uu")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user