diff --git a/Assets/Scripts/City3D/City3DCamera.cs b/Assets/Scripts/City3D/City3DCamera.cs index b46a694..1211385 100644 --- a/Assets/Scripts/City3D/City3DCamera.cs +++ b/Assets/Scripts/City3D/City3DCamera.cs @@ -66,7 +66,7 @@ public class City3DCamera : MonoBehaviour { // Колесо мыши (редактор, ПК) float wheel = Input.mouseScrollDelta.y; - if (UIBlocker.IsPointerOverUI()) wheel = 0f; // колесо над окнами HUD -- не приближать камеру (05.11) + if (City3DInput.OverHud(Input.mousePosition)) wheel = 0f; // колесо над окнами HUD -- не приближать камеру (05.11) if (Mathf.Abs(wheel) > 0.01f) Zoom(wheel * 0.1f); // Два пальца -- приближение, как на карте мира: расстояние камеры меняется во столько раз, diff --git a/Assets/Scripts/City3D/City3DController.cs b/Assets/Scripts/City3D/City3DController.cs index 36ca5d2..c0da680 100644 --- a/Assets/Scripts/City3D/City3DController.cs +++ b/Assets/Scripts/City3D/City3DController.cs @@ -695,7 +695,7 @@ public class City3DController : MonoBehaviour, City3DSave.ILive if (down) { - pointerOverGui = OverGui(pos) || UIBlocker.IsPointerOverUI(); // и кнопки/окна общего HUD + pointerOverGui = OverGui(pos) || City3DInput.OverHud(pos); // и кнопки/окна общего HUD if (pointerOverGui) return; pointerDown = pos; pointerMoved = false; diff --git a/Assets/Scripts/City3D/City3DInput.cs b/Assets/Scripts/City3D/City3DInput.cs new file mode 100644 index 0000000..e4e7ac4 --- /dev/null +++ b/Assets/Scripts/City3D/City3DInput.cs @@ -0,0 +1,66 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; + +// Палец над HUD в 3D-поселении (05.11): «над интерфейсом» -- только если под пальцем то, что нажимают или крутят +// (кнопка, поле, ползунок, прокручиваемое окно) или небольшая панель. Невидимый слой во весь экран +// (затемнение, контейнер безопасной зоны, фон) карту не блокирует -- иначе не работают ни тап, ни зум, ни стройка. +// Такой слой пишется в Console один раз, чтобы его можно было найти и убрать. +public static class City3DInput +{ + static readonly List hits = new List(); + static readonly HashSet reported = new HashSet(); + + public static bool OverHud(Vector2 screen) + { + var es = EventSystem.current; + if (es == null) return false; + // Открыто окно HUD (панель) -- весь ввод его, карта не трогается + if (UIPanelManager.Instance != null && UIPanelManager.Instance.CurrentId != "") + { + if (reported.Add("panel:" + UIPanelManager.Instance.CurrentId)) + Debug.Log($"[3D] Открыта панель HUD «{UIPanelManager.Instance.CurrentId}» -- 3D-карта не принимает нажатия, пока её не закрыть"); + return true; + } + hits.Clear(); + es.RaycastAll(new PointerEventData(es) { position = screen }, hits); + foreach (var h in hits) + { + if (h.gameObject == null) continue; + if (IsInteractive(h.gameObject) || !CoversScreen(h.gameObject)) return true; + if (reported.Add(h.gameObject.name)) + Debug.Log($"[3D] Слой интерфейса во весь экран ловит нажатия, 3D-карта его пропускает: «{Path(h.gameObject.transform)}». " + + "Если он не нужен -- выключить у него Raycast Target"); + } + return false; + } + + static bool IsInteractive(GameObject go) + { + // кнопки, прокрутка, поля, а также всё, что само ловит нажатие (затемнение модального окна закрывает его тапом) + return go.GetComponentInParent() != null || go.GetComponentInParent() != null + || go.GetComponentInParent() != null || go.GetComponentInParent() != null + || go.name == "Modal" || go.GetComponentInParent() != null; + } + + // Занимает почти весь экран (больше 80% по ширине и высоте) + static bool CoversScreen(GameObject go) + { + if (!(go.transform is RectTransform rt)) return false; + var corners = new Vector3[4]; + rt.GetWorldCorners(corners); + var canvas = go.GetComponentInParent(); + Camera cam = canvas != null && canvas.renderMode != RenderMode.ScreenSpaceOverlay ? canvas.worldCamera : null; + Vector2 a = RectTransformUtility.WorldToScreenPoint(cam, corners[0]); + Vector2 b = RectTransformUtility.WorldToScreenPoint(cam, corners[2]); + return Mathf.Abs(b.x - a.x) > Screen.width * 0.8f && Mathf.Abs(b.y - a.y) > Screen.height * 0.8f; + } + + static string Path(Transform t) + { + string p = t.name; + for (var x = t.parent; x != null; x = x.parent) p = x.name + "/" + p; + return p; + } +} diff --git a/Assets/Scripts/City3D/City3DInput.cs.meta b/Assets/Scripts/City3D/City3DInput.cs.meta new file mode 100644 index 0000000..bb13970 --- /dev/null +++ b/Assets/Scripts/City3D/City3DInput.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c71f24a7cb164064b98f198eec9665d3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: