using System; using RPGCoreCommon.Settings; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.UIElements; using Object = UnityEngine.Object; namespace RPGCoreCommon.Select { public static class Select { private static IRuntimePanel _panel; private static IRuntimePanel GetPanel() { if (_panel != null) return _panel; const string documentUITag = "MainUIDocument"; UIDocument uiDocument = null; try { // FIND BY TAG var go = GameObject.FindWithTag(documentUITag); if (go) uiDocument = go.GetComponent(); } catch (UnityException) { Debug.LogError($"Tag {documentUITag} not found! Please add it to the project."); } // FIND ANY UI DOCUMENT if (!uiDocument) { Debug.LogWarning($"Found no {nameof(UIDocument)} with tag '{documentUITag}', started looking for any on scene..."); uiDocument = Object.FindAnyObjectByType(); } // PANEL NOT FOUND if (!uiDocument) { Debug.LogError($"Current scene has no {nameof(UIDocument)}! {nameof(Select)} won't work with UI!"); return null; } _panel = uiDocument.runtimePanel; return _panel; } /// Get and if nothing selected then get instead. public static SelectUtilResult Get() { if (GetFromUI() is { hit: SelectType.UI } fromUI) return fromUI; if (GetFromScene() is { hit: SelectType.Scene } fromScene) return fromScene; return new SelectUtilResult(); } /// Try to select anything from given position on UI that extends public static SelectUtilResult GetFromUI() { var mousePos = Mouse.current.position.ReadValue(); mousePos.y = Screen.height - mousePos.y; var mousePosOnUI = RuntimePanelUtils.ScreenToPanel(GetPanel(), mousePos); return new SelectUtilResult(mousePosOnUI, GetPanel().Pick(mousePosOnUI)); } /// /// TComponent is by default if not provided.
/// ///
public static SelectUtilResult GetFromScene() { return GetFromScene(); } /// /// Try to select with component of given type '' in self or in any parent. /// If not found then gets 's . /// /// Type of component to look for public static SelectUtilResult GetFromScene() where TComponent : Component { var hit = SelectHit(); // Nothing hit - clicked void? if (!hit.collider) return new SelectUtilResult(); var component = hit.collider.gameObject.GetComponentInParent(); // Wanted component not found - get GameObject from Collider if (!component) return new SelectUtilResult(hit.point, hit.collider.gameObject); return new SelectUtilResult(hit.point, component.gameObject, component); } /// Returns Vector3 of clicked position public static Vector3 SelectPosition() { return SelectHit().point; } /// Returns of clicked position public static RaycastHit SelectHit() { Physics.Raycast( Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue()), out var hit, Mathf.Infinity, SettingsManager.Get().collisionLayerMask); return hit; } } }