class_name EntityMovement extends Node const GRAVITY = Vector3.DOWN * 100 const FRICTION = 0.01 const SPEED_DEFAULT = 8 const ROTATION_SPEED_DEFAULT = 15.0 @export var entity:Entity @export var interactingArea:EntityInteractingArea @export var speed:float = SPEED_DEFAULT @export var rotationSpeed:float = ROTATION_SPEED_DEFAULT # # Private Methods # func _applyGravity() -> void: if !entity.is_on_floor(): entity.velocity += GRAVITY * get_process_delta_time() func _applyPlayerMovement(delta:float): # Interactions, may move if Input.is_action_just_pressed("interact") && interactingArea && interactingArea.hasInteraction(): if !UI.hasAdvanceableChatBox() && !UI.dialogueActive: interactingArea.interact() return # Directional input var inputDir:Vector2 = Input.get_vector("move_left", "move_right", "move_back", "move_forward").normalized() var cameraCurrent = get_viewport().get_camera_3d() if !cameraCurrent: return # Use camera orientation for movement direction var camBasis = cameraCurrent.global_transform.basis # Forward and right vectors, ignore vertical component var forward = -camBasis.z forward.y = 0 forward = forward.normalized() var right = camBasis.x right.y = 0 right = right.normalized() var directionAdjusted = (forward * inputDir.y + right * inputDir.x).normalized() if directionAdjusted.length() <= 0.01: return var targetYaw:float = atan2(-directionAdjusted.x, -directionAdjusted.z) entity.rotation.y = lerp_angle(entity.rotation.y, targetYaw, rotationSpeed * delta) entity.velocity.x = directionAdjusted.x * speed entity.velocity.z = directionAdjusted.z * speed func _applyMovement(delta:float) -> void: if !_canMove(): return if entity.movementType == Entity.MovementType.PLAYER: _applyPlayerMovement(delta) func _applyFriction(delta:float) -> void: entity.velocity.x *= delta * FRICTION entity.velocity.z *= delta * FRICTION func _canMove() -> bool: if !UI.MAIN_CHATBOX.isClosed: return false if UI.GAME_MENU && UI.GAME_MENU.isOpen(): return false return true # # Callbacks # func _enter_tree() -> void: pass func _physics_process(delta:float) -> void: # Entity required to move if !entity || entity.movementType == Entity.MovementType.DISABLED || !entity.visible: return _applyGravity() _applyFriction(delta) _applyMovement(delta) entity.move_and_slide()