A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using System.Runtime.InteropServices;
4using UnityEngine.EventSystems;
5using UnityEngine.UI;
6
7namespace UnityEngine.UIElements
8{
9 // This code is disabled unless the UI Toolkit package or the com.unity.modules.uielements module are present.
10 // The UIElements module is always present in the Editor but it can be stripped from a project build if unused.
11#if PACKAGE_UITOOLKIT
12 /// <summary>
13 /// A derived BaseRaycaster to raycast against UI Toolkit panel instances at runtime.
14 /// </summary>
15 [AddComponentMenu("UI Toolkit/Panel Raycaster (UI Toolkit)")]
16 public class PanelRaycaster : BaseRaycaster, IRuntimePanelComponent
17 {
18 private BaseRuntimePanel m_Panel;
19
20 /// <summary>
21 /// The panel that this component relates to. If panel is null, this component will have no effect.
22 /// Will be set to null automatically if panel is Disposed from an external source.
23 /// </summary>
24 public IPanel panel
25 {
26 get => m_Panel;
27 set
28 {
29 var newPanel = (BaseRuntimePanel)value;
30 if (m_Panel != newPanel)
31 {
32 UnregisterCallbacks();
33 m_Panel = newPanel;
34 RegisterCallbacks();
35 }
36 }
37 }
38
39 void RegisterCallbacks()
40 {
41 if (m_Panel != null)
42 {
43 m_Panel.destroyed += OnPanelDestroyed;
44 }
45 }
46
47 void UnregisterCallbacks()
48 {
49 if (m_Panel != null)
50 {
51 m_Panel.destroyed -= OnPanelDestroyed;
52 }
53 }
54
55 void OnPanelDestroyed()
56 {
57 panel = null;
58 }
59
60 private GameObject selectableGameObject => m_Panel?.selectableGameObject;
61
62 public override int sortOrderPriority => Mathf.FloorToInt(m_Panel?.sortingPriority ?? 0f);
63 public override int renderOrderPriority => int.MaxValue - (UIElementsRuntimeUtility.s_ResolvedSortingIndexMax - (m_Panel?.resolvedSortingIndex ?? 0));
64
65 public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList)
66 {
67 if (m_Panel == null)
68 return;
69
70 var displayIndex = m_Panel.targetDisplay;
71
72 Vector3 eventPosition = MultipleDisplayUtilities.GetRelativeMousePositionForRaycast(eventData);
73
74 // Discard events that are not part of this display so the user does not interact with multiple displays at once.
75 if ((int) eventPosition.z != displayIndex)
76 return;
77
78 var position = eventPosition;
79 var delta = eventData.delta;
80
81 float h = Screen.height;
82 if (displayIndex > 0 && displayIndex < Display.displays.Length)
83 {
84 h = Display.displays[displayIndex].systemHeight;
85 }
86
87 position.y = h - position.y;
88 delta.y = -delta.y;
89
90 var eventSystem = UIElementsRuntimeUtility.activeEventSystem as EventSystem;
91 if (eventSystem == null || eventSystem.currentInputModule == null)
92 return;
93 var pointerId = eventSystem.currentInputModule.ConvertUIToolkitPointerId(eventData);
94
95 var capturingElement = m_Panel.GetCapturingElement(pointerId);
96 if (capturingElement is VisualElement ve && ve.panel != m_Panel)
97 return;
98
99 var capturingPanel = PointerDeviceState.GetPlayerPanelWithSoftPointerCapture(pointerId);
100 if (capturingPanel != null && capturingPanel != m_Panel)
101 return;
102
103 if (capturingElement == null && capturingPanel == null)
104 {
105 if (!m_Panel.ScreenToPanel(position, delta, out var panelPosition, out _))
106 return;
107
108 var pick = m_Panel.Pick(panelPosition);
109 if (pick == null)
110 return;
111 }
112
113 resultAppendList.Add(new RaycastResult
114 {
115 gameObject = selectableGameObject,
116 module = this,
117 screenPosition = eventPosition,
118 displayIndex = m_Panel.targetDisplay,
119 });
120 }
121
122 public override Camera eventCamera => null;
123 }
124#endif
125}