From d85007d284fd3cfe5a44c84cd7c39053647b7985 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Thu, 11 Jun 2026 22:27:41 -0500 Subject: [PATCH] Camera centering improvements --- overworld/camera/OverworldCamera.gd | 30 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/overworld/camera/OverworldCamera.gd b/overworld/camera/OverworldCamera.gd index 6a51bc3..f125d1d 100644 --- a/overworld/camera/OverworldCamera.gd +++ b/overworld/camera/OverworldCamera.gd @@ -25,8 +25,9 @@ const COLLISION_MARGIN:float = 0 @export var centeredDelay:float = 1.0 @export var centeredFollowRate:float = 0.75 @export var centeredMaxFollowRate:float = 1.5 -@export var centeredPitch:float = 30.0 +@export var centeredAcceleration:float = 360.0 @export var centeredMaxYawDiff:float = 120.0 +@export var centeredPitch:float = 30.0 @export_category("Collision") @export_flags_3d_physics var collisionMask:int = 1 @@ -35,6 +36,7 @@ var _mode:CameraMode = CameraMode.CENTERED var _yaw:float = 0.0 var _pitch:float = 30.0 var _camVelocity:Vector2 = Vector2.ZERO +var _centerVelocity:float = 0.0 var _freeTimer:float = 0.0 var _mouseDelta:Vector2 = Vector2.ZERO var _rightMouseHeld:bool = false @@ -97,24 +99,26 @@ func _process(delta:float) -> void: else: _freeTimer = 0.0 - # In CENTERED mode, smoothly slerp toward behind the player while they move; - # rate scales up with angular distance so large offsets catch up quickly. + # In CENTERED mode, accelerate a yaw velocity toward behind the player (using + # actual movement velocity for direction) then friction-decay when idle — + # mirrors how controller input works so there's no sudden stop. if _mode == CameraMode.CENTERED: var centerBody := targetNode as CharacterBody3D - if centerBody != null and centerBody.velocity.length_squared() > 0.1: - var behindYaw:float = rad_to_deg(atan2( - targetNode.global_transform.basis.z.x, - targetNode.global_transform.basis.z.z - )) - + var vel3d:Vector3 = Vector3.ZERO if centerBody == null else centerBody.velocity + if vel3d.length_squared() > 0.1: + var behindYaw:float = rad_to_deg(atan2(-vel3d.x, -vel3d.z)) var centerYawDiff:float = fposmod(behindYaw - _yaw + 180.0, 360.0) - 180.0 + var totalAngle:float = abs(centerYawDiff) + abs(centeredPitch - _pitch) + var dynamicRate:float = minf(centeredFollowRate * (1.0 + totalAngle / 90.0), centeredMaxFollowRate) if abs(centerYawDiff) <= centeredMaxYawDiff: - var totalAngle:float = abs(centerYawDiff) + abs(centeredPitch - _pitch) - var dynamicRate:float = minf(centeredFollowRate * (1.0 + totalAngle / 90.0), centeredMaxFollowRate) - var tYaw:float = minf(dynamicRate * delta, 1.0) + _centerVelocity = move_toward(_centerVelocity, centerYawDiff * dynamicRate, centeredAcceleration * delta) var tPitch:float = minf(dynamicRate * 3.0 * delta, 1.0) _pitch = lerpf(_pitch, centeredPitch, tPitch) - _yaw += centerYawDiff * tYaw + else: + _centerVelocity = lerpf(_centerVelocity, 0.0, minf(orbitFriction * delta, 1.0)) + else: + _centerVelocity = lerpf(_centerVelocity, 0.0, minf(orbitFriction * delta, 1.0)) + _yaw += _centerVelocity * delta _pitch = clamp(_pitch, pitchMin, pitchMax)