From 882d30797e237b362eebe3f9bbf1a72be38581c5 Mon Sep 17 00:00:00 2001 From: MelekTaus Moribundus Date: Thu, 2 Jul 2026 09:20:40 +0200 Subject: [PATCH] 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 --- Assets/Scripts/FirstPersonController.cs | 24 +---- Assets/Scripts/FirstPersonMode.cs | 14 +-- Assets/Scripts/FreeCamController.cs | 20 +--- Assets/Scripts/InputUtil.cs | 107 ++++++++++++++++++++ Assets/Scripts/InputUtil.cs.meta | 2 + Assets/Scripts/MeshPainter.Setup.cs | 4 +- Assets/Scripts/MeshPainter.cs | 77 +++++--------- Assets/Scripts/PaintHud.Library.cs | 3 +- Assets/Scripts/PaintHud.cs | 3 +- Assets/Scripts/PlayerCharacterController.cs | 39 ++----- Assets/Scripts/ThirdPersonOrbitInput.cs | 87 ++-------------- 11 files changed, 158 insertions(+), 222 deletions(-) create mode 100644 Assets/Scripts/InputUtil.cs create mode 100644 Assets/Scripts/InputUtil.cs.meta diff --git a/Assets/Scripts/FirstPersonController.cs b/Assets/Scripts/FirstPersonController.cs index aa89457..935826c 100644 --- a/Assets/Scripts/FirstPersonController.cs +++ b/Assets/Scripts/FirstPersonController.cs @@ -1,8 +1,5 @@ using UnityEngine; using Unity.Cinemachine; -#if ENABLE_INPUT_SYSTEM -using UnityEngine.InputSystem; -#endif /// /// First-person camera. Drives its OWN dedicated : 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(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; - } } diff --git a/Assets/Scripts/FirstPersonMode.cs b/Assets/Scripts/FirstPersonMode.cs index ee8bec6..b86bf98 100644 --- a/Assets/Scripts/FirstPersonMode.cs +++ b/Assets/Scripts/FirstPersonMode.cs @@ -1,8 +1,5 @@ using UnityEngine; using Unity.Netcode; -#if ENABLE_INPUT_SYSTEM -using UnityEngine.InputSystem; -#endif /// /// 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 { public static readonly RaycastDistanceComparer Instance = new RaycastDistanceComparer(); diff --git a/Assets/Scripts/FreeCamController.cs b/Assets/Scripts/FreeCamController.cs index e664f42..1670e03 100644 --- a/Assets/Scripts/FreeCamController.cs +++ b/Assets/Scripts/FreeCamController.cs @@ -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; - } } diff --git a/Assets/Scripts/InputUtil.cs b/Assets/Scripts/InputUtil.cs new file mode 100644 index 0000000..d770f95 --- /dev/null +++ b/Assets/Scripts/InputUtil.cs @@ -0,0 +1,107 @@ +using UnityEngine; +#if ENABLE_INPUT_SYSTEM +using UnityEngine.InputSystem; +#endif + +/// +/// Shared low-level input reads that were previously copy-pasted verbatim across the camera rigs +/// (, , +/// ), 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. +/// +public static class InputUtil +{ + /// Raw mouse delta this frame (pixels); the legacy path scales GetAxisRaw by 10 to match. + 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 + } + + /// Raw mouse-wheel delta this frame (usually only its sign is used). + 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 + } + + /// Locks+hides or frees+shows the hardware cursor. + 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 + } + + /// Left mouse button pressed on this exact frame (edge, not held). + public static bool LeftClickedThisFrame() + { +#if ENABLE_INPUT_SYSTEM + return Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame; +#else + return Input.GetMouseButtonDown(0); +#endif + } +} diff --git a/Assets/Scripts/InputUtil.cs.meta b/Assets/Scripts/InputUtil.cs.meta new file mode 100644 index 0000000..caa1f89 --- /dev/null +++ b/Assets/Scripts/InputUtil.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9ec32d583d2203244b854643c78360d4 \ No newline at end of file diff --git a/Assets/Scripts/MeshPainter.Setup.cs b/Assets/Scripts/MeshPainter.Setup.cs index f0f1cf4..c597895 100644 --- a/Assets/Scripts/MeshPainter.Setup.cs +++ b/Assets/Scripts/MeshPainter.Setup.cs @@ -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))); diff --git a/Assets/Scripts/MeshPainter.cs b/Assets/Scripts/MeshPainter.cs index 16e70f8..1008111 100644 --- a/Assets/Scripts/MeshPainter.cs +++ b/Assets/Scripts/MeshPainter.cs @@ -72,23 +72,23 @@ public partial class MeshPainter : MonoBehaviour /// 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); } /// Companion to : additive brightness shift (-1..1) of the /// flattened diffuse term, so the body tone can be tuned to match the scene. 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); } /// Companion to : scales down the direct specular highlight. 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); } /// @@ -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. 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); } /// Multiplier on the painted-height relief NORMAL strength (1 = base, 0 = flat). 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); } /// Multiplier on the painted-height UV PARALLAX amplitude (1 = base , /// 0 = no displacement). Backed by the material's _Parallax, so it round-trips like the others. 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); } /// Drives the see-through-walls X-ray overlay (see PlayerCamoLit): 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 - } - /// True if the pointer is currently over an interactive UI element (raycast target). private static bool IsPointerOverUi() { diff --git a/Assets/Scripts/PaintHud.Library.cs b/Assets/Scripts/PaintHud.Library.cs index e7ad7e9..0ebfd04 100644 --- a/Assets/Scripts/PaintHud.Library.cs +++ b/Assets/Scripts/PaintHud.Library.cs @@ -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 }); diff --git a/Assets/Scripts/PaintHud.cs b/Assets/Scripts/PaintHud.cs index 5e056d2..3318d64 100644 --- a/Assets/Scripts/PaintHud.cs +++ b/Assets/Scripts/PaintHud.cs @@ -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)); } } diff --git a/Assets/Scripts/PlayerCharacterController.cs b/Assets/Scripts/PlayerCharacterController.cs index bc27939..fbf01cd 100644 --- a/Assets/Scripts/PlayerCharacterController.cs +++ b/Assets/Scripts/PlayerCharacterController.cs @@ -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 - } - /// /// Collects contact normals during Move: wall/ceiling contacts feed the /// wall-climb detector, the flattest upward contact becomes the ground normal. diff --git a/Assets/Scripts/ThirdPersonOrbitInput.cs b/Assets/Scripts/ThirdPersonOrbitInput.cs index 87d1432..9c03c7d 100644 --- a/Assets/Scripts/ThirdPersonOrbitInput.cs +++ b/Assets/Scripts/ThirdPersonOrbitInput.cs @@ -1,8 +1,5 @@ using UnityEngine; using Unity.Cinemachine; -#if ENABLE_INPUT_SYSTEM -using UnityEngine.InputSystem; -#endif /// /// Feeds mouse input into a 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()); } /// Adds to an input axis; wrapping axes wrap, others clamp to their range. @@ -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 - } - /// 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 - } }