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>
48 lines
1.9 KiB
C#
48 lines
1.9 KiB
C#
/// <summary>
|
|
/// First-person mode. The player keeps walking (WASD, camera-relative) but the camera moves to the
|
|
/// player's eye (the CameraTarget) with free mouse-look, and the player's mesh is hidden so the body
|
|
/// isn't seen from the inside. The orbit camera input is disabled while here so it doesn't fight for
|
|
/// the cursor; the <see cref="FirstPersonController"/> drives its own dedicated CinemachineCamera.
|
|
/// </summary>
|
|
public class FirstPersonMode : GameMode
|
|
{
|
|
public override string DisplayName => "First Person";
|
|
|
|
public override void Enter()
|
|
{
|
|
// Player stays fully controllable; only the view changes.
|
|
if (Manager.Player)
|
|
{
|
|
Manager.Player.enabled = true;
|
|
Manager.Player.ControlEnabled = true;
|
|
}
|
|
|
|
if (Manager.Painter)
|
|
Manager.Painter.PaintingEnabled = false;
|
|
|
|
// The orbit rig would otherwise keep grabbing the cursor and reading the mouse every frame.
|
|
if (Manager.CameraInput)
|
|
Manager.CameraInput.enabled = false;
|
|
|
|
if (Manager.FirstPerson)
|
|
Manager.FirstPerson.SetActive(true);
|
|
}
|
|
|
|
public override void Exit()
|
|
{
|
|
// Modes are Enter-only, so first-person must undo its own camera takeover (and unhide the mesh)
|
|
// here; the next mode's Enter restores the player/painter/look-mode state.
|
|
if (Manager.FirstPerson)
|
|
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();
|
|
}
|
|
}
|
|
}
|