Files
Dawn-Godot/overworld/entity/EntityMovement.gd
T
2026-06-12 09:08:13 -05:00

89 lines
2.4 KiB
GDScript

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():
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.dialogueActive:
return false
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()