123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- #if UNITY_INPUT_SYSTEM_ENABLE_UI
- using UnityEngine.EventSystems;
-
- namespace UnityEngine.InputSystem.UI
- {
- // A pointer is identified by a single unique integer ID. It has an associated position and the ability to press
- // on up to three buttons. It can also scroll.
- //
- // There's a single ExtendedPointerEventData instance allocated for the pointer which is used to retain the pointer's
- // event state. As part of that state is specific to button presses, each button retains a partial copy of press-specific
- // event information.
- //
- // A pointer can operate in 2D (mouse, pen, touch) or 3D (tracked). For 3D, screen-space 2D positions are derived
- // via raycasts based on world-space position and orientation.
- internal struct PointerModel
- {
- public bool changedThisFrame;
- public UIPointerType pointerType => eventData.pointerType;
-
- public Vector2 screenPosition
- {
- get => m_ScreenPosition;
- set
- {
- if (m_ScreenPosition != value)
- {
- m_ScreenPosition = value;
- changedThisFrame = true;
- }
- }
- }
-
- public Vector3 worldPosition
- {
- get => m_WorldPosition;
- set
- {
- if (m_WorldPosition != value)
- {
- m_WorldPosition = value;
- changedThisFrame = true;
- }
- }
- }
-
- public Quaternion worldOrientation
- {
- get => m_WorldOrientation;
- set
- {
- if (m_WorldOrientation != value)
- {
- m_WorldOrientation = value;
- changedThisFrame = true;
- }
- }
- }
-
- public Vector2 scrollDelta
- {
- get => m_ScrollDelta;
- set
- {
- if (m_ScrollDelta != value)
- {
- changedThisFrame = true;
- m_ScrollDelta = value;
- }
- }
- }
-
- public float pressure
- {
- get => m_Pressure;
- set
- {
- if (m_Pressure != value)
- {
- changedThisFrame = true;
- m_Pressure = value;
- }
- }
- }
-
- public float azimuthAngle
- {
- get => m_AzimuthAngle;
- set
- {
- if (m_AzimuthAngle != value)
- {
- changedThisFrame = true;
- m_AzimuthAngle = value;
- }
- }
- }
-
- public float altitudeAngle
- {
- get => m_AltitudeAngle;
- set
- {
- if (m_AltitudeAngle != value)
- {
- changedThisFrame = true;
- m_AltitudeAngle = value;
- }
- }
- }
-
- public float twist
- {
- get => m_Twist;
- set
- {
- if (m_Twist != value)
- {
- changedThisFrame = true;
- m_Twist = value;
- }
- }
- }
-
- public Vector2 radius
- {
- get => m_Radius;
- set
- {
- if (m_Radius != value)
- {
- changedThisFrame = true;
- m_Radius = value;
- }
- }
- }
-
- public ButtonState leftButton;
- public ButtonState rightButton;
- public ButtonState middleButton;
- public ExtendedPointerEventData eventData;
-
- public PointerModel(ExtendedPointerEventData eventData)
- {
- this.eventData = eventData;
-
- changedThisFrame = false;
-
- leftButton = default; leftButton.OnEndFrame();
- rightButton = default; rightButton.OnEndFrame();
- middleButton = default; middleButton.OnEndFrame();
-
- m_ScreenPosition = default;
- m_ScrollDelta = default;
- m_WorldOrientation = default;
- m_WorldPosition = default;
-
- m_Pressure = default;
- m_AzimuthAngle = default;
- m_AltitudeAngle = default;
- m_Twist = default;
- m_Radius = default;
- }
-
- public void OnFrameFinished()
- {
- changedThisFrame = false;
- scrollDelta = default;
- leftButton.OnEndFrame();
- rightButton.OnEndFrame();
- middleButton.OnEndFrame();
- }
-
- private Vector2 m_ScreenPosition;
- private Vector2 m_ScrollDelta;
- private Vector3 m_WorldPosition;
- private Quaternion m_WorldOrientation;
-
- private float m_Pressure;
- private float m_AzimuthAngle;
- private float m_AltitudeAngle;
- private float m_Twist;
- private Vector2 m_Radius;
-
- public void CopyTouchOrPenStateFrom(PointerEventData eventData)
- {
- #if UNITY_2021_1_OR_NEWER
- pressure = eventData.pressure;
- azimuthAngle = eventData.azimuthAngle;
- altitudeAngle = eventData.altitudeAngle;
- twist = eventData.twist;
- radius = eventData.radius;
- #endif
- }
-
- // State related to pressing and releasing individual bodies. Retains those parts of
- // PointerInputEvent that are specific to presses and releases.
- public struct ButtonState
- {
- private bool m_IsPressed;
- private PointerEventData.FramePressState m_FramePressState;
- private float m_PressTime;
-
- public bool isPressed
- {
- get => m_IsPressed;
- set
- {
- if (m_IsPressed != value)
- {
- m_IsPressed = value;
-
- if (m_FramePressState == PointerEventData.FramePressState.NotChanged && value)
- m_FramePressState = PointerEventData.FramePressState.Pressed;
- else if (m_FramePressState == PointerEventData.FramePressState.NotChanged && !value)
- m_FramePressState = PointerEventData.FramePressState.Released;
- else if (m_FramePressState == PointerEventData.FramePressState.Pressed && !value)
- m_FramePressState = PointerEventData.FramePressState.PressedAndReleased;
- }
- }
- }
-
- /// <summary>
- /// When we "release" a button other than through user interaction (e.g. through focus switching),
- /// we don't want this to count as an actual release that ends up clicking. This flag will cause
- /// generated events to have <c>eligibleForClick</c> to be false.
- /// </summary>
- public bool ignoreNextClick
- {
- get => m_IgnoreNextClick;
- set => m_IgnoreNextClick = value;
- }
-
- public float pressTime
- {
- get => m_PressTime;
- set => m_PressTime = value;
- }
-
- public bool clickedOnSameGameObject
- {
- get => m_ClickedOnSameGameObject;
- set => m_ClickedOnSameGameObject = value;
- }
-
- public bool wasPressedThisFrame => m_FramePressState == PointerEventData.FramePressState.Pressed ||
- m_FramePressState == PointerEventData.FramePressState.PressedAndReleased;
- public bool wasReleasedThisFrame => m_FramePressState == PointerEventData.FramePressState.Released ||
- m_FramePressState == PointerEventData.FramePressState.PressedAndReleased;
-
- private RaycastResult m_PressRaycast;
- private GameObject m_PressObject;
- private GameObject m_RawPressObject;
- private GameObject m_LastPressObject;
- private GameObject m_DragObject;
- private Vector2 m_PressPosition;
- private float m_ClickTime; // On Time.unscaledTime timeline, NOT input event time.
- private int m_ClickCount;
- private bool m_Dragging;
- private bool m_ClickedOnSameGameObject;
- private bool m_IgnoreNextClick;
-
- public void CopyPressStateTo(PointerEventData eventData)
- {
- eventData.pointerPressRaycast = m_PressRaycast;
- eventData.pressPosition = m_PressPosition;
- eventData.clickCount = m_ClickCount;
- eventData.clickTime = m_ClickTime;
- // We can't set lastPress directly. Old input module uses three different event instances, one for each
- // button. We share one instance and just switch press states. Set pointerPress twice to get the lastPress
- // we need.
- //
- // NOTE: This does *NOT* quite work as stated in the docs. pointerPress is nulled out on button release which
- // will set lastPress as a side-effect. This means that lastPress will only be non-null while no press is
- // going on and will *NOT* refer to the last pressed object when a new object has been pressed on.
- eventData.pointerPress = m_LastPressObject;
- eventData.pointerPress = m_PressObject;
- eventData.rawPointerPress = m_RawPressObject;
- eventData.pointerDrag = m_DragObject;
- eventData.dragging = m_Dragging;
-
- if (ignoreNextClick)
- eventData.eligibleForClick = false;
- }
-
- public void CopyPressStateFrom(PointerEventData eventData)
- {
- m_PressRaycast = eventData.pointerPressRaycast;
- m_PressObject = eventData.pointerPress;
- m_RawPressObject = eventData.rawPointerPress;
- m_LastPressObject = eventData.lastPress;
- m_PressPosition = eventData.pressPosition;
- m_ClickTime = eventData.clickTime;
- m_ClickCount = eventData.clickCount;
- m_DragObject = eventData.pointerDrag;
- m_Dragging = eventData.dragging;
- }
-
- public void OnEndFrame()
- {
- m_FramePressState = PointerEventData.FramePressState.NotChanged;
- }
- }
- }
- }
- #endif
|