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