Smooth free-camera flight and look
FreeCamController: ease movement via dt-correct Vector3.SmoothDamp on a world-space velocity (accel/decel ramp) and lag the look with Mathf.SmoothDampAngle. Both are framerate-independent and collapse to instant at smoothTime 0; smoothed state is snapped on activation (SyncToCurrentView) so entering freecam never jumps to catch up. Bundles accumulated deferred work: PlayerScaler uniform-scale helper, scale-aware wall/ceiling climb probes and the double-scale skinned-collider bake fix, plus user content authoring (Sit pose + animation, font SDF, scene/prefab edits). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
f66ebbf10a
commit
8c89e95014
14 files changed
+12083
-360
No files matched your search
@@ -39,6 +39,15 @@ public class FreeCamController : MonoBehaviour
|
||||
[Range(1f, 89.9f)]
|
||||
public float maxPitch = 89f;
|
||||
|
||||
[Header("Smoothing")]
|
||||
[Tooltip("Acceleration/deceleration smoothing for flight, in seconds. 0 = instant (snappy starts/stops); higher = floatier ramp-up and coast-down.")]
|
||||
[Range(0f, 1f)]
|
||||
public float moveSmoothTime = 0.12f;
|
||||
|
||||
[Tooltip("Look smoothing, in seconds. 0 = raw mouse (instant); small values take the edge off jitter without feeling laggy.")]
|
||||
[Range(0f, 0.3f)]
|
||||
public float lookSmoothTime = 0.04f;
|
||||
|
||||
[Header("Camera")]
|
||||
[Tooltip("Priority the dedicated CinemachineCamera takes while active (must beat the gameplay camera).")]
|
||||
public int activePriority = 100;
|
||||
@@ -48,8 +57,14 @@ public class FreeCamController : MonoBehaviour
|
||||
|
||||
CharacterController _controller;
|
||||
CinemachineCamera _vcam;
|
||||
float _yaw;
|
||||
float _yaw; // look target (raw input accumulates here)
|
||||
float _pitch;
|
||||
float _displayYaw; // smoothed value actually applied to the transform
|
||||
float _displayPitch;
|
||||
float _yawSmoothRef;
|
||||
float _pitchSmoothRef;
|
||||
Vector3 _moveVelocity; // smoothed world-space flight velocity
|
||||
Vector3 _moveVelocityRef;
|
||||
bool _ignoredPlayer;
|
||||
|
||||
void Awake()
|
||||
@@ -98,8 +113,21 @@ public class FreeCamController : MonoBehaviour
|
||||
_yaw += delta.x * horizontalSensitivity;
|
||||
float vs = verticalSensitivity * (invertY ? 1f : -1f);
|
||||
_pitch = Mathf.Clamp(_pitch + delta.y * vs, -maxPitch, maxPitch);
|
||||
|
||||
if (lookSmoothTime > 0f)
|
||||
{
|
||||
// SmoothDampAngle is frame-rate-independent and wraps yaw correctly.
|
||||
_displayYaw = Mathf.SmoothDampAngle(_displayYaw, _yaw, ref _yawSmoothRef, lookSmoothTime);
|
||||
_displayPitch = Mathf.SmoothDampAngle(_displayPitch, _pitch, ref _pitchSmoothRef, lookSmoothTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
_displayYaw = _yaw;
|
||||
_displayPitch = _pitch;
|
||||
}
|
||||
|
||||
// Rotation is unconstrained by the CharacterController; only position is.
|
||||
transform.rotation = Quaternion.Euler(_pitch, _yaw, 0f);
|
||||
transform.rotation = Quaternion.Euler(_displayPitch, _displayYaw, 0f);
|
||||
}
|
||||
|
||||
void MoveTick()
|
||||
@@ -109,7 +137,14 @@ public class FreeCamController : MonoBehaviour
|
||||
dir.Normalize();
|
||||
|
||||
float speed = moveSpeed * (SprintHeld() ? sprintMultiplier : 1f);
|
||||
_controller.Move(dir * (speed * Time.deltaTime));
|
||||
Vector3 targetVelocity = dir * speed;
|
||||
|
||||
// SmoothDamp eases accel/decel and is already dt-correct; 0 collapses to instant.
|
||||
_moveVelocity = moveSmoothTime > 0f
|
||||
? Vector3.SmoothDamp(_moveVelocity, targetVelocity, ref _moveVelocityRef, moveSmoothTime)
|
||||
: targetVelocity;
|
||||
|
||||
_controller.Move(_moveVelocity * Time.deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>Place the rig at the currently rendered view so going live produces no visible jump.</summary>
|
||||
@@ -128,6 +163,14 @@ public class FreeCamController : MonoBehaviour
|
||||
_yaw = e.y;
|
||||
float p = e.x > 180f ? e.x - 360f : e.x;
|
||||
_pitch = Mathf.Clamp(p, -maxPitch, maxPitch);
|
||||
|
||||
// Snap the smoothed state to the fresh pose so entering freecam never lags/jumps to catch up.
|
||||
_displayYaw = _yaw;
|
||||
_displayPitch = _pitch;
|
||||
_yawSmoothRef = 0f;
|
||||
_pitchSmoothRef = 0f;
|
||||
_moveVelocity = Vector3.zero;
|
||||
_moveVelocityRef = Vector3.zero;
|
||||
}
|
||||
|
||||
/// <summary>Stop the freecam capsule from being blocked by the (frozen) player's capsule.</summary>
|
||||
|
||||
Reference in new issue
Block a user