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:
@@ -9,6 +9,7 @@ const ADT_TILE_COORDINATE_SCRIPT := preload("res://src/domain/coordinates/adt_ti
|
||||
const ADT_TILE_LOCAL_POSITION_SCRIPT := preload("res://src/domain/coordinates/adt_tile_local_position.gd")
|
||||
const PLAYER_INPUT_SOURCE_SCRIPT := preload("res://src/gameplay/input/player_input_source.gd")
|
||||
const PLAYER_INPUT_ACTIONS_SCRIPT := preload("res://src/gameplay/input/player_input_actions.gd")
|
||||
const LOCAL_PLAYER_MOVEMENT_CONTROLLER_SCRIPT := preload("res://src/gameplay/movement/local_player_movement_controller.gd")
|
||||
|
||||
const CHUNK_SIZE := COORDINATE_MAPPER_SCRIPT.ADT_CHUNK_SIZE_YARDS
|
||||
const UNIT_SIZE := CHUNK_SIZE / 8.0
|
||||
@@ -54,14 +55,21 @@ var _active_animation := ""
|
||||
var _captured := false
|
||||
var _yaw := 0.0
|
||||
var _pitch := deg_to_rad(-18.0)
|
||||
var _horizontal_velocity := Vector3.ZERO
|
||||
var _flight_enabled := false
|
||||
var _adt_cache: Dictionary = {}
|
||||
var _player_input_source: PlayerInputSource
|
||||
var _local_movement_controller: LocalPlayerMovementController
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_player_input_source = PLAYER_INPUT_SOURCE_SCRIPT.new()
|
||||
_local_movement_controller = LOCAL_PLAYER_MOVEMENT_CONTROLLER_SCRIPT.new(
|
||||
run_speed,
|
||||
backward_speed,
|
||||
strafe_speed,
|
||||
flight_vertical_speed,
|
||||
acceleration,
|
||||
sprint_multiplier
|
||||
)
|
||||
_camera_pivot = get_node_or_null(camera_pivot_path) as Node3D
|
||||
_camera = get_node_or_null(camera_path) as Camera3D
|
||||
_visual = get_node_or_null(visual_path) as Node3D
|
||||
@@ -99,8 +107,7 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||
_captured = false
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED if _captured else Input.MOUSE_MODE_VISIBLE
|
||||
elif event.is_action_pressed(PLAYER_INPUT_ACTIONS_SCRIPT.DEBUG_TOGGLE_FLIGHT) and not event.is_echo():
|
||||
_flight_enabled = not _flight_enabled
|
||||
_horizontal_velocity = Vector3.ZERO
|
||||
_local_movement_controller.toggle_sandbox_flight()
|
||||
|
||||
if _captured and event is InputEventMouseMotion:
|
||||
_yaw -= event.relative.x * mouse_sensitivity
|
||||
@@ -111,54 +118,26 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var move_intent := _player_input_source.sample_move_intent()
|
||||
var target_velocity := Vector3.ZERO
|
||||
if move_intent.has_translation():
|
||||
target_velocity = _movement_vector(move_intent)
|
||||
if _flight_enabled:
|
||||
target_velocity.y += move_intent.vertical_axis * flight_vertical_speed * _debug_speed_multiplier(move_intent)
|
||||
var godot_world_movement_basis := global_basis
|
||||
if _local_movement_controller.is_flight_enabled and _camera_pivot:
|
||||
godot_world_movement_basis = _camera_pivot.global_basis
|
||||
global_position += _local_movement_controller.advance(move_intent, godot_world_movement_basis, delta)
|
||||
|
||||
_horizontal_velocity = _horizontal_velocity.move_toward(target_velocity, acceleration * delta)
|
||||
global_position += _horizontal_velocity * delta
|
||||
|
||||
if not _flight_enabled:
|
||||
if not _local_movement_controller.is_flight_enabled:
|
||||
var ground := _sample_ground_height(global_position)
|
||||
if is_finite(ground):
|
||||
var target_y := ground + ground_offset
|
||||
global_position.y = lerpf(global_position.y, target_y, clampf(ground_snap_speed * delta, 0.0, 1.0))
|
||||
|
||||
var horizontal_motion := Vector2(_horizontal_velocity.x, _horizontal_velocity.z)
|
||||
var movement_velocity := _local_movement_controller.godot_world_velocity_units_per_second
|
||||
var horizontal_motion := Vector2(movement_velocity.x, movement_velocity.z)
|
||||
if _visual and horizontal_motion.length_squared() > 0.01:
|
||||
_visual.global_rotation.y = atan2(-_horizontal_velocity.x, -_horizontal_velocity.z)
|
||||
_visual.global_rotation.y = atan2(-movement_velocity.x, -movement_velocity.z)
|
||||
|
||||
_update_character_animation(horizontal_motion.length_squared() > 0.04)
|
||||
|
||||
_apply_camera_transform()
|
||||
|
||||
|
||||
func _movement_vector(move_intent: MoveIntent) -> Vector3:
|
||||
var forward := -global_basis.z
|
||||
var right := global_basis.x
|
||||
if _flight_enabled and _camera_pivot:
|
||||
forward = -_camera_pivot.global_basis.z
|
||||
right = _camera_pivot.global_basis.x
|
||||
else:
|
||||
forward.y = 0.0
|
||||
right.y = 0.0
|
||||
forward = forward.normalized()
|
||||
right = right.normalized()
|
||||
|
||||
var speed_z := run_speed if move_intent.forward_axis > 0.0 else backward_speed
|
||||
var speed_x := strafe_speed
|
||||
return (
|
||||
forward * move_intent.forward_axis * speed_z
|
||||
+ right * move_intent.strafe_axis * speed_x
|
||||
) * _debug_speed_multiplier(move_intent)
|
||||
|
||||
|
||||
func _debug_speed_multiplier(move_intent: MoveIntent) -> float:
|
||||
return sprint_multiplier if move_intent.is_sprint_requested else 1.0
|
||||
|
||||
|
||||
func _load_character_visual() -> void:
|
||||
if character_model_path.is_empty() or _visual == null:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user