gmp(M02): extract local player movement
Work-Package: M02-GMP-MOVEMENT-001 Agent: sindo-main-codex Tests: local movement and player input regressions; asset-free scene; renderer dry-run; coordinate, streaming, documentation and coordination gates Fidelity: preserves current sandbox speed, acceleration, sprint and camera-relative flight behavior; build-12340 parity remains unverified
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
class_name LocalPlayerMovementController
|
||||
extends RefCounted
|
||||
|
||||
## Scene-free state and velocity integrator for the current local sandbox player.
|
||||
## Direction inputs use a Godot-world movement basis selected by the scene
|
||||
## adapter. This class does not discover Nodes, query terrain or mutate transforms.
|
||||
|
||||
var godot_world_velocity_units_per_second: Vector3:
|
||||
get:
|
||||
return _godot_world_velocity_units_per_second
|
||||
|
||||
var is_flight_enabled: bool:
|
||||
get:
|
||||
return _is_flight_enabled
|
||||
|
||||
var _run_speed_units_per_second: float
|
||||
var _backward_speed_units_per_second: float
|
||||
var _strafe_speed_units_per_second: float
|
||||
var _flight_vertical_speed_units_per_second: float
|
||||
var _acceleration_units_per_second_squared: float
|
||||
var _sandbox_sprint_multiplier: float
|
||||
var _godot_world_velocity_units_per_second := Vector3.ZERO
|
||||
var _is_flight_enabled := false
|
||||
|
||||
|
||||
## Creates a movement state with explicit Godot-unit speeds and acceleration.
|
||||
## The current compatibility renderer treats one Godot unit as one WoW yard.
|
||||
func _init(
|
||||
run_speed_units_per_second: float,
|
||||
backward_speed_units_per_second: float,
|
||||
strafe_speed_units_per_second: float,
|
||||
flight_vertical_speed_units_per_second: float,
|
||||
acceleration_units_per_second_squared: float,
|
||||
sandbox_sprint_multiplier: float
|
||||
) -> void:
|
||||
_run_speed_units_per_second = run_speed_units_per_second
|
||||
_backward_speed_units_per_second = backward_speed_units_per_second
|
||||
_strafe_speed_units_per_second = strafe_speed_units_per_second
|
||||
_flight_vertical_speed_units_per_second = flight_vertical_speed_units_per_second
|
||||
_acceleration_units_per_second_squared = acceleration_units_per_second_squared
|
||||
_sandbox_sprint_multiplier = sandbox_sprint_multiplier
|
||||
|
||||
|
||||
## Toggles sandbox free flight and clears velocity exactly like the pre-M02 controller.
|
||||
## Returns the new flight state.
|
||||
func toggle_sandbox_flight() -> bool:
|
||||
_is_flight_enabled = not _is_flight_enabled
|
||||
_godot_world_velocity_units_per_second = Vector3.ZERO
|
||||
return _is_flight_enabled
|
||||
|
||||
|
||||
## Advances velocity by one physics step and returns local-world displacement.
|
||||
## `godot_world_movement_basis` is the player basis on ground and camera-pivot basis in flight.
|
||||
## Negative delta values are treated as zero and do not mutate velocity.
|
||||
func advance(
|
||||
move_intent: MoveIntent,
|
||||
godot_world_movement_basis: Basis,
|
||||
delta_seconds: float
|
||||
) -> Vector3:
|
||||
var safe_delta_seconds := maxf(delta_seconds, 0.0)
|
||||
if is_zero_approx(safe_delta_seconds):
|
||||
return Vector3.ZERO
|
||||
|
||||
var target_velocity := _calculate_target_velocity(move_intent, godot_world_movement_basis)
|
||||
_godot_world_velocity_units_per_second = _godot_world_velocity_units_per_second.move_toward(
|
||||
target_velocity,
|
||||
_acceleration_units_per_second_squared * safe_delta_seconds
|
||||
)
|
||||
return _godot_world_velocity_units_per_second * safe_delta_seconds
|
||||
|
||||
|
||||
func _calculate_target_velocity(move_intent: MoveIntent, godot_world_movement_basis: Basis) -> Vector3:
|
||||
var forward_direction := -godot_world_movement_basis.z
|
||||
var right_direction := godot_world_movement_basis.x
|
||||
if not _is_flight_enabled:
|
||||
forward_direction.y = 0.0
|
||||
right_direction.y = 0.0
|
||||
forward_direction = forward_direction.normalized()
|
||||
right_direction = right_direction.normalized()
|
||||
|
||||
var forward_speed := (
|
||||
_run_speed_units_per_second
|
||||
if move_intent.forward_axis > 0.0
|
||||
else _backward_speed_units_per_second
|
||||
)
|
||||
var speed_multiplier := _sandbox_sprint_multiplier if move_intent.is_sprint_requested else 1.0
|
||||
var target_velocity := (
|
||||
forward_direction * move_intent.forward_axis * forward_speed
|
||||
+ right_direction * move_intent.strafe_axis * _strafe_speed_units_per_second
|
||||
) * speed_multiplier
|
||||
if _is_flight_enabled:
|
||||
target_velocity.y += (
|
||||
move_intent.vertical_axis
|
||||
* _flight_vertical_speed_units_per_second
|
||||
* speed_multiplier
|
||||
)
|
||||
return target_velocity
|
||||
@@ -0,0 +1 @@
|
||||
uid://dxlx5kloh7p5c
|
||||
Reference in New Issue
Block a user