Refactor: dedupe input reads, material-property guards, button hooks

Extract byte-identical duplicated code into shared helpers (behaviour-neutral):
- New InputUtil.cs: single source for mouse-delta/scroll/cursor-lock, modifier
  and mouse-button reads, previously copied verbatim across camera controllers,
  MeshPainter, FirstPersonMode and PlayerCharacterController.
- GetMatFloat/SetMatFloat replace the 12x material-instance + HasProperty guard
  pattern for the camo/height float properties.
- Route two inline button hooks through the existing Hook() helper.

Bespoke variants deliberately kept local (FreeCam SprintHeld = LeftShift only,
MeshPainter.TryGetMouse with out-params).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-07-02 09:20:40 +02:00
1 parent 626dcc1bdf
commit 882d30797e
11 files changed
+158 -222

No files matched your search

+3 -21
View File
@@ -1,8 +1,5 @@
using UnityEngine;
using Unity.Cinemachine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
/// <summary>
/// First-person camera. Drives its OWN dedicated <see cref="CinemachineCamera"/>: each frame it snaps
@@ -90,13 +87,13 @@ public class FirstPersonController : MonoBehaviour
if (active)
{
SyncToCurrentView();
SetCursorLocked(true);
InputUtil.SetCursorLocked(true);
ApplyTransform(); // place at the eye on the same frame so the blend starts from there
if (_player) _player.FaceYaw = _displayYaw; // body faces the camera from frame one
}
else
{
SetCursorLocked(false);
InputUtil.SetCursorLocked(false);
if (_player) _player.FaceYaw = null; // restore movement-facing
}
@@ -113,7 +110,7 @@ public class FirstPersonController : MonoBehaviour
void LookTick()
{
Vector2 delta = ReadMouseDelta() * MouseSensitivity.Multiplier;
Vector2 delta = InputUtil.ReadMouseDelta() * MouseSensitivity.Multiplier;
_yaw += delta.x * horizontalSensitivity;
float vs = verticalSensitivity * (invertY ? 1f : -1f);
_pitch = Mathf.Clamp(_pitch + delta.y * vs, -maxPitch, maxPitch);
@@ -212,19 +209,4 @@ public class FirstPersonController : MonoBehaviour
if (hiddenRenderers == null || hiddenRenderers.Length == 0)
hiddenRenderers = player.GetComponentsInChildren<SkinnedMeshRenderer>(true);
}
Vector2 ReadMouseDelta()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null ? Mouse.current.delta.ReadValue() : Vector2.zero;
#else
return new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")) * 10f;
#endif
}
static void SetCursorLocked(bool locked)
{
Cursor.lockState = locked ? CursorLockMode.Locked : CursorLockMode.None;
Cursor.visible = !locked;
}
}
+1 -13
View File
@@ -1,8 +1,5 @@
using UnityEngine;
using Unity.Netcode;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
/// <summary>
/// First-person mode. The player keeps walking (WASD, camera-relative) but the camera moves to the
@@ -64,7 +61,7 @@ public class FirstPersonMode : GameMode
{
if (!CanShoot()) return;
if (Time.time < _nextShootTime) return;
if (!ClickedThisFrame()) return;
if (!InputUtil.LeftClickedThisFrame()) return;
_nextShootTime = Time.time + Mathf.Max(0f, MatchManager.Instance.ShootCooldown);
TryShoot();
@@ -107,15 +104,6 @@ public class FirstPersonMode : GameMode
}
}
private static bool ClickedThisFrame()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame;
#else
return Input.GetMouseButtonDown(0);
#endif
}
private sealed class RaycastDistanceComparer : System.Collections.Generic.IComparer<RaycastHit>
{
public static readonly RaycastDistanceComparer Instance = new RaycastDistanceComparer();
+3 -17
View File
@@ -91,11 +91,11 @@ public class FreeCamController : MonoBehaviour
{
IgnorePlayerCollision();
SyncToCurrentView();
SetCursorLocked(true);
InputUtil.SetCursorLocked(true);
}
else
{
SetCursorLocked(false);
InputUtil.SetCursorLocked(false);
}
enabled = active;
@@ -109,7 +109,7 @@ public class FreeCamController : MonoBehaviour
void LookTick()
{
Vector2 delta = ReadMouseDelta() * MouseSensitivity.Multiplier;
Vector2 delta = InputUtil.ReadMouseDelta() * MouseSensitivity.Multiplier;
_yaw += delta.x * horizontalSensitivity;
float vs = verticalSensitivity * (invertY ? 1f : -1f);
_pitch = Mathf.Clamp(_pitch + delta.y * vs, -maxPitch, maxPitch);
@@ -222,18 +222,4 @@ public class FreeCamController : MonoBehaviour
#endif
}
Vector2 ReadMouseDelta()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null ? Mouse.current.delta.ReadValue() : Vector2.zero;
#else
return new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")) * 10f;
#endif
}
static void SetCursorLocked(bool locked)
{
Cursor.lockState = locked ? CursorLockMode.Locked : CursorLockMode.None;
Cursor.visible = !locked;
}
}
+107
View File
@@ -0,0 +1,107 @@
using UnityEngine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
/// <summary>
/// Shared low-level input reads that were previously copy-pasted verbatim across the camera rigs
/// (<see cref="FirstPersonController"/>, <see cref="FreeCamController"/>,
/// <see cref="ThirdPersonOrbitInput"/>), the paint controller and the first-person shoot mode. Each
/// method preserves its original per-backend behaviour (new Input System when present, legacy Input
/// Manager otherwise). Sensitivity scaling stays at the call sites.
/// </summary>
public static class InputUtil
{
/// <summary>Raw mouse delta this frame (pixels); the legacy path scales GetAxisRaw by 10 to match.</summary>
public static Vector2 ReadMouseDelta()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null ? Mouse.current.delta.ReadValue() : Vector2.zero;
#else
return new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")) * 10f;
#endif
}
/// <summary>Raw mouse-wheel delta this frame (usually only its sign is used).</summary>
public static float ReadScroll()
{
#if ENABLE_INPUT_SYSTEM
if (Mouse.current != null) return Mouse.current.scroll.ReadValue().y;
#endif
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetAxis("Mouse ScrollWheel");
#else
return 0f;
#endif
}
/// <summary>Locks+hides or frees+shows the hardware cursor.</summary>
public static void SetCursorLocked(bool locked)
{
Cursor.lockState = locked ? CursorLockMode.Locked : CursorLockMode.None;
Cursor.visible = !locked;
}
public static bool ShiftHeld()
{
#if ENABLE_INPUT_SYSTEM
var kb = Keyboard.current;
if (kb != null) return kb.leftShiftKey.isPressed || kb.rightShiftKey.isPressed;
#endif
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
#else
return false;
#endif
}
public static bool CtrlHeld()
{
#if ENABLE_INPUT_SYSTEM
var kb = Keyboard.current;
if (kb != null) return kb.leftCtrlKey.isPressed || kb.rightCtrlKey.isPressed;
#endif
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
#else
return false;
#endif
}
public static bool LeftMouseHeld()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null && Mouse.current.leftButton.isPressed;
#else
return Input.GetMouseButton(0);
#endif
}
public static bool RightMouseHeld()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null && Mouse.current.rightButton.isPressed;
#else
return Input.GetMouseButton(1);
#endif
}
public static bool MiddleMouseHeld()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null && Mouse.current.middleButton.isPressed;
#else
return Input.GetMouseButton(2);
#endif
}
/// <summary>Left mouse button pressed on this exact frame (edge, not held).</summary>
public static bool LeftClickedThisFrame()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame;
#else
return Input.GetMouseButtonDown(0);
#endif
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9ec32d583d2203244b854643c78360d4
+2 -2
View File
@@ -152,8 +152,8 @@ public partial class MeshPainter
// A = smoothness. G = 128 (= 0.5) is the NEUTRAL height: no parallax/relief and AO =
// saturate(2*0.5) = 1 (no darkening), so the unpainted look is unchanged. Painting G
// below 0.5 carves a hole (and darkens), above 0.5 raises a hill (see PlayerCamoLit).
float metallic0 = _materialInstance.HasProperty(MetallicId) ? _materialInstance.GetFloat(MetallicId) : 0f;
float smoothness0 = _materialInstance.HasProperty(SmoothnessId) ? _materialInstance.GetFloat(SmoothnessId) : 0.5f;
float metallic0 = GetMatFloat(MetallicId, 0f);
float smoothness0 = GetMatFloat(SmoothnessId, 0.5f);
_seedCanonical[MAP_MSO] = FillCanonical(new Color32(
(byte)(Mathf.Clamp01(metallic0) * 255f), 128, 0, (byte)(Mathf.Clamp01(smoothness0) * 255f)));
+24 -53
View File
@@ -72,23 +72,23 @@ public partial class MeshPainter : MonoBehaviour
/// </summary>
public float CamoHalfLambert
{
get => _materialInstance && _materialInstance.HasProperty(HalfLambertId) ? _materialInstance.GetFloat(HalfLambertId) : 0f;
set { if (_materialInstance && _materialInstance.HasProperty(HalfLambertId)) _materialInstance.SetFloat(HalfLambertId, value); }
get => GetMatFloat(HalfLambertId, 0f);
set => SetMatFloat(HalfLambertId, value);
}
/// <summary>Companion to <see cref="CamoHalfLambert"/>: additive brightness shift (-1..1) of the
/// flattened diffuse term, so the body tone can be tuned to match the scene.</summary>
public float CamoHalfLambertBrightness
{
get => _materialInstance && _materialInstance.HasProperty(HalfLambertBrightnessId) ? _materialInstance.GetFloat(HalfLambertBrightnessId) : 0f;
set { if (_materialInstance && _materialInstance.HasProperty(HalfLambertBrightnessId)) _materialInstance.SetFloat(HalfLambertBrightnessId, value); }
get => GetMatFloat(HalfLambertBrightnessId, 0f);
set => SetMatFloat(HalfLambertBrightnessId, value);
}
/// <summary>Companion to <see cref="CamoHalfLambert"/>: scales down the direct specular highlight.</summary>
public float CamoSpecularDampen
{
get => _materialInstance && _materialInstance.HasProperty(SpecularDampenId) ? _materialInstance.GetFloat(SpecularDampenId) : 0f;
set { if (_materialInstance && _materialInstance.HasProperty(SpecularDampenId)) _materialInstance.SetFloat(SpecularDampenId, value); }
get => GetMatFloat(SpecularDampenId, 0f);
set => SetMatFloat(SpecularDampenId, value);
}
/// <summary>
@@ -101,23 +101,23 @@ public partial class MeshPainter : MonoBehaviour
/// the deepest painted hole. 0 = no darkening (no black spots), 1 = full black at occ=0.</summary>
public float OcclusionThreshold
{
get => _materialInstance && _materialInstance.HasProperty(OcclusionThresholdId) ? _materialInstance.GetFloat(OcclusionThresholdId) : 0.2f;
set { if (_materialInstance && _materialInstance.HasProperty(OcclusionThresholdId)) _materialInstance.SetFloat(OcclusionThresholdId, value); }
get => GetMatFloat(OcclusionThresholdId, 0.2f);
set => SetMatFloat(OcclusionThresholdId, value);
}
/// <summary>Multiplier on the painted-height relief NORMAL strength (1 = base, 0 = flat).</summary>
public float HeightNormalIntensity
{
get => _materialInstance && _materialInstance.HasProperty(HeightNormalIntensityId) ? _materialInstance.GetFloat(HeightNormalIntensityId) : 1.4f;
set { if (_materialInstance && _materialInstance.HasProperty(HeightNormalIntensityId)) _materialInstance.SetFloat(HeightNormalIntensityId, value); }
get => GetMatFloat(HeightNormalIntensityId, 1.4f);
set => SetMatFloat(HeightNormalIntensityId, value);
}
/// <summary>Multiplier on the painted-height UV PARALLAX amplitude (1 = base <see cref="ParallaxBase"/>,
/// 0 = no displacement). Backed by the material's _Parallax, so it round-trips like the others.</summary>
public float ParallaxIntensity
{
get => _materialInstance && _materialInstance.HasProperty(ParallaxId) ? _materialInstance.GetFloat(ParallaxId) / ParallaxBase : 1f;
set { if (_materialInstance && _materialInstance.HasProperty(ParallaxId)) _materialInstance.SetFloat(ParallaxId, Mathf.Max(0f, value) * ParallaxBase); }
get => GetMatFloat(ParallaxId, ParallaxBase) / ParallaxBase;
set => SetMatFloat(ParallaxId, Mathf.Max(0f, value) * ParallaxBase);
}
/// <summary>Drives the see-through-walls X-ray overlay (see <c>PlayerCamoLit</c>): sets the TARGET for
@@ -1060,6 +1060,15 @@ public partial class MeshPainter : MonoBehaviour
private static float Cross2D(Vector2 a, Vector2 b) => a.x * b.y - a.y * b.x;
// Guarded material float access: absent instance/property -> the caller's fallback, no write.
private float GetMatFloat(int id, float fallback)
=> _materialInstance && _materialInstance.HasProperty(id) ? _materialInstance.GetFloat(id) : fallback;
private void SetMatFloat(int id, float value)
{
if (_materialInstance && _materialInstance.HasProperty(id)) _materialInstance.SetFloat(id, value);
}
private bool TryGetMouse(out bool pressed, out Vector2 screenPos)
{
pressed = false;
@@ -1096,8 +1105,8 @@ public partial class MeshPainter : MonoBehaviour
{
// Momentary pipette: arm on the Shift/Ctrl press (remembering the toggle's state), force it on
// while held (re-arms after a one-shot pick), and restore the prior state on release.
bool shift = ShiftHeld();
bool ctrl = CtrlHeld();
bool shift = InputUtil.ShiftHeld();
bool ctrl = InputUtil.CtrlHeld();
bool mod = shift || ctrl;
if (mod && !_pipetteModHeld) _pipetteBeforeMod = pipette;
if (mod) pipette = true;
@@ -1108,7 +1117,7 @@ public partial class MeshPainter : MonoBehaviour
// held, so it does not also zoom).
if (!mod) return;
float scroll = ReadScroll();
float scroll = InputUtil.ReadScroll();
if (Mathf.Approximately(scroll, 0f)) return;
// Geometric resize: the step scales with the current size, so small brushes change a texel
@@ -1121,44 +1130,6 @@ public partial class MeshPainter : MonoBehaviour
BrushSizeChanged?.Invoke();
}
private static bool ShiftHeld()
{
#if ENABLE_INPUT_SYSTEM
var kb = Keyboard.current;
if (kb != null) return kb.leftShiftKey.isPressed || kb.rightShiftKey.isPressed;
#endif
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
#else
return false;
#endif
}
private static bool CtrlHeld()
{
#if ENABLE_INPUT_SYSTEM
var kb = Keyboard.current;
if (kb != null) return kb.leftCtrlKey.isPressed || kb.rightCtrlKey.isPressed;
#endif
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
#else
return false;
#endif
}
private static float ReadScroll()
{
#if ENABLE_INPUT_SYSTEM
if (Mouse.current != null) return Mouse.current.scroll.ReadValue().y;
#endif
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetAxis("Mouse ScrollWheel");
#else
return 0f;
#endif
}
/// <summary>True if the pointer is currently over an interactive UI element (raycast target).</summary>
private static bool IsPointerOverUi()
{
+1 -2
View File
@@ -144,8 +144,7 @@ public partial class PaintHud
if (btn)
{
string captured = name;
btn.onClick.RemoveAllListeners();
btn.onClick.AddListener(() => SelectPainting(captured));
Hook(btn, () => SelectPainting(captured));
}
_entries.Add(new EntryRef { name = name, bg = bg });
+1 -2
View File
@@ -455,8 +455,7 @@ public partial class PaintHud : MonoBehaviour
if (btn)
{
int idx = i; // capture per swatch
btn.onClick.RemoveAllListeners();
btn.onClick.AddListener(() => SelectMask(idx));
Hook(btn, () => SelectMask(idx));
}
}
+6 -33
View File
@@ -775,12 +775,12 @@ public class PlayerCharacterController : MonoBehaviour
// offset eases back to zero while moving and never detaches. On a WALL the turn is a held
// yaw offset from the wall normal (kept until leaving); on a CEILING the body is free like
// on the ground, so the drag rotates the transform directly. Either drag pauses the orbit.
bool offsetDrag = found && IsLeftMouseHeld();
bool yawDrag = found && IsRightMouseHeld();
bool offsetDrag = found && InputUtil.LeftMouseHeld();
bool yawDrag = found && InputUtil.RightMouseHeld();
if (offsetDrag || yawDrag)
{
_offsetDragging = true;
Vector2 drag = ReadMouseDelta();
Vector2 drag = InputUtil.ReadMouseDelta();
if (offsetDrag)
_wallOffset = Mathf.Clamp(_wallOffset - drag.y * wallOffsetSensitivity, -wallMaxInset, wallMaxOffset);
if (yawDrag)
@@ -948,14 +948,14 @@ public class PlayerCharacterController : MonoBehaviour
{
_offsetDragging = false;
bool offsetDrag = IsLeftMouseHeld();
bool yawDrag = IsRightMouseHeld();
bool offsetDrag = InputUtil.LeftMouseHeld();
bool yawDrag = InputUtil.RightMouseHeld();
bool hasMoveInput = (h * h + v * v) > 1e-4f;
if (offsetDrag || yawDrag)
{
_offsetDragging = true;
Vector2 drag = ReadMouseDelta();
Vector2 drag = InputUtil.ReadMouseDelta();
if (offsetDrag)
_groundOffset = Mathf.Clamp(
_groundOffset + drag.y * wallOffsetSensitivity, -wallMaxInset, wallMaxOffset);
@@ -1245,33 +1245,6 @@ public class PlayerCharacterController : MonoBehaviour
_mantleTimer = 0f;
}
bool IsLeftMouseHeld()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null && Mouse.current.leftButton.isPressed;
#else
return Input.GetMouseButton(0);
#endif
}
bool IsRightMouseHeld()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null && Mouse.current.rightButton.isPressed;
#else
return Input.GetMouseButton(1);
#endif
}
Vector2 ReadMouseDelta()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null ? Mouse.current.delta.ReadValue() : Vector2.zero;
#else
return new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")) * 10f;
#endif
}
/// <summary>
/// Collects contact normals during Move: wall/ceiling contacts feed the
/// wall-climb detector, the flattest upward contact becomes the ground normal.
+8 -79
View File
@@ -1,8 +1,5 @@
using UnityEngine;
using Unity.Cinemachine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
/// <summary>
/// Feeds mouse input into a <see cref="CinemachineOrbitalFollow"/> so the camera
@@ -141,7 +138,7 @@ public class ThirdPersonOrbitInput : MonoBehaviour
void OnDisable()
{
SetCursorLocked(false);
InputUtil.SetCursorLocked(false);
// 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 -
@@ -209,11 +206,11 @@ public class ThirdPersonOrbitInput : MonoBehaviour
bool modeWantsLook = ShouldRotate();
if (manageCursor)
SetCursorLocked(modeWantsLook);
InputUtil.SetCursorLocked(modeWantsLook);
if (modeWantsLook && !LookSuppressed)
{
Vector2 delta = ReadMouseDelta() * MouseSensitivity.Multiplier;
Vector2 delta = InputUtil.ReadMouseDelta() * MouseSensitivity.Multiplier;
Vector2 raw = new Vector2(
delta.x * horizontalSensitivity,
delta.y * verticalSensitivity * (invertY ? 1f : -1f));
@@ -250,7 +247,7 @@ public class ThirdPersonOrbitInput : MonoBehaviour
// Shift/Ctrl+wheel is reserved for the paint brush resize (MeshPainter), so the orbit camera
// ignores the wheel while either is held - otherwise it would zoom and resize at once.
float scroll = (ShiftHeld() || CtrlHeld()) ? 0f : ReadScroll();
float scroll = (InputUtil.ShiftHeld() || InputUtil.CtrlHeld()) ? 0f : InputUtil.ReadScroll();
if (!Mathf.Approximately(scroll, 0f))
{
// One wheel notch = one zoom step (sign only), independent of the platform's raw wheel
@@ -277,7 +274,7 @@ public class ThirdPersonOrbitInput : MonoBehaviour
switch (lookMode)
{
case OrbitLookMode.AlwaysActive: return true;
case OrbitLookMode.HoldRightMouseButton: return IsRightMouseHeld();
case OrbitLookMode.HoldRightMouseButton: return InputUtil.RightMouseHeld();
default: return false;
}
}
@@ -285,7 +282,7 @@ public class ThirdPersonOrbitInput : MonoBehaviour
void ApplyCursorState()
{
if (manageCursor)
SetCursorLocked(ShouldRotate());
InputUtil.SetCursorLocked(ShouldRotate());
}
/// <summary>Adds to an input axis; wrapping axes wrap, others clamp to their range.</summary>
@@ -311,30 +308,6 @@ public class ThirdPersonOrbitInput : MonoBehaviour
axis.Value = value;
}
static void SetCursorLocked(bool locked)
{
Cursor.lockState = locked ? CursorLockMode.Locked : CursorLockMode.None;
Cursor.visible = !locked;
}
bool IsRightMouseHeld()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null && Mouse.current.rightButton.isPressed;
#else
return Input.GetMouseButton(1);
#endif
}
bool IsMiddleMouseHeld()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null && Mouse.current.middleButton.isPressed;
#else
return Input.GetMouseButton(2);
#endif
}
/// <summary>Middle-mouse pan: while PaintMode enables it, holding the middle button and dragging slides the
/// whole framing along the screen right/up axes (via the camera-offset extension), then eases the offset
/// back to center on release. A temporary framing offset to line up an awkward spot of the model for
@@ -348,9 +321,9 @@ public class ThirdPersonOrbitInput : MonoBehaviour
bool active = PanEnabled && lookMode != OrbitLookMode.Disabled;
float zoom = PanZoomScale();
if (active && IsMiddleMouseHeld())
if (active && InputUtil.MiddleMouseHeld())
{
Vector2 d = ReadMouseDelta() * MouseSensitivity.Multiplier;
Vector2 d = InputUtil.ReadMouseDelta() * MouseSensitivity.Multiplier;
// Subtracting the drag gives a hand-tool feel (the model follows the cursor: drag right -> model
// 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
@@ -382,48 +355,4 @@ public class ThirdPersonOrbitInput : MonoBehaviour
_camOffset.Offset = new Vector3(_pan.x, _pan.y, 0f);
}
static bool ShiftHeld()
{
#if ENABLE_INPUT_SYSTEM
var kb = Keyboard.current;
if (kb != null) return kb.leftShiftKey.isPressed || kb.rightShiftKey.isPressed;
#endif
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
#else
return false;
#endif
}
static bool CtrlHeld()
{
#if ENABLE_INPUT_SYSTEM
var kb = Keyboard.current;
if (kb != null) return kb.leftCtrlKey.isPressed || kb.rightCtrlKey.isPressed;
#endif
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
#else
return false;
#endif
}
Vector2 ReadMouseDelta()
{
#if ENABLE_INPUT_SYSTEM
return Mouse.current != null ? Mouse.current.delta.ReadValue() : Vector2.zero;
#else
return new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")) * 10f;
#endif
}
float ReadScroll()
{
#if ENABLE_INPUT_SYSTEM
// Raw wheel delta; only its sign is used (one notch = one zoom step).
return Mouse.current != null ? Mouse.current.scroll.ReadValue().y : 0f;
#else
return Input.GetAxis("Mouse ScrollWheel");
#endif
}
}