Camera centering improvements

This commit is contained in:
2026-06-11 22:27:41 -05:00
parent e9bd74ddaa
commit d85007d284
+17 -13
View File
@@ -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)