Feat/1 movement foundation #5
@@ -1,78 +1,56 @@
|
|||||||
extends CharacterBody3D
|
extends CharacterBody3D
|
||||||
class_name PlayerMovementController
|
class_name PlayerMovementController
|
||||||
|
|
||||||
## PlayerMovementController — root node for all player 3D locomotion.
|
|
||||||
## Attach to a CharacterBody3D with a CollisionShape3D.
|
|
||||||
## States are expected to be children: state_ground, state_air,
|
|
||||||
## state_wall_run, state_wall_cling, state_slide, state_dash.
|
|
||||||
|
|
||||||
signal chain_updated(count: int, bonus: float)
|
signal chain_updated(count: int, bonus: float)
|
||||||
|
|
||||||
@export var params: MovementParams = preload("res://movement/movement_params.gd").new()
|
@export var params: MovementParams = preload("res://movement/movement_params.gd").new()
|
||||||
|
|
||||||
var machine: MovementStateMachine
|
|
||||||
var jump_buffered: bool = false
|
|
||||||
var _ready_ran: bool = false
|
|
||||||
var _machine: MovementStateMachine = null
|
var _machine: MovementStateMachine = null
|
||||||
|
|
||||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
|
||||||
func _ensure_machine() -> MovementStateMachine:
|
func _ensure_machine() -> MovementStateMachine:
|
||||||
if typeof(_machine) != TYPE_NIL and is_instance_valid(_machine):
|
if is_instance_valid(_machine):
|
||||||
return _machine as MovementStateMachine
|
|
||||||
var candidates := [
|
|
||||||
get_node("MovementStateMachine") if has_node("MovementStateMachine") else null,
|
|
||||||
_machine if is_instance_valid(_machine) and _machine.has_method("register_chain_mechanic") else null,
|
|
||||||
]
|
|
||||||
for c in candidates:
|
|
||||||
if c and (c is MovementStateMachine or (c.has_method("switch_to") and c.has_method("register_chain_mechanic"))):
|
|
||||||
_machine = c
|
|
||||||
return _machine
|
return _machine
|
||||||
|
if has_node("MovementStateMachine"):
|
||||||
|
_machine = $MovementStateMachine
|
||||||
|
if _machine is MovementStateMachine:
|
||||||
|
return _machine
|
||||||
|
_machine = null
|
||||||
return null
|
return null
|
||||||
|
|
||||||
# ── Input references ─────────────────────────────────────────────────────────
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
func _unhandled_input(event: InputEvent) -> void:
|
||||||
if event.is_action_pressed("ui_accept"):
|
var sm := _ensure_machine()
|
||||||
# Space / jump
|
if not sm:
|
||||||
pass
|
|
||||||
var node := _ensure_machine()
|
|
||||||
if not node:
|
|
||||||
return
|
return
|
||||||
node.input_jump_just_pressed = Input.is_action_just_pressed("jump")
|
sm.input_jump_just_pressed = Input.is_action_just_pressed("jump")
|
||||||
node.input_jump_pressed = Input.is_action_pressed("jump")
|
sm.input_jump_pressed = Input.is_action_pressed("jump")
|
||||||
node.input_sprint = Input.is_action_pressed("sprint")
|
sm.input_sprint = Input.is_action_pressed("sprint")
|
||||||
node.input_crouch = Input.is_action_pressed("crouch")
|
sm.input_crouch = Input.is_action_pressed("crouch")
|
||||||
node.input_dash = Input.is_action_just_pressed("dash")
|
sm.input_dash = Input.is_action_just_pressed("dash")
|
||||||
var input_v := Input.get_vector("move_left", "move_right", "move_forward", "move_back")
|
sm.input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
|
||||||
node.input_dir = input_v
|
|
||||||
|
|
||||||
|
|
||||||
@onready var _machine = get_node("MovementStateMachine")
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
if _ready_ran:
|
var sm := _ensure_machine()
|
||||||
return
|
if sm:
|
||||||
_ready_ran = true
|
|
||||||
var node := _ensure_machine()
|
|
||||||
if node:
|
|
||||||
var sm := node
|
|
||||||
sm.player = self
|
sm.player = self
|
||||||
sm.params = params
|
sm.params = params
|
||||||
# Mirror signal up
|
sm.movement_event.connect(_on_movement_event)
|
||||||
sm.movement_event.connect(func(ev, data):
|
|
||||||
if ev == "chain_updated":
|
|
||||||
chain_updated.emit(data.count, data.bonus)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
var node := _ensure_machine()
|
var sm := _ensure_machine()
|
||||||
if not node:
|
if not sm:
|
||||||
return
|
return
|
||||||
# Keep one consistent source of truth for inputs
|
sm.input_jump_just_pressed = Input.is_action_just_pressed("jump") and not sm.input_jump_pressed
|
||||||
node.input_jump_just_pressed = Input.is_action_just_pressed("jump") and not node.input_jump_pressed
|
sm.input_jump_pressed = Input.is_action_pressed("jump")
|
||||||
node.input_jump_pressed = Input.is_action_pressed("jump")
|
sm.input_sprint = Input.is_action_pressed("sprint")
|
||||||
node.input_sprint = Input.is_action_pressed("sprint")
|
sm.input_crouch = Input.is_action_pressed("crouch")
|
||||||
node.input_crouch = Input.is_action_pressed("crouch")
|
sm.input_dash = Input.is_action_just_pressed("dash") and not sm.input_dash
|
||||||
node.input_dash = Input.is_action_just_pressed("dash") and not node.input_dash
|
sm.input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
|
||||||
node.input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
|
|
||||||
|
|
||||||
|
func _on_movement_event(ev: String, data: Dictionary) -> void:
|
||||||
|
if ev == "chain_updated":
|
||||||
|
chain_updated.emit(data.count, data.bonus)
|
||||||
|
|||||||
Reference in New Issue
Block a user