diff --git a/Assets/Scripts/Components/Controller/ThirdPersonOrbitInput.cs b/Assets/Scripts/Components/Controller/ThirdPersonOrbitInput.cs index f089884..b85607c 100644 --- a/Assets/Scripts/Components/Controller/ThirdPersonOrbitInput.cs +++ b/Assets/Scripts/Components/Controller/ThirdPersonOrbitInput.cs @@ -238,11 +238,13 @@ public class ThirdPersonOrbitInput : MonoBehaviour float scale = CurrentScale(); - // Shift/Ctrl+wheel is reserved for the paint brush resize (MeshPainter) - but only in paint - // mode (PanEnabled), where the resize actually claims the wheel. Outside paint mode Shift is - // the sprint key, so the wheel must still zoom. - bool brushResizeClaimsWheel = PanEnabled && (InputUtil.ShiftHeld() || InputUtil.CtrlHeld()); - float scroll = brushResizeClaimsWheel ? 0f : InputUtil.ReadScroll(); + // The wheel belongs to the UI when the pointer is over an interactive element (e.g. a scroll + // list), so it scrolls the UI instead of zooming. Shift/Ctrl+wheel is likewise reserved for the + // paint brush resize (MeshPainter) - but only in paint mode (PanEnabled), where the resize + // actually claims the wheel; outside paint mode Shift is the sprint key, so the wheel must zoom. + bool wheelClaimed = InputUtil.PointerOverUi() + || (PanEnabled && (InputUtil.ShiftHeld() || InputUtil.CtrlHeld())); + float scroll = wheelClaimed ? 0f : InputUtil.ReadScroll(); if (!Mathf.Approximately(scroll, 0f)) { // One wheel notch = one zoom step (sign only, platform-independent). The step scales with diff --git a/Assets/Scripts/Components/MeshPainter/MeshPainter.cs b/Assets/Scripts/Components/MeshPainter/MeshPainter.cs index 18097e9..da23a34 100644 --- a/Assets/Scripts/Components/MeshPainter/MeshPainter.cs +++ b/Assets/Scripts/Components/MeshPainter/MeshPainter.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using UnityEngine; -using UnityEngine.EventSystems; #if ENABLE_INPUT_SYSTEM using UnityEngine.InputSystem; #endif @@ -1123,11 +1122,7 @@ public partial class MeshPainter : MonoBehaviour } /// True if the pointer is currently over an interactive UI element (raycast target). - private static bool IsPointerOverUi() - { - var es = EventSystem.current; - return es && es.IsPointerOverGameObject(); - } + private static bool IsPointerOverUi() => InputUtil.PointerOverUi(); private void OnDestroy() { diff --git a/Assets/Scripts/Helper/InputUtil.cs b/Assets/Scripts/Helper/InputUtil.cs index e154b21..3a0cb9a 100644 --- a/Assets/Scripts/Helper/InputUtil.cs +++ b/Assets/Scripts/Helper/InputUtil.cs @@ -1,4 +1,5 @@ using UnityEngine; +using UnityEngine.EventSystems; #if ENABLE_INPUT_SYSTEM using UnityEngine.InputSystem; #endif @@ -40,6 +41,15 @@ public static class InputUtil Cursor.visible = !locked; } + /// True while the pointer is over an interactive UI element (a raycast target), so the + /// wheel/click belongs to the UI (e.g. a scroll list) and must not also zoom the camera or paint + /// the mesh behind it. False when no EventSystem exists. + public static bool PointerOverUi() + { + var es = EventSystem.current; + return es && es.IsPointerOverGameObject(); + } + public static bool ShiftHeld() { #if ENABLE_INPUT_SYSTEM