diff --git a/Assets/Scripts/FirstPersonMode.cs b/Assets/Scripts/FirstPersonMode.cs
index e4a89df..b5b389c 100644
--- a/Assets/Scripts/FirstPersonMode.cs
+++ b/Assets/Scripts/FirstPersonMode.cs
@@ -36,6 +36,12 @@ public class FirstPersonMode : GameMode
Manager.FirstPerson.SetActive(false);
if (Manager.CameraInput)
+ {
Manager.CameraInput.enabled = true;
+ // Carry the first-person facing into the orbit camera so the next orbit mode (Paint / Player
+ // Control) keeps the current view angle instead of snapping back to the orbit's last-used angle.
+ // Camera.main still shows the first-person view this frame (the brain hasn't blended yet).
+ Manager.CameraInput.SyncToView();
+ }
}
}
diff --git a/Assets/Scripts/ThirdPersonOrbitInput.cs b/Assets/Scripts/ThirdPersonOrbitInput.cs
index b05cdd3..148dd8e 100644
--- a/Assets/Scripts/ThirdPersonOrbitInput.cs
+++ b/Assets/Scripts/ThirdPersonOrbitInput.cs
@@ -123,6 +123,27 @@ public class ThirdPersonOrbitInput : MonoBehaviour
_zoomInit = true;
}
+ /// Snaps the orbit axes so the camera faces along Camera.main's current view direction, so the
+ /// next orbit mode keeps that facing instead of restoring the orbit's last-used angle. Called when
+ /// switching out of a non-orbit rig (first person): Camera.main still shows that rig's view this frame
+ /// (the brain hasn't blended yet), so the read is exact. With WorldSpace binding + Sphere orbit + a
+ /// centered composer the camera look rotation is exactly Euler(VerticalAxis, HorizontalAxis, 0), so
+ /// HorizontalAxis = world yaw and VerticalAxis = world pitch (positive = looking down). No-op without a
+ /// live camera/orbit.
+ public void SyncToView()
+ {
+ if (!_orbit) return;
+ var cam = Camera.main;
+ if (!cam) return;
+
+ Vector3 e = cam.transform.rotation.eulerAngles;
+ SetAxisValue(ref _orbit.HorizontalAxis, e.y > 180f ? e.y - 360f : e.y);
+ SetAxisValue(ref _orbit.VerticalAxis, e.x > 180f ? e.x - 360f : e.x);
+
+ // Drop any eased look carry-over so the snapped angle isn't immediately dragged back.
+ _smoothedLook = Vector2.zero;
+ }
+
void Update()
{
if (!_orbit)
@@ -210,8 +231,11 @@ public class ThirdPersonOrbitInput : MonoBehaviour
/// Adds to an input axis; wrapping axes wrap, others clamp to their range.
static void ApplyAxisDelta(ref InputAxis axis, float amount)
+ => SetAxisValue(ref axis, axis.Value + amount);
+
+ /// Sets an input axis to an absolute value; wrapping axes wrap, others clamp to their range.
+ static void SetAxisValue(ref InputAxis axis, float value)
{
- float value = axis.Value + amount;
float min = axis.Range.x;
float max = axis.Range.y;