123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- using System;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using UnityEngine.EventSystems;
-
- namespace UnityEngine.UIElements
- {
- #if PACKAGE_UITOOLKIT
- /// <summary>
- /// A derived BaseRaycaster to raycast against UI Toolkit panel instances at runtime.
- /// </summary>
- [AddComponentMenu("UI Toolkit/Panel Raycaster (UI Toolkit)")]
- public class PanelRaycaster : BaseRaycaster, IRuntimePanelComponent
- {
- private BaseRuntimePanel m_Panel;
-
- /// <summary>
- /// The panel that this component relates to. If panel is null, this component will have no effect.
- /// Will be set to null automatically if panel is Disposed from an external source.
- /// </summary>
- public IPanel panel
- {
- get => m_Panel;
- set
- {
- var newPanel = (BaseRuntimePanel)value;
- if (m_Panel != newPanel)
- {
- UnregisterCallbacks();
- m_Panel = newPanel;
- RegisterCallbacks();
- }
- }
- }
-
- void RegisterCallbacks()
- {
- if (m_Panel != null)
- {
- m_Panel.destroyed += OnPanelDestroyed;
- }
- }
-
- void UnregisterCallbacks()
- {
- if (m_Panel != null)
- {
- m_Panel.destroyed -= OnPanelDestroyed;
- }
- }
-
- void OnPanelDestroyed()
- {
- panel = null;
- }
-
- private GameObject selectableGameObject => m_Panel?.selectableGameObject;
-
- public override int sortOrderPriority => (int)(m_Panel?.sortingPriority ?? 0f);
- public override int renderOrderPriority => ConvertFloatBitsToInt(m_Panel?.sortingPriority ?? 0f);
-
- public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList)
- {
- if (m_Panel == null)
- return;
-
- var eventPosition = Display.RelativeMouseAt(eventData.position);
- var displayIndex = m_Panel.targetDisplay;
-
- var originalEventPosition = eventPosition;
- if (eventPosition != Vector3.zero)
- {
- // We support multiple display and display identification based on event position.
-
- int eventDisplayIndex = (int)eventPosition.z;
-
- // Discard events that are not part of this display so the user does not interact with multiple displays at once.
- if (eventDisplayIndex != displayIndex)
- return;
- }
- else
- {
- // The multiple display system is not supported on all platforms, when it is not supported the returned position
- // will be all zeros so when the returned index is 0 we will default to the event data to be safe.
- eventPosition = eventData.position;
- #if UNITY_EDITOR
- if (Display.activeEditorGameViewTarget != displayIndex)
- return;
- eventPosition.z = Display.activeEditorGameViewTarget;
- #endif
-
- // We don't really know in which display the event occurred. We will process the event assuming it occurred in our display.
- }
-
- var position = eventPosition;
- var delta = eventData.delta;
-
- float h = Screen.height;
- if (displayIndex > 0 && displayIndex < Display.displays.Length)
- {
- h = Display.displays[displayIndex].systemHeight;
- }
-
- position.y = h - position.y;
- delta.y = -delta.y;
-
- var eventSystem = UIElementsRuntimeUtility.activeEventSystem as EventSystem;
- var pointerId = eventSystem.currentInputModule.ConvertUIToolkitPointerId(eventData);
-
- var capturingElement = m_Panel.GetCapturingElement(pointerId);
- if (capturingElement is VisualElement ve && ve.panel != m_Panel)
- return;
-
- var capturingPanel = PointerDeviceState.GetPressedButtons(pointerId) != 0 ?
- PointerDeviceState.GetPlayerPanelWithSoftPointerCapture(pointerId) :
- null;
- if (capturingPanel != null && capturingPanel != m_Panel)
- return;
-
- if (capturingElement == null && capturingPanel == null)
- {
- if (!m_Panel.ScreenToPanel(position, delta, out var panelPosition, out _))
- return;
-
- var pick = m_Panel.Pick(panelPosition);
- if (pick == null)
- return;
- }
-
- resultAppendList.Add(new RaycastResult
- {
- gameObject = selectableGameObject,
- module = this,
- screenPosition = eventPosition,
- displayIndex = m_Panel.targetDisplay,
- });
- }
-
- public override Camera eventCamera => null;
-
-
- [StructLayout(LayoutKind.Explicit, Size = sizeof(int))]
- private struct FloatIntBits
- {
- [FieldOffset(0)]
- public float f;
- [FieldOffset(0)]
- public int i;
- }
-
- private static int ConvertFloatBitsToInt(float f)
- {
- FloatIntBits bits = new FloatIntBits {f = f};
- return bits.i;
- }
- }
- #endif
- }
|