Carry first-person facing into orbit camera on mode switch
When leaving first person for an orbit mode (Paint / Player Control), snap the orbit axes to Camera.main's current view direction instead of restoring the orbit's last-used angle. With WorldSpace binding + Sphere orbit + a centered composer the camera look rotation is exactly Euler(VerticalAxis, HorizontalAxis, 0), so the inverse mapping is exact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
054cadbd80
commit
a7a4fbdcb7
2 files changed
+31
-1
No files matched your search
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,27 @@ public class ThirdPersonOrbitInput : MonoBehaviour
|
||||
_zoomInit = true;
|
||||
}
|
||||
|
||||
/// <summary>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.</summary>
|
||||
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
|
||||
|
||||
/// <summary>Adds to an input axis; wrapping axes wrap, others clamp to their range.</summary>
|
||||
static void ApplyAxisDelta(ref InputAxis axis, float amount)
|
||||
=> SetAxisValue(ref axis, axis.Value + amount);
|
||||
|
||||
/// <summary>Sets an input axis to an absolute value; wrapping axes wrap, others clamp to their range.</summary>
|
||||
static void SetAxisValue(ref InputAxis axis, float value)
|
||||
{
|
||||
float value = axis.Value + amount;
|
||||
float min = axis.Range.x;
|
||||
float max = axis.Range.y;
|
||||
|
||||
|
||||
Reference in new issue
Block a user