Skip to content

Commit bb685c5

Browse files
FIX: The button is not clickable when using Windows touch simulation inputs (ISXB-483) (#2012)
* Pair simulated touchscreen with PlayerInput user * Add period to end of sentence * Fix formatting * Refactored initial fix to queue state events instead Based on review and code comments, this seems like a better solution that fixes the main problem and also better simulates a touchscreen when used together with PlayerInput. Automatic pairing and control scheme occurs now since we're using input events a real device would also use. * Change logic to be based on state events The previous logic was based on changing state and didn't apply if we queued events. Also, this commit avoids processing the queued events for the simulated Touchscreen. * Remove unnecessary left over code * Fix setting wrong touchIDs when moving multiple touches
1 parent ff7837e commit bb685c5

File tree

2 files changed

+19
-34
lines changed

2 files changed

+19
-34
lines changed

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ however, it has to be formatted properly to pass verification tests.
3030
- Fixed "MissingReferenceException" errors when closing an in-game dropdown field [ISXB-1081](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1081).
3131
- Fixed potential crash on Mac when using stale references to deleted InputDevice objects [ISXB-606](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-606).
3232
- Fixed conditional compilation for non-editor analytics on platforms not enabling analytics.
33+
- Fixed simulated touch input not working with PlayerInput component [ISXB-483](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-483).
3334

3435
### Changed
3536
- Renamed editor Resources directories to PackageResources to fix package validation warnings.

Packages/com.unity.inputsystem/InputSystem/Plugins/EnhancedTouch/TouchSimulation.cs

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ protected void RemovePointer(Pointer pointer)
121121

122122
private unsafe void OnEvent(InputEventPtr eventPtr, InputDevice device)
123123
{
124+
if (device == simulatedTouchscreen)
125+
{
126+
// Avoid processing events queued by this simulation device
127+
return;
128+
}
129+
124130
var pointerIndex = m_Pointers.IndexOfReference(device, m_NumPointers);
125131
if (pointerIndex < 0)
126132
return;
@@ -129,9 +135,6 @@ private unsafe void OnEvent(InputEventPtr eventPtr, InputDevice device)
129135
if (eventType != StateEvent.Type && eventType != DeltaStateEvent.Type)
130136
return;
131137

132-
////TODO: this can be simplified if we use events instead of InputState.Change() but doing so requires work on buffering events while processing; also
133-
//// needs extra handling to not lag into the next frame
134-
135138
////REVIEW: should we have specialized paths for MouseState and PenState here? (probably can only use for StateEvents)
136139

137140
Pointer pointer = m_Pointers[pointerIndex];
@@ -254,6 +257,9 @@ protected void OnEnable()
254257
if (m_Touches == null)
255258
m_Touches = new ButtonControl[simulatedTouchscreen.touches.Count];
256259

260+
if (m_TouchIds == null)
261+
m_TouchIds = new int[simulatedTouchscreen.touches.Count];
262+
257263
foreach (var device in InputSystem.devices)
258264
OnDeviceChange(device, InputDeviceChange.Added);
259265

@@ -280,7 +286,6 @@ protected void OnDisable()
280286

281287
m_NumPointers = 0;
282288
m_LastTouchId = 0;
283-
m_PrimaryTouchIndex = -1;
284289

285290
InputSystem.onDeviceChange -= m_OnDeviceChange;
286291
InputSystem.onEvent -= m_OnEvent;
@@ -292,55 +297,34 @@ private unsafe void UpdateTouch(int touchIndex, int pointerIndex, TouchPhase pha
292297
Debug.Assert(m_CurrentDisplayIndices[pointerIndex] <= byte.MaxValue, "Display index was larger than expected");
293298
byte displayIndex = (byte)m_CurrentDisplayIndices[pointerIndex];
294299

300+
// We need to partially set TouchState in a similar way that the Native side would do, but deriving that
301+
// data from the Pointer events.
302+
// The handling of the remaining fields is done by the Touchscreen.OnStateEvent() callback.
295303
var touch = new TouchState
296304
{
297305
phase = phase,
298306
position = position,
299307
displayIndex = displayIndex
300308
};
301-
var time = eventPtr.valid ? eventPtr.time : InputState.currentTime;
302-
303-
var oldTouchState = (TouchState*)((byte*)simulatedTouchscreen.currentStatePtr +
304-
simulatedTouchscreen.touches[touchIndex].stateBlock.byteOffset);
305309

306310
if (phase == TouchPhase.Began)
307311
{
308-
touch.isPrimaryTouch = m_PrimaryTouchIndex < 0;
309-
touch.startTime = time;
312+
touch.startTime = eventPtr.valid ? eventPtr.time : InputState.currentTime;
310313
touch.startPosition = position;
311314
touch.touchId = ++m_LastTouchId;
312-
touch.tapCount = oldTouchState->tapCount; // Get reset automatically by Touchscreen.
313-
314-
if (touch.isPrimaryTouch)
315-
m_PrimaryTouchIndex = touchIndex;
315+
m_TouchIds[touchIndex] = m_LastTouchId;
316316
}
317317
else
318318
{
319-
touch.touchId = oldTouchState->touchId;
320-
touch.isPrimaryTouch = m_PrimaryTouchIndex == touchIndex;
321-
touch.delta = position - oldTouchState->position;
322-
touch.startPosition = oldTouchState->startPosition;
323-
touch.startTime = oldTouchState->startTime;
324-
touch.tapCount = oldTouchState->tapCount;
325-
326-
if (phase == TouchPhase.Ended)
327-
{
328-
touch.isTap = time - oldTouchState->startTime <= Touchscreen.s_TapTime &&
329-
(position - oldTouchState->startPosition).sqrMagnitude <= Touchscreen.s_TapRadiusSquared;
330-
if (touch.isTap)
331-
++touch.tapCount;
332-
}
319+
touch.touchId = m_TouchIds[touchIndex];
333320
}
334321

335-
if (touch.isPrimaryTouch)
336-
InputState.Change(simulatedTouchscreen.primaryTouch, touch, eventPtr: eventPtr);
337-
InputState.Change(simulatedTouchscreen.touches[touchIndex], touch, eventPtr: eventPtr);
322+
//NOTE: Processing these events still happen in the current frame.
323+
InputSystem.QueueStateEvent(simulatedTouchscreen, touch);
338324

339325
if (phase.IsEndedOrCanceled())
340326
{
341327
m_Touches[touchIndex] = null;
342-
if (m_PrimaryTouchIndex == touchIndex)
343-
m_PrimaryTouchIndex = -1;
344328
}
345329
}
346330

@@ -349,9 +333,9 @@ private unsafe void UpdateTouch(int touchIndex, int pointerIndex, TouchPhase pha
349333
[NonSerialized] private Vector2[] m_CurrentPositions;
350334
[NonSerialized] private int[] m_CurrentDisplayIndices;
351335
[NonSerialized] private ButtonControl[] m_Touches;
336+
[NonSerialized] private int[] m_TouchIds;
352337

353338
[NonSerialized] private int m_LastTouchId;
354-
[NonSerialized] private int m_PrimaryTouchIndex = -1;
355339
[NonSerialized] private Action<InputDevice, InputDeviceChange> m_OnDeviceChange;
356340
[NonSerialized] private Action<InputEventPtr, InputDevice> m_OnEvent;
357341

0 commit comments

Comments
 (0)