Skip to content

Commit a0b21ba

Browse files
authored
FIX: EnhancedTouch getting out of sync when disabled and reenabled (case 1286865, #1250).
1 parent 4e2f7f6 commit a0b21ba

File tree

6 files changed

+143
-31
lines changed

6 files changed

+143
-31
lines changed

Assets/Tests/InputSystem/Plugins/EnhancedTouchTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,42 @@ public void EnhancedTouch_CanReceiveCallbacksOnFingerActivity()
798798
}));
799799
}
800800

801+
// https://fogbugz.unity3d.com/f/cases/1286865/
802+
[Test]
803+
[Category("EnhancedTouch")]
804+
public void EnhancedTouch_CanBeDisabledAndReenabled()
805+
{
806+
BeginTouch(1, new Vector2(0.123f, 0.234f), queueEventOnly: true);
807+
InputSystem.Update();
808+
Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
809+
Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Began));
810+
811+
MoveTouch(1, new Vector2(0.234f, 0.345f), queueEventOnly: true);
812+
InputSystem.Update();
813+
Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
814+
Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Moved));
815+
816+
InputSystem.Update();
817+
Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
818+
Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Stationary));
819+
820+
EnhancedTouchSupport.Disable();
821+
EnhancedTouchSupport.Enable();
822+
823+
InputSystem.Update();
824+
Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
825+
Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Stationary));
826+
827+
MoveTouch(1, new Vector2(0.123f, 0.234f), queueEventOnly: true);
828+
InputSystem.Update();
829+
Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
830+
Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Moved));
831+
832+
InputSystem.Update();
833+
Assert.That(Touch.activeTouches.Count, Is.EqualTo(1));
834+
Assert.That(Touch.activeTouches[0].phase, Is.EqualTo(TouchPhase.Stationary));
835+
}
836+
801837
[Test]
802838
[Category("EnhancedTouch")]
803839
[Property("EnhancedTouchDisabled", 1)]

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ however, it has to be formatted properly to pass verification tests.
2626
- Fixed restart prompt after package installation not appearing on Unity 2020.2+ ([case 1292513](https://issuetracker.unity3d.com/issues/input-system-after-package-install-the-update-slash-switch-and-restart-prompt-does-not-appear)).
2727
- Fixed action with multiple bindings getting stuck in `Performed` state when two or more controls are pressed at the same time ([case 1295535](https://issuetracker.unity3d.com/issues/input-system-not-registering-multiple-inputs)).
2828
* Regression introduced in 1.1-preview.2.
29+
- Fixed `Touch.activeTouches` having incorrect touch phases after calling `EnhancedTouch.Disable()` and then `EnhancedTouch.Enable()` ([case 1286865](https://issuetracker.unity3d.com/issues/new-input-system-began-moved-and-ended-touch-phases-are-not-reported-when-a-second-scene-is-loaded)).
2930

3031
#### Actions
3132

Packages/com.unity.inputsystem/InputSystem/InputManager.cs

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2257,14 +2257,7 @@ private void OnBeforeUpdate(InputUpdateType updateType)
22572257

22582258
InputStateBuffers.SwitchTo(m_StateBuffers, updateType);
22592259

2260-
InputUpdate.s_LastUpdateType = updateType;
2261-
if (updateType == InputUpdateType.Dynamic || updateType == InputUpdateType.Manual || updateType == InputUpdateType.Fixed)
2262-
{
2263-
// We want to update step counts to be correct in OnNextUpdate() and onBeforeUpdate callbacks.
2264-
// We use a boolean flag to tell OnUpdate() that we've already incremented the count.
2265-
++InputUpdate.s_UpdateStepCount;
2266-
InputUpdate.s_HaveUpdatedStepCount = true;
2267-
}
2260+
InputUpdate.OnBeforeUpdate(updateType);
22682261

22692262
// For devices that have state callbacks, tell them we're carrying state over
22702263
// into the next frame.
@@ -2586,20 +2579,9 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev
25862579
// Store current time offset.
25872580
InputRuntime.s_CurrentTimeOffsetToRealtimeSinceStartup = m_Runtime.currentTimeOffsetToRealtimeSinceStartup;
25882581

2589-
InputUpdate.s_LastUpdateType = updateType;
25902582
InputStateBuffers.SwitchTo(m_StateBuffers, updateType);
25912583

2592-
var isBeforeRenderUpdate = false;
2593-
if (updateType == InputUpdateType.Dynamic || updateType == InputUpdateType.Manual || updateType == InputUpdateType.Fixed)
2594-
{
2595-
if (!InputUpdate.s_HaveUpdatedStepCount)
2596-
++InputUpdate.s_UpdateStepCount;
2597-
InputUpdate.s_HaveUpdatedStepCount = false;
2598-
}
2599-
else if (updateType == InputUpdateType.BeforeRender)
2600-
{
2601-
isBeforeRenderUpdate = true;
2602-
}
2584+
InputUpdate.OnUpdate(updateType);
26032585

26042586
// See if we're supposed to only take events up to a certain time.
26052587
// NOTE: We do not require the events in the queue to be sorted. Instead, we will walk over
@@ -2650,7 +2632,7 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev
26502632

26512633
// In before render updates, we only take state events and only those for devices
26522634
// that have before render updates enabled.
2653-
if (isBeforeRenderUpdate)
2635+
if (updateType == InputUpdateType.BeforeRender)
26542636
{
26552637
while (remainingEventCount > 0)
26562638
{

Packages/com.unity.inputsystem/InputSystem/InputUpdateType.cs

Lines changed: 97 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,27 +71,98 @@ public enum InputUpdateType
7171

7272
internal static class InputUpdate
7373
{
74-
public static bool s_HaveUpdatedStepCount;
74+
public static uint s_UpdateStepCount; // read only, but kept as a variable for performance reasons
7575
public static InputUpdateType s_LastUpdateType;
76-
public static uint s_UpdateStepCount;
76+
public static UpdateStepCount s_PlayerUpdateStepCount;
77+
#if UNITY_EDITOR
78+
public static UpdateStepCount s_EditorUpdateStepCount;
79+
#endif
7780
public static uint s_LastUpdateRetainedEventBytes;
7881
public static uint s_LastUpdateRetainedEventCount;
7982

83+
[Serializable]
84+
public struct UpdateStepCount
85+
{
86+
private bool m_WasUpdated;
87+
88+
public uint value { get; private set; }
89+
90+
public void OnBeforeUpdate()
91+
{
92+
m_WasUpdated = true;
93+
value++;
94+
}
95+
96+
public void OnUpdate()
97+
{
98+
// only increment if OnBeforeUpdate was not called
99+
if (!m_WasUpdated)
100+
value++;
101+
m_WasUpdated = false;
102+
}
103+
};
104+
80105
[Serializable]
81106
public struct SerializedState
82107
{
83108
public InputUpdateType lastUpdateType;
84-
public uint updateStepCount;
109+
public UpdateStepCount playerUpdateStepCount;
110+
#if UNITY_EDITOR
111+
public UpdateStepCount editorUpdateStepCount;
112+
#endif
85113
public uint lastUpdateRetainedEventBytes;
86114
public uint lastUpdateRetainedEventCount;
87115
}
88116

117+
internal static void OnBeforeUpdate(InputUpdateType type)
118+
{
119+
s_LastUpdateType = type;
120+
switch (type)
121+
{
122+
case InputUpdateType.Dynamic:
123+
case InputUpdateType.Manual:
124+
case InputUpdateType.Fixed:
125+
s_PlayerUpdateStepCount.OnBeforeUpdate();
126+
s_UpdateStepCount = s_PlayerUpdateStepCount.value;
127+
break;
128+
#if UNITY_EDITOR
129+
case InputUpdateType.Editor:
130+
s_EditorUpdateStepCount.OnBeforeUpdate();
131+
s_UpdateStepCount = s_EditorUpdateStepCount.value;
132+
break;
133+
#endif
134+
}
135+
}
136+
137+
internal static void OnUpdate(InputUpdateType type)
138+
{
139+
s_LastUpdateType = type;
140+
switch (type)
141+
{
142+
case InputUpdateType.Dynamic:
143+
case InputUpdateType.Manual:
144+
case InputUpdateType.Fixed:
145+
s_PlayerUpdateStepCount.OnUpdate();
146+
s_UpdateStepCount = s_PlayerUpdateStepCount.value;
147+
break;
148+
#if UNITY_EDITOR
149+
case InputUpdateType.Editor:
150+
s_EditorUpdateStepCount.OnUpdate();
151+
s_UpdateStepCount = s_EditorUpdateStepCount.value;
152+
break;
153+
#endif
154+
}
155+
}
156+
89157
public static SerializedState Save()
90158
{
91159
return new SerializedState
92160
{
93161
lastUpdateType = s_LastUpdateType,
94-
updateStepCount = s_UpdateStepCount,
162+
playerUpdateStepCount = s_PlayerUpdateStepCount,
163+
#if UNITY_EDITOR
164+
editorUpdateStepCount = s_EditorUpdateStepCount,
165+
#endif
95166
lastUpdateRetainedEventBytes = s_LastUpdateRetainedEventBytes,
96167
lastUpdateRetainedEventCount = s_LastUpdateRetainedEventCount,
97168
};
@@ -100,9 +171,30 @@ public static SerializedState Save()
100171
public static void Restore(SerializedState state)
101172
{
102173
s_LastUpdateType = state.lastUpdateType;
103-
s_UpdateStepCount = state.updateStepCount;
174+
s_PlayerUpdateStepCount = state.playerUpdateStepCount;
104175
s_LastUpdateRetainedEventBytes = state.lastUpdateRetainedEventBytes;
105176
s_LastUpdateRetainedEventCount = state.lastUpdateRetainedEventCount;
177+
#if UNITY_EDITOR
178+
s_EditorUpdateStepCount = state.editorUpdateStepCount;
179+
#endif
180+
181+
switch (s_LastUpdateType)
182+
{
183+
case InputUpdateType.Dynamic:
184+
case InputUpdateType.Manual:
185+
case InputUpdateType.Fixed:
186+
s_UpdateStepCount = s_PlayerUpdateStepCount.value;
187+
break;
188+
#if UNITY_EDITOR
189+
case InputUpdateType.Editor:
190+
s_UpdateStepCount = s_EditorUpdateStepCount.value;
191+
break;
192+
#endif
193+
default:
194+
// if there was no previous update type, reset the counter
195+
s_UpdateStepCount = 0;
196+
break;
197+
}
106198
}
107199
}
108200
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public Touch currentTouch
9191
if (touch.isInProgress)
9292
return touch;
9393
// Ended touches stay current in the frame they ended in.
94-
if (touch.updateStepCount == Touch.s_PlayerState.updateStepCount)
94+
if (touch.updateStepCount == InputUpdate.s_UpdateStepCount)
9595
return touch;
9696
return default;
9797
}
@@ -124,6 +124,10 @@ internal Finger(Touchscreen screen, int index, InputUpdateType updateMask)
124124
updateMask = updateMask,
125125
};
126126
m_StateHistory.StartRecording();
127+
128+
// record the current state if touch is already in progress
129+
if (screen.touches[index].isInProgress)
130+
m_StateHistory.RecordStateChange(screen.touches[index], screen.touches[index].ReadValue());
127131
}
128132

129133
private static unsafe bool ShouldRecordTouch(InputControl control, double time, InputEventPtr eventPtr)

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -565,8 +565,6 @@ internal static void BeginUpdate()
565565
}
566566
#endif
567567

568-
++s_PlayerState.updateStepCount;
569-
570568
// If we have any touches in activeTouches that are ended or canceled,
571569
// we need to clear them in the next frame.
572570
if (s_PlayerState.haveActiveTouchesNeedingRefreshNextUpdate)
@@ -598,7 +596,6 @@ internal static void BeginUpdate()
598596
internal struct FingerAndTouchState
599597
{
600598
public InputUpdateType updateMask;
601-
public uint updateStepCount;
602599
public Finger[] fingers;
603600
public Finger[] activeFingers;
604601
public Touch[] activeTouches;
@@ -691,7 +688,7 @@ public unsafe void UpdateActiveTouches()
691688
}
692689
activeTouchCount = 0;
693690
haveActiveTouchesNeedingRefreshNextUpdate = false;
694-
var currentUpdateStepCount = s_PlayerState.updateStepCount;
691+
var currentUpdateStepCount = InputUpdate.s_UpdateStepCount;
695692

696693
////OPTIMIZE: Handle touchscreens that have no activity more efficiently
697694
////FIXME: This is sensitive to history size; we probably need to ensure that the Begans and Endeds/Canceleds of touches are always available to us

0 commit comments

Comments
 (0)