init
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user