feat: implement player movement controller with grounded state, stair stepping, and wall interaction mechanics
This commit is contained in:
@@ -14,6 +14,7 @@ var _target_tilt: float = 0.0
|
|||||||
var _current_tilt: float = 0.0
|
var _current_tilt: float = 0.0
|
||||||
var _target_fov: float = 90.0
|
var _target_fov: float = 90.0
|
||||||
var _weapon_fov_override: float = -1.0
|
var _weapon_fov_override: float = -1.0
|
||||||
|
var _step_offset_y: float = 0.0
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
@@ -80,6 +81,10 @@ func _process(delta: float) -> void:
|
|||||||
camera.position.y = lerp(camera.position.y, 0.0, 0.15)
|
camera.position.y = lerp(camera.position.y, 0.0, 0.15)
|
||||||
camera.position.x = lerp(camera.position.x, 0.0, 0.15)
|
camera.position.x = lerp(camera.position.x, 0.0, 0.15)
|
||||||
|
|
||||||
|
# ── Step Smoothing ─────────────────────────────────────────────────────
|
||||||
|
_step_offset_y = lerpf(_step_offset_y, 0.0, 15.0 * delta)
|
||||||
|
camera.position.y += _step_offset_y
|
||||||
|
|
||||||
# ── Wall-run tilt ─────────────────────────────────────────────────────
|
# ── Wall-run tilt ─────────────────────────────────────────────────────
|
||||||
_current_tilt = lerpf(_current_tilt, _target_tilt, 1.0 - exp(-params.wall_run_tilt_speed * delta))
|
_current_tilt = lerpf(_current_tilt, _target_tilt, 1.0 - exp(-params.wall_run_tilt_speed * delta))
|
||||||
camera.rotation.z = deg_to_rad(_current_tilt)
|
camera.rotation.z = deg_to_rad(_current_tilt)
|
||||||
@@ -99,3 +104,9 @@ func set_weapon_fov(fov: float) -> void:
|
|||||||
## Called to reset tilt (e.g., on landing).
|
## Called to reset tilt (e.g., on landing).
|
||||||
func clear_wall_tilt() -> void:
|
func clear_wall_tilt() -> void:
|
||||||
_target_tilt = 0.0
|
_target_tilt = 0.0
|
||||||
|
|
||||||
|
## Adds an offset to the camera so that when the player physics body snaps up a step,
|
||||||
|
## the camera interpolates smoothly instead of snapping.
|
||||||
|
func add_step_offset(offset_y: float) -> void:
|
||||||
|
_step_offset_y += offset_y
|
||||||
|
|
||||||
|
|||||||
@@ -47,12 +47,12 @@ class_name MovementParams
|
|||||||
@export var wall_angle_threshold: float = 70.0
|
@export var wall_angle_threshold: float = 70.0
|
||||||
@export var wall_detect_distance: float = 0.7
|
@export var wall_detect_distance: float = 0.7
|
||||||
@export var wall_ray_up_height: float = 0.6
|
@export var wall_ray_up_height: float = 0.6
|
||||||
@export var wall_ray_down_height: float = -0.3
|
@export var wall_ray_down_height: float = 0.0
|
||||||
|
|
||||||
# ── Wall Climb ────────────────────────────────────────────────────────────────
|
# ── Wall Climb ────────────────────────────────────────────────────────────────
|
||||||
@export var wall_climb_speed: float = 6.0
|
@export var wall_climb_speed: float = 6.0
|
||||||
@export var wall_climb_duration: float = 3.0
|
@export var wall_climb_duration: float = 3.0
|
||||||
@export var wall_climb_max_angle: float = 55.0
|
@export var wall_climb_max_angle: float = 75.0
|
||||||
@export var wall_climb_vault_forward: float = 16.0
|
@export var wall_climb_vault_forward: float = 16.0
|
||||||
@export var wall_climb_vault_up: float = 14.0
|
@export var wall_climb_vault_up: float = 14.0
|
||||||
@export var wall_climb_vault_height_check: float = 1.0
|
@export var wall_climb_vault_height_check: float = 1.0
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ func update(delta: float) -> void:
|
|||||||
return
|
return
|
||||||
|
|
||||||
# ── Wall interaction (Run, Climb, Vault) ──────────────────────────────
|
# ── Wall interaction (Run, Climb, Vault) ──────────────────────────────
|
||||||
if machine.input_dir.length() > 0.1 and machine.wall_cooldown_timer <= 0.0:
|
if machine.input_dir.length() > 0.1 and machine.input_dir.y <= 0.0 and machine.wall_cooldown_timer <= 0.0:
|
||||||
var fwd_wall = machine.detect_wall_forward()
|
var fwd_wall = machine.detect_wall_forward()
|
||||||
if fwd_wall.hit:
|
if fwd_wall.hit:
|
||||||
if fwd_wall.is_short:
|
if fwd_wall.is_short:
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ func update(delta: float) -> void:
|
|||||||
if space_state.intersect_ray(head_ray).is_empty():
|
if space_state.intersect_ray(head_ray).is_empty():
|
||||||
# We can safely step up
|
# We can safely step up
|
||||||
player.global_position.y += step_height + 0.01
|
player.global_position.y += step_height + 0.01
|
||||||
|
if player.head_pivot and player.head_pivot.has_method("add_step_offset"):
|
||||||
|
player.head_pivot.add_step_offset(-(step_height + 0.01))
|
||||||
# Push slightly forward to get onto the step
|
# Push slightly forward to get onto the step
|
||||||
player.global_position += fwd * 0.1
|
player.global_position += fwd * 0.1
|
||||||
# Restore horizontal velocity that was lost from hitting the wall
|
# Restore horizontal velocity that was lost from hitting the wall
|
||||||
@@ -156,7 +158,7 @@ func update(delta: float) -> void:
|
|||||||
return
|
return
|
||||||
|
|
||||||
# ── Wall interaction (Run, Climb, Vault) ──────────────────────────────
|
# ── Wall interaction (Run, Climb, Vault) ──────────────────────────────
|
||||||
if machine.input_dir.length() > 0.1 and machine.wall_cooldown_timer <= 0.0 and not machine.input_crouch:
|
if machine.input_dir.length() > 0.1 and machine.input_dir.y <= 0.0 and machine.wall_cooldown_timer <= 0.0 and not machine.input_crouch:
|
||||||
var fwd_wall = machine.detect_wall_forward()
|
var fwd_wall = machine.detect_wall_forward()
|
||||||
if fwd_wall.hit:
|
if fwd_wall.hit:
|
||||||
if fwd_wall.is_short:
|
if fwd_wall.is_short:
|
||||||
|
|||||||
Reference in New Issue
Block a user