Açıklama Yok
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ExtendedPointerEventData.cs 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. #if PACKAGE_DOCS_GENERATION || UNITY_INPUT_SYSTEM_ENABLE_UI
  2. using System.Text;
  3. using UnityEngine.EventSystems;
  4. using UnityEngine.InputSystem.Controls;
  5. using UnityEngine.InputSystem.Utilities;
  6. namespace UnityEngine.InputSystem.UI
  7. {
  8. /// <summary>
  9. /// An extension to <c>PointerEventData</c> which makes additional data about the input event available.
  10. /// </summary>
  11. /// <remarks>
  12. /// Instances of this class are sent instead of <see cref="PointerEventData"/> by <see cref="InputSystemUIInputModule"/>
  13. /// for all pointer-type input.
  14. ///
  15. /// The <see cref="PointerEventData.pointerId"/> property will generally correspond to the <see cref="InputDevice.deviceId"/>
  16. /// of <see cref="device"/>. An exception to this are touches as each <see cref="Touchscreen"/> may generate several pointers
  17. /// (one for each active finger).
  18. /// </remarks>
  19. public class ExtendedPointerEventData : PointerEventData
  20. {
  21. public ExtendedPointerEventData(EventSystem eventSystem)
  22. : base(eventSystem)
  23. {
  24. }
  25. /// <summary>
  26. /// The <see cref="InputControl"/> that generated the pointer input.
  27. /// The device associated with this control should be the same as this event's device.
  28. /// </summary>
  29. /// <seealso cref="device"/>
  30. public InputControl control { get; set; }
  31. /// <summary>
  32. /// The <see cref="InputDevice"/> that generated the pointer input.
  33. /// </summary>
  34. /// <seealso cref="Pointer"/>
  35. /// <seealso cref="Touchscreen"/>
  36. /// <seealso cref="Mouse"/>
  37. /// <seealso cref="Pen"/>
  38. public InputDevice device { get; set; }
  39. /// <summary>
  40. /// For <see cref="UIPointerType.Touch"/> type pointer input, this is the touch ID as reported by the
  41. /// <see cref="Touchscreen"/> device.
  42. /// </summary>
  43. /// <remarks>
  44. /// For pointer input that is not coming from touch, this will be 0 (which is not considered a valid touch ID
  45. /// by the input system).
  46. ///
  47. /// Note that for touch input, <see cref="PointerEventData.pointerId"/> will be a combination of the
  48. /// device ID of <see cref="device"/> and the touch ID to generate a unique pointer ID even if there
  49. /// are multiple touchscreens.
  50. /// </remarks>
  51. /// <seealso cref="TouchControl.touchId"/>
  52. public int touchId { get; set; }
  53. /// <summary>
  54. /// Type of pointer that generated the input.
  55. /// </summary>
  56. public UIPointerType pointerType { get; set; }
  57. public int uiToolkitPointerId { get; set; }
  58. /// <summary>
  59. /// For <see cref="UIPointerType.Tracked"/> type pointer input, this is the world-space position of
  60. /// the <see cref="TrackedDevice"/>.
  61. /// </summary>
  62. /// <seealso cref="InputSystemUIInputModule.trackedDevicePosition"/>
  63. public Vector3 trackedDevicePosition { get; set; }
  64. /// <summary>
  65. /// For <see cref="UIPointerType.Tracked"/> type pointer input, this is the world-space orientation of
  66. /// the <see cref="TrackedDevice"/>.
  67. /// </summary>
  68. /// <seealso cref="InputSystemUIInputModule.trackedDeviceOrientation"/>
  69. public Quaternion trackedDeviceOrientation { get; set; }
  70. public override string ToString()
  71. {
  72. var stringBuilder = new StringBuilder();
  73. stringBuilder.Append(base.ToString());
  74. stringBuilder.AppendLine("button: " + button); // Defined in PointerEventData but PointerEventData.ToString() does not include it.
  75. stringBuilder.AppendLine("clickTime: " + clickTime); // Same here.
  76. stringBuilder.AppendLine("clickCount: " + clickCount); // Same here.
  77. stringBuilder.AppendLine("device: " + device);
  78. stringBuilder.AppendLine("pointerType: " + pointerType);
  79. stringBuilder.AppendLine("touchId: " + touchId);
  80. stringBuilder.AppendLine("pressPosition: " + pressPosition);
  81. stringBuilder.AppendLine("trackedDevicePosition: " + trackedDevicePosition);
  82. stringBuilder.AppendLine("trackedDeviceOrientation: " + trackedDeviceOrientation);
  83. #if UNITY_2021_1_OR_NEWER
  84. stringBuilder.AppendLine("pressure" + pressure);
  85. stringBuilder.AppendLine("radius: " + radius);
  86. stringBuilder.AppendLine("azimuthAngle: " + azimuthAngle);
  87. stringBuilder.AppendLine("altitudeAngle: " + altitudeAngle);
  88. stringBuilder.AppendLine("twist: " + twist);
  89. #endif
  90. #if UNITY_2022_3_OR_NEWER
  91. stringBuilder.AppendLine("displayIndex: " + displayIndex);
  92. #endif
  93. return stringBuilder.ToString();
  94. }
  95. internal static int MakePointerIdForTouch(int deviceId, int touchId)
  96. {
  97. unchecked
  98. {
  99. return (deviceId << 24) + touchId;
  100. }
  101. }
  102. internal static int TouchIdFromPointerId(int pointerId)
  103. {
  104. return pointerId & 0xff;
  105. }
  106. ////TODO: add pressure and tilt support (probably add after 1.0; probably should have separate actions)
  107. /*
  108. /// <summary>
  109. /// If supported by the input device, this is the pressure level of the pointer contact. This is generally
  110. /// only supported by <see cref="Pen"/> devices as well as by <see cref="Touchscreen"/>s on phones. If not
  111. /// supported, this will be 1.
  112. /// </summary>
  113. /// <seealso cref="Pointer.pressure"/>
  114. public float pressure { get; set; }
  115. /// <summary>
  116. /// If the pointer input is coming from a <see cref="Pen"/>, this is pen's <see cref="Pen.tilt"/>.
  117. /// </summary>
  118. public Vector2 tilt { get; set; }
  119. */
  120. internal void ReadDeviceState()
  121. {
  122. if (control.parent is Pen pen)
  123. {
  124. uiToolkitPointerId = GetPenPointerId(pen);
  125. #if UNITY_2021_1_OR_NEWER
  126. pressure = pen.pressure.magnitude;
  127. azimuthAngle = (pen.tilt.value.x + 1) * Mathf.PI / 2;
  128. altitudeAngle = (pen.tilt.value.y + 1) * Mathf.PI / 2;
  129. twist = pen.twist.value * Mathf.PI * 2;
  130. #endif
  131. #if UNITY_2022_3_OR_NEWER
  132. displayIndex = pen.displayIndex.ReadValue();
  133. #endif
  134. }
  135. else if (control.parent is TouchControl touchControl)
  136. {
  137. uiToolkitPointerId = GetTouchPointerId(touchControl);
  138. #if UNITY_2021_1_OR_NEWER
  139. pressure = touchControl.pressure.magnitude;
  140. radius = touchControl.radius.value;
  141. #endif
  142. #if UNITY_2022_3_OR_NEWER
  143. displayIndex = touchControl.displayIndex.ReadValue();
  144. #endif
  145. }
  146. else if (control.parent is Touchscreen touchscreen)
  147. {
  148. uiToolkitPointerId = GetTouchPointerId(touchscreen.primaryTouch);
  149. #if UNITY_2021_1_OR_NEWER
  150. pressure = touchscreen.pressure.magnitude;
  151. radius = touchscreen.radius.value;
  152. #endif
  153. #if UNITY_2022_3_OR_NEWER
  154. displayIndex = touchscreen.displayIndex.ReadValue();
  155. #endif
  156. }
  157. else
  158. {
  159. uiToolkitPointerId = UIElements.PointerId.mousePointerId;
  160. }
  161. }
  162. private static int GetPenPointerId(Pen pen)
  163. {
  164. var n = 0;
  165. foreach (var otherDevice in InputSystem.devices)
  166. if (otherDevice is Pen otherPen)
  167. {
  168. if (pen == otherPen)
  169. {
  170. return UIElements.PointerId.penPointerIdBase +
  171. Mathf.Min(n, UIElements.PointerId.penPointerCount - 1);
  172. }
  173. n++;
  174. }
  175. return UIElements.PointerId.penPointerIdBase;
  176. }
  177. private static int GetTouchPointerId(TouchControl touchControl)
  178. {
  179. var i = ((Touchscreen)touchControl.device).touches.IndexOfReference(touchControl);
  180. return UIElements.PointerId.touchPointerIdBase +
  181. Mathf.Clamp(i, 0, UIElements.PointerId.touchPointerCount - 1);
  182. }
  183. }
  184. /// <summary>
  185. /// General type of pointer that generated a <see cref="PointerEventData"/> pointer event.
  186. /// </summary>
  187. public enum UIPointerType
  188. {
  189. None,
  190. /// <summary>
  191. /// A <see cref="Mouse"/> or <see cref="Pen"/> or other general <see cref="Pointer"/>.
  192. /// </summary>
  193. MouseOrPen,
  194. /// <summary>
  195. /// A <see cref="Touchscreen"/>.
  196. /// </summary>
  197. Touch,
  198. /// <summary>
  199. /// A <see cref="TrackedDevice"/>.
  200. /// </summary>
  201. Tracked,
  202. }
  203. /// <summary>
  204. /// Determine how the UI behaves in the presence of multiple pointer devices.
  205. /// </summary>
  206. /// <remarks>
  207. /// While running, an application may, for example, have both a <see cref="Mouse"/> and a <see cref="Touchscreen"/> device
  208. /// and both may end up getting bound to the actions of <see cref="InputSystemUIInputModule"/> and thus both may route
  209. /// input into the UI. When this happens, the pointer behavior decides how the UI input module resolves the ambiguity.
  210. /// </remarks>
  211. public enum UIPointerBehavior
  212. {
  213. /// <summary>
  214. /// Any input that isn't <see cref="Touchscreen"/> or <see cref="TrackedDevice"/> input is
  215. /// treated as a single unified pointer.
  216. ///
  217. /// This is the default behavior based on the expectation that mice and pens will generally drive a single on-screen
  218. /// cursor whereas touch and tracked devices have an inherent ability to generate multiple pointers.
  219. ///
  220. /// Note that when input from touch or tracked devices is received, the combined pointer for mice and pens (if it exists)
  221. /// will be removed. If it was over UI objects, <c>IPointerExitHandler</c>s will be invoked.
  222. /// </summary>
  223. SingleMouseOrPenButMultiTouchAndTrack,
  224. /// <summary>
  225. /// All input is unified to a single pointer. This means that all input from all pointing devices (<see cref="Mouse"/>,
  226. /// <see cref="Pen"/>, <see cref="Touchscreen"/>, and <see cref="TrackedDevice"/>) is routed into a single pointer
  227. /// instance. There is only one position on screen which can be controlled from any of these devices.
  228. /// </summary>
  229. SingleUnifiedPointer,
  230. /// <summary>
  231. /// Any pointing device, whether it's <see cref="Mouse"/>, <see cref="Pen"/>, <see cref="Touchscreen"/>,
  232. /// or <see cref="TrackedDevice"/> input, is treated as its own independent pointer and arbitrary many
  233. /// such pointers can be active at any one time.
  234. /// </summary>
  235. AllPointersAsIs,
  236. }
  237. }
  238. #endif