112 lines
4.5 KiB
C#
112 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Sirenix.OdinInspector;
|
|
using Sirenix.Utilities;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace VOID.UserInterface
|
|
{
|
|
[DefaultExecutionOrder(-1)]
|
|
public class GameUI : MonoBehaviour
|
|
{
|
|
public static GameUI current { get; private set; }
|
|
|
|
[Title("Generic Templates:")]
|
|
public VisualTreeAsset slotTemplate => _slotTemplate;
|
|
public VisualTreeAsset statusTemplate => _statusTemplate;
|
|
public VisualTreeAsset unitPortraitTemplate => _unitPortraitTemplate;
|
|
public VisualTreeAsset levelUpOptionTemplate => _levelUpOptionTemplate;
|
|
public VisualTreeAsset profileTemplate => _profileTemplate;
|
|
[SerializeField, Required] private VisualTreeAsset _slotTemplate;
|
|
[SerializeField, Required] private VisualTreeAsset _statusTemplate;
|
|
[SerializeField, Required] private VisualTreeAsset _unitPortraitTemplate;
|
|
[SerializeField, Required] private VisualTreeAsset _levelUpOptionTemplate;
|
|
[SerializeField, Required] private VisualTreeAsset _profileTemplate;
|
|
|
|
private VisualElement _rootVisualElement;
|
|
public IPanel runtimePanel { get; private set; }
|
|
public PanelSettings panelSettings { get; private set; }
|
|
public Vector2 cursorPositionOnUI { get; private set; }
|
|
public bool isCursorOverUI { get; private set; }
|
|
public float scale { get; private set; }
|
|
|
|
// Visual elements under cursor + event when Visual element under cursor changes
|
|
public readonly List<VisualElement> elementsUnderCursor = new();
|
|
public event Action ElementsUnderCursorChanged;
|
|
|
|
private void Awake()
|
|
{
|
|
current = this;
|
|
var uiDocument = gameObject.GetComponent<UIDocument>();
|
|
_rootVisualElement = uiDocument.rootVisualElement;
|
|
panelSettings = uiDocument.panelSettings;
|
|
runtimePanel = _rootVisualElement.panel;
|
|
CalculateScale();
|
|
}
|
|
|
|
public VisualElement PickTopElementUI(List<VisualElement> cachedElements = null)
|
|
{
|
|
return (cachedElements ?? elementsUnderCursor).FirstOrDefault();
|
|
}
|
|
|
|
public T PickComponentUI<T>(List<VisualElement> cachedElements = null)
|
|
{
|
|
return (cachedElements ?? elementsUnderCursor).Select(el => el.dataSource).FilterCast<T>().FirstOrDefault();
|
|
}
|
|
|
|
public T PickTopComponentUI<T>(List<VisualElement> cachedElements = null)
|
|
{
|
|
return PickTopComponentUI(cachedElements) is T dataSource ? dataSource : default;
|
|
}
|
|
|
|
public object PickTopComponentUI(List<VisualElement> cachedElements = null)
|
|
{
|
|
return PickTopElementUI(cachedElements)?.dataSource;
|
|
}
|
|
|
|
private void CalculateScale()
|
|
{
|
|
var screenSize = new Vector2(Screen.width, Screen.height);
|
|
var referenceScreenSize = panelSettings.referenceResolution;
|
|
var proportions = referenceScreenSize / screenSize;
|
|
scale = proportions.x * panelSettings.match + proportions.y * (1f - panelSettings.match);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
FindCursorPositionOnUI();
|
|
FindElementsUnderCursor();
|
|
|
|
isCursorOverUI = !elementsUnderCursor.IsNullOrEmpty();
|
|
}
|
|
|
|
private void FindCursorPositionOnUI()
|
|
{
|
|
var mousePos = Mouse.current.position.ReadValue();
|
|
mousePos.y = Screen.height - mousePos.y;
|
|
cursorPositionOnUI = RuntimePanelUtils.ScreenToPanel(runtimePanel, mousePos);
|
|
}
|
|
|
|
private void FindElementsUnderCursor()
|
|
{
|
|
var previousTopElement = elementsUnderCursor.FirstOrDefault();
|
|
var currentTopElement = _rootVisualElement.panel.Pick(cursorPositionOnUI);
|
|
|
|
elementsUnderCursor.Clear();
|
|
|
|
// Find all "touchable" elements in UI under cursor - those with PickingMode.Position
|
|
// Move through parents (in case when position absolute is used)
|
|
var element = currentTopElement;
|
|
while (element != null)
|
|
{
|
|
if (element.pickingMode is PickingMode.Position) elementsUnderCursor.Add(element);
|
|
element = element.parent;
|
|
}
|
|
|
|
if (previousTopElement != currentTopElement) ElementsUnderCursorChanged?.Invoke();
|
|
}
|
|
}
|
|
} |