diff --git a/Assets/Scripts/ThirdPersonOrbitInput.cs b/Assets/Scripts/ThirdPersonOrbitInput.cs index 341d502..87d1432 100644 --- a/Assets/Scripts/ThirdPersonOrbitInput.cs +++ b/Assets/Scripts/ThirdPersonOrbitInput.cs @@ -79,8 +79,8 @@ public class ThirdPersonOrbitInput : MonoBehaviour "zoom (closer in = finer). Body scale is folded in automatically via the orbit radius.")] public float panSensitivity = 0.004f; - [Tooltip("Farthest the framing can pan from center, measured at the default zoom. It scales with the zoom " + - "distance too, so the maximum on-screen pan reach stays the same at every zoom level.")] + [Tooltip("Farthest the framing can pan from center, in world units (body scale folded in). This is NOT scaled " + + "by zoom, so the maximum pan distance stays the same at every zoom level - only the sensitivity changes.")] public float panMaxDistance = 1f; [Tooltip("How snappily the pan glides back to center when paint mode is left (1/second; 0 = snaps home " + @@ -142,9 +142,12 @@ public class ThirdPersonOrbitInput : MonoBehaviour void OnDisable() { SetCursorLocked(false); - // Drop any live pan so a disabled rig doesn't leave a stale framing offset behind. - _pan = Vector2.zero; - if (_camOffset) _camOffset.Offset = Vector3.zero; + // Deliberately DON'T zero the pan here. The only thing that disables this component is FreeCamMode + // taking over, and the freecam snaps to the live (still panned) view. Resetting the offset now would + // jump the orbit camera the brain blends FROM to center while the freecam sits at the panned pose - + // the visible "snap to 0, then translate to the offset" on the paint->freecam switch. Leaving the + // offset frozen keeps blend-from == blend-to (both panned) -> a seamless handoff. The pan then glides + // home on its own once the orbit input runs again in a non-paint mode (PanEnabled false). } /// Uniform scale of the current follow target (1 when none, or when Scale With Target is off). @@ -157,13 +160,13 @@ public class ThirdPersonOrbitInput : MonoBehaviour return t ? Mathf.Max(0.0001f, t.lossyScale.x) : 1f; } - /// How much the pan scales with the live zoom distance. Dividing the orbit radius by the default - /// radius makes this exactly 1 at the default zoom (so the authored panSensitivity/panMaxDistance keep their - /// feel there), smaller when zoomed in (finer pan, less reach) and larger when zoomed out. The body scale - /// cancels out because the radius already embeds it - a bigger player orbits proportionally farther - so the - /// pan stays body-relative across player sizes at every zoom, just like CurrentScale() did at the default - /// radius. The result: the model slides the same amount ON SCREEN per pixel, and the same maximum reach - /// across the screen, regardless of how far the wheel has zoomed. + /// How much the pan SENSITIVITY scales with the live zoom distance. Dividing the orbit radius by the + /// default radius makes this exactly 1 at the default zoom (so the authored panSensitivity keeps its feel + /// there), smaller when zoomed in (finer pan) and larger when zoomed out. The body scale cancels out because + /// the radius already embeds it - a bigger player orbits proportionally farther - so the pan stays + /// body-relative across player sizes at every zoom. The result: the model slides the same amount ON SCREEN + /// per pixel regardless of how far the wheel has zoomed. The clamp does NOT use this - panMaxDistance is + /// body-relative only (CurrentScale), so the world-space pan limit is constant across zoom levels. float PanZoomScale() => _orbit ? _orbit.Radius / Mathf.Max(0.0001f, defaultRadius) : 1f; /// Snaps the zoom to the scaled default radius. Called when a new avatar binds (see @@ -349,10 +352,11 @@ public class ThirdPersonOrbitInput : MonoBehaviour { Vector2 d = ReadMouseDelta() * MouseSensitivity.Multiplier; // Subtracting the drag gives a hand-tool feel (the model follows the cursor: drag right -> model - // slides right). Both the step and the clamp scale with the orbit distance so the pan feels the same - // on screen at every zoom - finer when zoomed in, and the same maximum reach across the screen. + // slides right). The step scales with the orbit distance so it feels the same on screen at every + // zoom (finer when zoomed in). The clamp stays body-relative only (no zoom factor), so the maximum + // pan distance in world units is the same at every zoom level. _pan -= d * (panSensitivity * zoom); - _pan = Vector2.ClampMagnitude(_pan, panMaxDistance * zoom); + _pan = Vector2.ClampMagnitude(_pan, panMaxDistance * CurrentScale()); } else if (active) {