Skip to content

Commit bfe5dfd

Browse files
authored
FIX: Improvement for event handling in FixedUpdate mode (#2026)
* [Input System] Improvement for event handling in FixedUpdate mode Previously InputAction.WasPerformedThisFrame() could be true for consecutive frames.InputAction. This happens in frames where no FixedUpdate steps are run.
1 parent ba9677b commit bfe5dfd

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

Packages/com.unity.inputsystem/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ however, it has to be formatted properly to pass verification tests.
1616
- Fixed wrong mapping of Xbox Series S|X and Xbox One wireless controllers "View" button on macOS.[ISXB-385](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-385)
1717
- Fixed "AnalyticsResult" errors on consoles [ISXB-1107]
1818
- Fixed wrong `Display Index` value for touchscreen events.[ISXB-1101](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1101)
19+
- Fixed event handling when using Fixed Update processing where WasPressedThisFrame could appear to true for consecutive frames [ISXB-1006](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1006)
1920

2021
### Added
2122
- Added the display of the device flag `CanRunInBackground` in device debug view.

Packages/com.unity.inputsystem/InputSystem/Actions/InputAction.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ public unsafe bool WasPressedThisFrame()
12361236
{
12371237
var actionStatePtr = &state.actionStates[m_ActionIndexInState];
12381238
var currentUpdateStep = InputUpdate.s_UpdateStepCount;
1239-
return actionStatePtr->pressedInUpdate == currentUpdateStep && currentUpdateStep != default;
1239+
return actionStatePtr->pressedInUpdate == currentUpdateStep && currentUpdateStep != default && actionStatePtr->frame == Time.frameCount;
12401240
}
12411241

12421242
return false;
@@ -1285,7 +1285,7 @@ public unsafe bool WasReleasedThisFrame()
12851285
{
12861286
var actionStatePtr = &state.actionStates[m_ActionIndexInState];
12871287
var currentUpdateStep = InputUpdate.s_UpdateStepCount;
1288-
return actionStatePtr->releasedInUpdate == currentUpdateStep && currentUpdateStep != default;
1288+
return actionStatePtr->releasedInUpdate == currentUpdateStep && currentUpdateStep != default && actionStatePtr->frame == Time.frameCount;
12891289
}
12901290

12911291
return false;
@@ -1344,7 +1344,7 @@ public unsafe bool WasPerformedThisFrame()
13441344
{
13451345
var actionStatePtr = &state.actionStates[m_ActionIndexInState];
13461346
var currentUpdateStep = InputUpdate.s_UpdateStepCount;
1347-
return actionStatePtr->lastPerformedInUpdate == currentUpdateStep && currentUpdateStep != default;
1347+
return actionStatePtr->lastPerformedInUpdate == currentUpdateStep && currentUpdateStep != default && actionStatePtr->frame == Time.frameCount;
13481348
}
13491349

13501350
return false;
@@ -1417,7 +1417,7 @@ public unsafe bool WasCompletedThisFrame()
14171417
{
14181418
var actionStatePtr = &state.actionStates[m_ActionIndexInState];
14191419
var currentUpdateStep = InputUpdate.s_UpdateStepCount;
1420-
return actionStatePtr->lastCompletedInUpdate == currentUpdateStep && currentUpdateStep != default;
1420+
return actionStatePtr->lastCompletedInUpdate == currentUpdateStep && currentUpdateStep != default && actionStatePtr->frame == Time.frameCount;
14211421
}
14221422

14231423
return false;

Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs

+13-1
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ private void RestoreActionStatesAfterReResolvingBindings(UnmanagedMemory oldStat
560560
newActionState.releasedInUpdate = oldActionState.releasedInUpdate;
561561
newActionState.startTime = oldActionState.startTime;
562562
newActionState.bindingIndex = oldActionState.bindingIndex;
563+
newActionState.frame = oldActionState.frame;
563564

564565
if (oldActionState.phase != InputActionPhase.Disabled)
565566
{
@@ -884,6 +885,7 @@ public void ResetActionState(int actionIndex, InputActionPhase toPhase = InputAc
884885
actionState->lastCompletedInUpdate = default;
885886
actionState->pressedInUpdate = default;
886887
actionState->releasedInUpdate = default;
888+
actionState->frame = default;
887889
}
888890

889891
Debug.Assert(!actionState->isStarted, "Cannot reset an action to started phase");
@@ -1579,6 +1581,7 @@ private void ProcessButtonState(ref TriggerState trigger, int actionIndex, Bindi
15791581
{
15801582
actionState->pressedInUpdate = InputUpdate.s_UpdateStepCount;
15811583
actionState->isPressed = true;
1584+
actionState->frame = Time.frameCount;
15821585
}
15831586
else if (actionState->isPressed)
15841587
{
@@ -1587,6 +1590,7 @@ private void ProcessButtonState(ref TriggerState trigger, int actionIndex, Bindi
15871590
{
15881591
actionState->releasedInUpdate = InputUpdate.s_UpdateStepCount;
15891592
actionState->isPressed = false;
1593+
actionState->frame = Time.frameCount;
15901594
}
15911595
}
15921596
}
@@ -2445,6 +2449,7 @@ private void ChangePhaseOfActionInternal(int actionIndex, TriggerState* actionSt
24452449
newState.magnitude = 0f;
24462450

24472451
newState.phase = newPhase;
2452+
newState.frame = Time.frameCount;
24482453
if (newPhase == InputActionPhase.Performed)
24492454
{
24502455
newState.lastPerformedInUpdate = InputUpdate.s_UpdateStepCount;
@@ -3627,7 +3632,7 @@ public int partIndex
36273632
/// other is to represent the current actuation state of an action as a whole. The latter is stored in <see cref="actionStates"/>
36283633
/// while the former is passed around as temporary instances on the stack.
36293634
/// </remarks>
3630-
[StructLayout(LayoutKind.Explicit, Size = 52)]
3635+
[StructLayout(LayoutKind.Explicit, Size = 56)]
36313636
public struct TriggerState
36323637
{
36333638
public const int kMaxNumMaps = byte.MaxValue;
@@ -3651,6 +3656,7 @@ public struct TriggerState
36513656
[FieldOffset(40)] private uint m_PressedInUpdate;
36523657
[FieldOffset(44)] private uint m_ReleasedInUpdate;
36533658
[FieldOffset(48)] private uint m_LastCompletedInUpdate;
3659+
[FieldOffset(52)] private int m_Frame;
36543660

36553661
/// <summary>
36563662
/// Phase being triggered by the control value change.
@@ -3806,6 +3812,12 @@ public uint lastPerformedInUpdate
38063812
set => m_LastPerformedInUpdate = value;
38073813
}
38083814

3815+
internal int frame
3816+
{
3817+
get => m_Frame;
3818+
set => m_Frame = value;
3819+
}
3820+
38093821
/// <summary>
38103822
/// Update step count (<see cref="InputUpdate.s_UpdateStepCount"/>) in which action completed last.
38113823
/// Zero if the action did not become completed yet. Also reset to zero when the action is hard reset.

0 commit comments

Comments
 (0)