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;