diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/EnhancedTouch/Touch.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/EnhancedTouch/Touch.cs index 096f8c9659..32b02471ac 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/EnhancedTouch/Touch.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/EnhancedTouch/Touch.cs @@ -22,7 +22,7 @@ namespace UnityEngine.InputSystem.EnhancedTouch /// and touch phases () in order to tell one touch apart from another. /// /// Also, this class protects against losing touches. If a touch is shorter-lived than a single input update, - /// may overwrite it with a new touch coming in in the same update whereas this class + /// may overwrite it with a new touch coming in the same update whereas this class /// will retain all changes that happened on the touchscreen in any particular update. /// /// The API makes a distinction between "fingers" and "touches". A touch refers to one contact state change event, that is, a @@ -33,6 +33,52 @@ namespace UnityEngine.InputSystem.EnhancedTouch /// A Touch instance is a struct which only contains a reference to the actual data which is stored in unmanaged /// memory. /// + /// + /// + /// using UnityEngine; + /// using UnityEngine.InputSystem.EnhancedTouch; + /// + /// // Alias EnhancedTouch.Touch to "Touch" for less typing. + /// using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch; + /// using TouchPhase = UnityEngine.InputSystem.TouchPhase; + /// + /// public class Example : MonoBehaviour + /// { + /// void Awake() + /// { + /// // Note that enhanced touch support needs to be explicitly enabled. + /// EnhancedTouchSupport.Enable(); + /// } + /// + /// void Update() + /// { + /// // Illustrates how to examine all active touches once per frame and show their last recorded position + /// // in the associated screen-space. + /// foreach (var touch in Touch.activeTouches) + /// { + /// switch (touch.phase) + /// { + /// case TouchPhase.Began: + /// Debug.Log($"Frame {Time.frameCount}: Touch {touch} started this frame at ({touch.screenPosition.x}, {touch.screenPosition.y})"); + /// break; + /// case TouchPhase.Ended: + /// Debug.Log($"Frame {Time.frameCount}:Touch {touch} ended this frame at ({touch.screenPosition.x}, {touch.screenPosition.y})"); + /// break; + /// case TouchPhase.Moved: + /// Debug.Log($"Frame {Time.frameCount}: Touch {touch} moved this frame to ({touch.screenPosition.x}, {touch.screenPosition.y})"); + /// break; + /// case TouchPhase.Canceled: + /// Debug.Log($"Frame {Time.frameCount}: Touch {touch} was canceled this frame"); + /// break; + /// case TouchPhase.Stationary: + /// Debug.Log($"Frame {Time.frameCount}: ouch {touch} was not updated this frame"); + /// break; + /// } + /// } + /// } + /// } + /// + /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces")] public struct Touch : IEquatable { @@ -42,132 +88,148 @@ public struct Touch : IEquatable /// /// Whether this touch record holds valid data. /// - /// If true, the data contained in the touch is valid. /// + /// /// Touch data is stored in unmanaged memory as a circular input buffer. This means that when /// the buffer runs out of capacity, older touch entries will get reused. When this happens, /// existing Touch instances referring to the record become invalid. - /// + /// + /// /// This property can be used to determine whether the record held on to by the Touch /// instance is still valid. - /// + /// + /// /// This property will be false for default-initialized Touch instances. - /// + /// + /// /// Note that accessing most of the other properties on this struct when the touch is - /// invalid will trigger InvalidOperationException. + /// invalid will trigger . + /// /// public bool valid => m_TouchRecord.valid; /// - /// The finger used for the touch contact. Null only for default-initialized - /// instances of the struct. + /// The finger used for the touch contact. /// - /// Finger used for the touch contact. - /// + /// + /// + /// Note that this is only null for default-initialized instances of the struct. + /// + /// + /// See for how to access all active fingers. + /// + /// public Finger finger => m_Finger; /// - /// Current phase of the touch. + /// The current touch phase of the touch indicating its current state in the phase cycle. /// - /// Current phase of the touch. /// + /// /// Every touch goes through a predefined cycle that starts with , /// then potentially and/or , /// and finally concludes with either or . - /// - /// This property indicates where in the cycle the touch is. + /// + /// + /// This property indicates where in the cycle the touch is and is based on . + /// + /// + /// Use to more conveniently evaluate whether this touch is currently active or not. + /// /// - /// - /// public TouchPhase phase => state.phase; /// /// Whether the touch has begun this frame, i.e. whether is . /// - /// - /// - /// + /// + /// Use to more conveniently evaluate whether this touch is currently active or not. + /// public bool began => phase == TouchPhase.Began; /// /// Whether the touch is currently in progress, i.e. whether is either /// , , or . /// - /// - /// - /// public bool inProgress => phase == TouchPhase.Moved || phase == TouchPhase.Stationary || phase == TouchPhase.Began; /// /// Whether the touch has ended this frame, i.e. whether is either /// or . /// - /// - /// - /// + /// + /// Use to more conveniently evaluate whether this touch is currently active or not. + /// public bool ended => phase == TouchPhase.Ended || phase == TouchPhase.Canceled; /// /// Unique ID of the touch as (usually) assigned by the platform. /// - /// Unique, non-zero ID of the touch. /// - /// Each touch contact that is made with the screen receives its own unique ID which is - /// normally assigned by the underlying platform. - /// + /// + /// Each touch contact that is made with the screen receives its own unique, non-zero ID which is + /// normally assigned by the underlying platform via . + /// + /// /// Note a platform may reuse touch IDs after their respective touches have finished. /// This means that the guarantee of uniqueness is only made with respect to . - /// + /// + /// /// In particular, all touches in will have the same ID whereas - /// touches in the a finger's may end up having the same + /// touches in the finger's may end up having the same /// touch ID even though constituting different physical touch contacts. + /// /// - /// public int touchId => state.touchId; /// /// Normalized pressure of the touch against the touch surface. /// - /// Pressure level of the touch. /// + /// /// Not all touchscreens are pressure-sensitive. If unsupported, this property will /// always return 0. - /// + /// + /// /// In general, touch pressure is supported on mobile platforms only. - /// + /// + /// + /// Touch pressure may also be retrieved directly from the device control via . + /// + /// /// Note that it is possible for the value to go above 1 even though it is considered normalized. The reason is /// that calibration on the system can put the maximum pressure point below the physically supported maximum value. + /// /// - /// public float pressure => state.pressure; /// - /// Screen-space radius of the touch. + /// Screen-space radius of the touch which define its horizontal and vertical extents. /// - /// Horizontal and vertical extents of the touch contact. /// + /// /// If supported by the underlying device, this reports the size of the touch contact based on its /// center point. If not supported, this will be default(Vector2). + /// + /// + /// Touch radius may also be retrieved directly from the device control via . + /// /// - /// public Vector2 radius => state.radius; /// - /// Time in seconds on the same timeline as Time.realTimeSinceStartup when the touch began. + /// Start time of the touch in seconds on the same timeline as Time.realTimeSinceStartup. /// - /// Start time of the touch. /// /// This is the value of when the touch started with - /// . + /// . Note that start time may also be retrieved directly + /// from the device control via . /// - /// public double startTime => state.startTime; /// - /// Time in seconds on the same timeline as Time.realTimeSinceStartup when the touch record was - /// reported. + /// Time the touch record was reported on the same timeline as . /// - /// Time the touch record was reported. /// /// This is the value of the event that signaled the current state /// change for the touch. @@ -175,34 +237,36 @@ public struct Touch : IEquatable public double time => m_TouchRecord.time; /// - /// The touchscreen on which the touch occurred. + /// The associated with the touch contact. /// - /// Touchscreen associated with the touch. public Touchscreen screen => finger.screen; /// /// Screen-space position of the touch. /// - /// Screen-space position of the touch. - /// + /// Also see for retrieving position directly from a device + /// control. public Vector2 screenPosition => state.position; /// /// Screen-space position where the touch started. /// - /// Start position of the touch. - /// + /// Also see for retrieving start position directly from + /// a device control. public Vector2 startScreenPosition => state.startPosition; /// /// Screen-space motion delta of the touch. /// - /// Screen-space motion delta of the touch. /// + /// /// Note that deltas have behaviors attached to them different from most other /// controls. See for details. + /// + /// + /// Also see for retrieving delta directly from a device control. + /// /// - /// public Vector2 delta => state.delta; /// @@ -210,12 +274,16 @@ public struct Touch : IEquatable /// /// Indicates how many taps have been performed one after the other. /// + /// /// Successive taps have to come within for them /// to increase the tap count. I.e. if a new tap finishes within that time after /// of the previous touch, the tap count is increased by one. If more than /// passes after a tap with no successive tap, the tap count is reset to zero. + /// + /// + /// Also see for retrieving tap count directly from a device control. + /// /// - /// public int tapCount => state.tapCount; /// @@ -223,31 +291,42 @@ public struct Touch : IEquatable /// /// Indicates whether the touch has tapped the screen. /// + /// /// A tap is defined as a touch that begins and ends within and /// stays within of its . If this /// is the case for a touch, this button is set to 1 at the time the touch goes to /// . - /// + /// + /// /// Resets to 0 only when another touch is started on the control or when the control is reset. + /// + /// + /// Use to determine if there were multiple taps occurring during the frame. + /// Also note that may be used to determine whether there was a tap. + /// /// - /// - /// - /// public bool isTap => state.isTap; /// /// The index of the display containing the touch. /// - /// A zero based number representing the display index containing the touch. - /// - /// + /// + /// + /// A zero based number representing the display index of the that contains the touch. + /// + /// + /// Also see for retrieving display index directly from a device + /// control. + /// + /// public int displayIndex => state.displayIndex; /// - /// Whether the touch is currently in progress, i.e. has a of - /// , , or . + /// Whether the touch is currently in progress. /// - /// Whether the touch is currently ongoing. + /// This is effectively equivalent to checking if is equal to either of: + /// , , or . + /// public bool isInProgress { get @@ -271,7 +350,7 @@ public bool isInProgress ref *(ExtraDataPerTouchState*)m_TouchRecord.GetUnsafeExtraMemoryPtr(); /// - /// History for this specific touch. + /// History touch readings for this specific touch contact. /// /// /// Unlike , this gives the history of this touch only. @@ -287,7 +366,7 @@ public TouchHistory history } /// - /// All touches that are either on-going as of the current frame or have ended in the current frame. + /// All touches that are either ongoing as of the current frame or have ended in the current frame. /// /// /// A touch that begins in a frame will always have its phase set to even @@ -304,7 +383,7 @@ public TouchHistory history /// case will be instead of ). /// /// Note that the touches reported by this API do not necessarily have to match the contents of - /// UnityEngine.Input.touches. + /// UnityEngine.Input.touches. /// The reason for this is that the UnityEngine.Input API and the Input System API flush their input /// queues at different points in time and may thus have a different view on available input. In particular, /// the Input System event queue is flushed later in the frame than inputs for UnityEngine.Input @@ -313,27 +392,55 @@ public TouchHistory history /// Due to this setup, touch events that will reach UnityEngine.Input only in the next frame may have /// already reached the Input System. /// + /// In order to evaluate all active touches on a per-frame basis see . + /// /// /// - /// void Awake() - /// { - /// // Enable EnhancedTouch. - /// EnhancedTouchSupport.Enable(); - /// } + /// using UnityEngine; + /// using UnityEngine.InputSystem.EnhancedTouch; + /// + /// // Alias EnhancedTouch.Touch to "Touch" for less typing. + /// using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch; + /// using TouchPhase = UnityEngine.InputSystem.TouchPhase; /// - /// void Update() + /// public class Example : MonoBehaviour /// { - /// foreach (var touch in Touch.activeTouches) - /// if (touch.began) - /// Debug.Log($"Touch {touch} started this frame"); - /// else if (touch.ended) - /// Debug.Log($"Touch {touch} ended this frame"); + /// void Awake() + /// { + /// // Note that enhanced touch support needs to be explicitly enabled. + /// EnhancedTouchSupport.Enable(); + /// } + /// + /// void Update() + /// { + /// // Illustrates how to examine all active touches once per frame and show their last recorded position + /// // in the associated screen-space. + /// foreach (var touch in Touch.activeTouches) + /// { + /// switch (touch.phase) + /// { + /// case TouchPhase.Began: + /// Debug.Log($"Frame {Time.frameCount}: Touch {touch} started this frame at ({touch.screenPosition.x}, {touch.screenPosition.y})"); + /// break; + /// case TouchPhase.Ended: + /// Debug.Log($"Frame {Time.frameCount}:Touch {touch} ended this frame at ({touch.screenPosition.x}, {touch.screenPosition.y})"); + /// break; + /// case TouchPhase.Moved: + /// Debug.Log($"Frame {Time.frameCount}: Touch {touch} moved this frame to ({touch.screenPosition.x}, {touch.screenPosition.y})"); + /// break; + /// case TouchPhase.Canceled: + /// Debug.Log($"Frame {Time.frameCount}: Touch {touch} was canceled this frame"); + /// break; + /// case TouchPhase.Stationary: + /// Debug.Log($"Frame {Time.frameCount}: ouch {touch} was not updated this frame"); + /// break; + /// } + /// } + /// } /// } /// /// - /// /// EnhancedTouch has not been enabled via . - /// public static ReadOnlyArray activeTouches { get @@ -351,14 +458,13 @@ public static ReadOnlyArray activeTouches /// /// /// For querying only active fingers, use . + /// For querying only active touches, use . /// /// The length of this array will always correspond to the maximum number of concurrent touches supported by the system. /// Note that the actual number of physically supported concurrent touches as determined by the current hardware and /// operating system may be lower than this number. /// /// EnhancedTouch has not been enabled via . - /// - /// public static ReadOnlyArray fingers { get @@ -371,9 +477,10 @@ public static ReadOnlyArray fingers /// /// Set of currently active fingers, i.e. touch contacts that currently have an active touch (as defined by ). /// + /// + /// To instead get a collection of all fingers (not only currently active) use . + /// /// EnhancedTouch has not been enabled via . - /// - /// public static ReadOnlyArray activeFingers { get @@ -401,9 +508,11 @@ public static IEnumerable screens /// /// Event that is invoked when a finger touches a . /// + /// + /// In order to react to a finger being moved or released, see and + /// respectively. + /// /// EnhancedTouch has not been enabled via . - /// - /// public static event Action onFingerDown { add @@ -425,9 +534,11 @@ public static event Action onFingerDown /// /// Event that is invoked when a finger stops touching a . /// + /// + /// In order to react to a finger that touches a or a finger that is being moved + /// use and respectively. + /// /// EnhancedTouch has not been enabled via . - /// - /// public static event Action onFingerUp { add @@ -450,9 +561,11 @@ public static event Action onFingerUp /// Event that is invoked when a finger that is in contact with a moves /// on the screen. /// + /// + /// In order to react to a finger that touches a or a finger that stops touching + /// a , use and respectively. + /// /// EnhancedTouch has not been enabled via . - /// - /// public static event Action onFingerMove { add @@ -501,6 +614,7 @@ internal Touch(Finger finger, InputStateHistory.Record touchRecord) m_TouchRecord = touchRecord; } + /// public override string ToString() { if (!valid) @@ -509,16 +623,24 @@ public override string ToString() return $"{{id={touchId} finger={finger.index} phase={phase} position={screenPosition} delta={delta} time={time}}}"; } + /// + /// Compares this touch for equality with another instance . + /// + /// The other instance to compare with. + /// true if this touch and represents the same finger and maps to the + /// same touch record, otherwise false public bool Equals(Touch other) { return Equals(m_Finger, other.m_Finger) && m_TouchRecord.Equals(other.m_TouchRecord); } + /// public override bool Equals(object obj) { return obj is Touch other && Equals(other); } + /// public override int GetHashCode() { unchecked