Skip to content

Commit 6b1a048

Browse files
committed
Check if pointer state touchID matches cached TouchControl touchID
Covers the edge case of releasing one finger and pressing with another in the same frame.
1 parent 94c260e commit 6b1a048

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

Packages/com.unity.inputsystem/InputSystem/Plugins/UI/InputSystemUIInputModule.cs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,16 +1729,33 @@ private int GetPointerStateIndexFor(InputControl control, bool createIfNotExists
17291729
// Determine the pointer (and touch) ID. We default the pointer ID to the device
17301730
// ID of the InputDevice.
17311731
var controlParent = control.parent;
1732+
// NOTE: m_PointerTouchControls stores references to TouchControl instances. e.g. this means that "touch0"
1733+
// in the same frame can have different touchId values.
17321734
var touchControlIndex = m_PointerTouchControls.IndexOfReference(controlParent);
17331735
if (touchControlIndex != -1)
17341736
{
1735-
// For touches, we cache a reference to the control of a pointer so that we don't
1736-
// have to continuously do ReadValue() on the touch ID control.
1737-
m_CurrentPointerId = m_PointerIds[touchControlIndex];
1738-
m_CurrentPointerIndex = touchControlIndex;
1739-
m_CurrentPointerType = UIPointerType.Touch;
1740-
1741-
return touchControlIndex;
1737+
// Pointers are deallocated in the frame after their release (unpressed), which means the pointer state
1738+
// and the m_PointerTouchControls entry is only removed in the next frame
1739+
// (see UI_TouchPointersAreKeptForOneFrameAfterRelease).
1740+
// To accomodate for cases when touch is released and pressed in the same frame, the pointer
1741+
// state touchId needs to be checked against the cached touch control touchId (in m_PointerTouchControls)
1742+
// This is because the pointer state of the released touch (unpressed) still exists.
1743+
// If touchIDs are different, a new pointer should be allocated. Otherwise, a cached reference will
1744+
// be used.
1745+
var pointerTouchControl = m_PointerTouchControls[touchControlIndex];
1746+
ref var pointerState = ref GetPointerStateForIndex(touchControlIndex);
1747+
1748+
if (!(pointerTouchControl is TouchControl) ||
1749+
(pointerTouchControl is TouchControl &&
1750+
pointerState.eventData.touchId == ((TouchControl)pointerTouchControl).touchId.value))
1751+
{
1752+
// For touches, we cache a reference to the control of a pointer so that we don't
1753+
// have to continuously do ReadValue() on the touch ID control.
1754+
m_CurrentPointerId = m_PointerIds[touchControlIndex];
1755+
m_CurrentPointerIndex = touchControlIndex;
1756+
m_CurrentPointerType = UIPointerType.Touch;
1757+
return touchControlIndex;
1758+
}
17421759
}
17431760

17441761
var pointerId = device.deviceId;

0 commit comments

Comments
 (0)