From e5509ff3326193cefc5141832f17131b189d5560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kan=20Sidenvall?= Date: Wed, 9 Apr 2025 15:49:57 +0200 Subject: [PATCH 01/21] Debug files --- Assets/ActionDebug.cs | 25 ++++++++++++++++ Assets/ActionDebug.cs.meta | 2 ++ .../RebindUISampleActions.inputactions | 29 +++++++++++++++++-- 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 Assets/ActionDebug.cs create mode 100644 Assets/ActionDebug.cs.meta diff --git a/Assets/ActionDebug.cs b/Assets/ActionDebug.cs new file mode 100644 index 0000000000..bc161e4534 --- /dev/null +++ b/Assets/ActionDebug.cs @@ -0,0 +1,25 @@ +using UnityEngine; +using UnityEngine.InputSystem; + +public class ActionDebug : MonoBehaviour +{ + public InputActionReference trigger; + + // Start is called once before the first execution of Update after the MonoBehaviour is created + void Start() + { + trigger.action.performed += ActionOnperformed; + trigger.action.Enable(); + } + + private void ActionOnperformed(InputAction.CallbackContext obj) + { + Debug.Log("Action Performed"); + } + + // Update is called once per frame + void Update() + { + + } +} diff --git a/Assets/ActionDebug.cs.meta b/Assets/ActionDebug.cs.meta new file mode 100644 index 0000000000..93697c7c4a --- /dev/null +++ b/Assets/ActionDebug.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 7d36843388d90a04782f5f49339e23c4 \ No newline at end of file diff --git a/Assets/Samples/RebindingUI/RebindUISampleActions.inputactions b/Assets/Samples/RebindingUI/RebindUISampleActions.inputactions index 0c0478cf71..662218926d 100644 --- a/Assets/Samples/RebindingUI/RebindUISampleActions.inputactions +++ b/Assets/Samples/RebindingUI/RebindUISampleActions.inputactions @@ -11,7 +11,8 @@ "id": "9d8fcbff-87d1-43ef-857e-931c84d5bd72", "expectedControlType": "Vector2", "processors": "", - "interactions": "" + "interactions": "", + "initialStateCheck": true }, { "name": "Look", @@ -19,7 +20,8 @@ "id": "ddab72da-d325-4b4c-a484-abe4f6bdf113", "expectedControlType": "Vector2", "processors": "", - "interactions": "" + "interactions": "", + "initialStateCheck": true }, { "name": "Interact", @@ -27,7 +29,17 @@ "id": "2bd60403-0923-469e-a3a4-7338b04f6bbc", "expectedControlType": "", "processors": "", - "interactions": "" + "interactions": "", + "initialStateCheck": false + }, + { + "name": "Test", + "type": "Button", + "id": "a0bbd927-54af-4ba8-be59-8470a31efd79", + "expectedControlType": "", + "processors": "", + "interactions": "", + "initialStateCheck": false } ], "bindings": [ @@ -140,6 +152,17 @@ "action": "Interact", "isComposite": false, "isPartOfComposite": false + }, + { + "name": "", + "id": "60a650d1-dafb-4f35-bfb4-94d9974472fb", + "path": "/buttonNorth", + "interactions": "", + "processors": "", + "groups": "", + "action": "Test", + "isComposite": false, + "isPartOfComposite": false } ] } From d323b9b5f6eb3bc3dfce1d4eac7adfbc04f2e6e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Mon, 14 Apr 2025 15:43:11 +0200 Subject: [PATCH 02/21] Added debug script to scene --- .../RebindingUI/RebindingUISampleScene.unity | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Assets/Samples/RebindingUI/RebindingUISampleScene.unity b/Assets/Samples/RebindingUI/RebindingUISampleScene.unity index 0908be1603..68cfad33e0 100644 --- a/Assets/Samples/RebindingUI/RebindingUISampleScene.unity +++ b/Assets/Samples/RebindingUI/RebindingUISampleScene.unity @@ -1096,6 +1096,7 @@ GameObject: - component: {fileID: 780148237} - component: {fileID: 780148236} - component: {fileID: 780148235} + - component: {fileID: 780148238} m_Layer: 0 m_Name: EventSystem m_TagString: Untagged @@ -1175,6 +1176,19 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &780148238 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 780148234} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7d36843388d90a04782f5f49339e23c4, type: 3} + m_Name: + m_EditorClassIdentifier: + trigger: {fileID: 2345695455583553484, guid: 7dead05c54ca85b4681351aafd8bd03a, type: 3} --- !u!1 &861395291 GameObject: m_ObjectHideFlags: 0 From da35c496b114bd113c32ddba7681ce5fae4b942b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Tue, 15 Apr 2025 15:35:43 +0200 Subject: [PATCH 03/21] Added wait to RebindActionUI.cs --- Assets/Samples/RebindingUI/RebindActionUI.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Assets/Samples/RebindingUI/RebindActionUI.cs b/Assets/Samples/RebindingUI/RebindActionUI.cs index f755919be6..5f750be78b 100644 --- a/Assets/Samples/RebindingUI/RebindActionUI.cs +++ b/Assets/Samples/RebindingUI/RebindActionUI.cs @@ -289,6 +289,7 @@ void CleanUp() UpdateBindingDisplay(); CleanUp(); }) + .OnMatchWaitForAnother(0.2f) .OnComplete( operation => { From 93de642001c6b2139fe1d7d0484bcf97a166f112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Tue, 22 Apr 2025 20:21:00 +0200 Subject: [PATCH 04/21] Added input event handled policy run-time setting --- Assets/Tests/InputSystem/CoreTests_Events.cs | 83 +++++++++++++++++++ .../Events/InputEventHandledPolicy.cs | 19 +++++ .../Events/InputEventHandledPolicy.cs.meta | 3 + .../InputSystem/InputManager.cs | 27 ++++++ .../InputSystem/InputSystem.cs | 25 ++++++ 5 files changed, 157 insertions(+) create mode 100644 Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs create mode 100644 Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs.meta diff --git a/Assets/Tests/InputSystem/CoreTests_Events.cs b/Assets/Tests/InputSystem/CoreTests_Events.cs index 6addd65598..d7ea3677fe 100644 --- a/Assets/Tests/InputSystem/CoreTests_Events.cs +++ b/Assets/Tests/InputSystem/CoreTests_Events.cs @@ -1216,6 +1216,89 @@ public void Events_CanPreventEventsFromBeingProcessed() Assert.That(device.rightTrigger.ReadValue(), Is.EqualTo(0.0).Within(0.00001)); } + class SuppressedActionEventData + { + public bool markNextEventHandled; + public int startedCount; + public int performedCount; + public int canceledCount; + } + + [Test] + [Category("Events")] + public void EventHandledPolicy_ShouldReflectUserSetting() + { + // Assert default setting + Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressProcessing)); + + // Assert policy can be changed + InputSystem.inputEventHandledPolicy = InputEventHandledPolicy.SuppressNotifications; + Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressNotifications)); + + // Assert policy can be changed back + InputSystem.inputEventHandledPolicy = InputEventHandledPolicy.SuppressProcessing; + Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressProcessing)); + + // Assert setting property to an invalid value throws exception and do not have side-effects + Assert.Throws(() => + InputSystem.inputEventHandledPolicy = (InputEventHandledPolicy)123456); + Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressProcessing)); + } + + [TestCase(InputEventHandledPolicy.SuppressProcessing, + new int[] { 0, 0, 1, 1}, new int[] {0, 0, 0, 1})] + [TestCase(InputEventHandledPolicy.SuppressNotifications, + new int[] { 0, 0, 0, 0}, new int[] {0, 0, 0, 0})] + [Category("Events")] + [Description("ISXB-1524 Events suppressed has side-effects on actions when based on polling")] + public void Events_ShouldRespectHandledPolicyUponUpdate(InputEventHandledPolicy policy, + int[] expectedProcessed, int[] expectedCancelled) // EDIT + { + // Use a boxed boolean to allow lambda to capture reference. + var data = new SuppressedActionEventData(); + + InputSystem.onEvent += + (inputEvent, _) => + { + // If we mark the event handled, the system should skip it and not + // let it go to the device. + inputEvent.handled = data.markNextEventHandled; + }; + + var device = InputSystem.AddDevice(); + var action = new InputAction(type: InputActionType.Button, binding: "/buttonNorth"); + action.Enable(); + action.started += _ => ++ data.startedCount; + action.performed += _ => ++ data.performedCount; + action.canceled += _ => ++ data.canceledCount; + + // Ensure state is updated/initialized + InputSystem.QueueStateEvent(device, new GamepadState() { leftStick = new Vector2(0.01f, 0.0f) }); + InputSystem.Update(); + Assert.That(data.performedCount, Is.EqualTo(expectedProcessed[0])); + Assert.That(data.canceledCount, Is.EqualTo(expectedCancelled[0])); + + // Press button north with event suppression active + data.markNextEventHandled = true; + InputSystem.QueueStateEvent(device, new GamepadState() { leftStick = new Vector2(0.00f, 0.01f) }.WithButton(GamepadButton.North)); + InputSystem.Update(); + Assert.That(data.performedCount, Is.EqualTo(expectedProcessed[1])); + Assert.That(data.canceledCount, Is.EqualTo(expectedCancelled[1])); + + // Simulate a periodic reading, this will trigger performed count + data.markNextEventHandled = false; + InputSystem.QueueStateEvent(device, new GamepadState() { leftStick = new Vector2(0.01f, 0.00f) }.WithButton(GamepadButton.North)); + InputSystem.Update(); + Assert.That(data.performedCount, Is.EqualTo(expectedProcessed[2])); // Firing without actual change + Assert.That(data.canceledCount, Is.EqualTo(expectedCancelled[2])); + + // Release button north + InputSystem.QueueStateEvent(device, new GamepadState() { leftStick = new Vector2(0.00f, 0.01f) }); + InputSystem.Update(); + Assert.That(data.performedCount, Is.EqualTo(expectedProcessed[3])); + Assert.That(data.canceledCount, Is.EqualTo(expectedCancelled[3])); + } + [StructLayout(LayoutKind.Explicit, Size = 2)] struct StateWith2Bytes : IInputStateTypeInfo { diff --git a/Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs b/Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs new file mode 100644 index 0000000000..c509ca1cbd --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs @@ -0,0 +1,19 @@ +namespace UnityEngine.InputSystem.LowLevel +{ + /// + /// Policy defining how the Input System will process instances marked as + /// . + /// + public enum InputEventHandledPolicy + { + /// + /// Input events will be discarded and not propagated for neither state updates nor notifications. + /// + SuppressProcessing, + + /// + /// Input events will be processed for state updates but will not trigger interaction nor phase notifications. + /// + SuppressNotifications + } +} diff --git a/Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs.meta new file mode 100644 index 0000000000..32abd146f5 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7c9443eaca924751a528ee833d503cb0 +timeCreated: 1745344677 \ No newline at end of file diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs index 10e3c17fb8..f7a6585b63 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs @@ -210,6 +210,23 @@ public float pollingFrequency } } + public InputEventHandledPolicy inputEventHandledPolicy + { + get => m_InputEventHandledPolicy; + set + { + switch (value) + { + case InputEventHandledPolicy.SuppressNotifications: + case InputEventHandledPolicy.SuppressProcessing: + m_InputEventHandledPolicy = value; + break; + default: + throw new ArgumentOutOfRangeException("value"); + } + } + } + public event DeviceChangeListener onDeviceChange { add => m_DeviceChangeListeners.AddCallback(value); @@ -1891,6 +1908,9 @@ internal void InitializeData() // Default polling frequency is 60 Hz. m_PollingFrequency = 60; + // Default input event handled policy. + m_InputEventHandledPolicy = InputEventHandledPolicy.SuppressProcessing; + // Register layouts. // NOTE: Base layouts must be registered before their derived layouts // for the detection of base layouts to work. @@ -2142,6 +2162,7 @@ internal struct AvailableDevice // Used by EditorInputControlLayoutCache to determine whether its state is outdated. internal int m_LayoutRegistrationVersion; private float m_PollingFrequency; + private InputEventHandledPolicy m_InputEventHandledPolicy; internal InputControlLayout.Collection m_Layouts; private TypeTable m_Processors; @@ -3901,8 +3922,11 @@ internal unsafe bool UpdateState(InputDevice device, InputUpdateType updateType, } // Notify listeners. + //if (eventPtr == null || !eventPtr.handled) // EDIT + //{ DelegateHelpers.InvokeCallbacksSafe(ref m_DeviceStateChangeListeners, device, eventPtr, k_InputOnDeviceSettingsChangeMarker, "InputSystem.onDeviceStateChange"); + //} // Now that we've committed the new state to memory, if any of the change // monitors fired, let the associated actions know. @@ -4048,6 +4072,7 @@ internal struct SerializedState { public int layoutRegistrationVersion; public float pollingFrequency; + public InputEventHandledPolicy inputEventHandledPolicy; public DeviceState[] devices; public AvailableDevice[] availableDevices; public InputStateBuffers buffers; @@ -4093,6 +4118,7 @@ internal SerializedState SaveState() { layoutRegistrationVersion = m_LayoutRegistrationVersion, pollingFrequency = m_PollingFrequency, + inputEventHandledPolicy = m_InputEventHandledPolicy, devices = deviceArray, availableDevices = m_AvailableDevices?.Take(m_AvailableDeviceCount).ToArray(), buffers = m_StateBuffers, @@ -4119,6 +4145,7 @@ internal void RestoreStateWithoutDevices(SerializedState state) scrollDeltaBehavior = state.scrollDeltaBehavior; m_Metrics = state.metrics; m_PollingFrequency = state.pollingFrequency; + m_InputEventHandledPolicy = state.inputEventHandledPolicy; if (m_Settings != null) Object.DestroyImmediate(m_Settings); diff --git a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs index eb7a35dcd7..d704407f55 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs @@ -1382,6 +1382,31 @@ public static float pollingFrequency set => s_Manager.pollingFrequency = value; } + /// + /// The policy to be applied when processing input events that has been marked as "handled" by setting + /// or to true. + /// + /// + /// The default setting of this property is which + /// implies that events are completely suppressed which means that associated state will not be updated. + /// Hence, any state dependent classes such as or associated interactions will + /// not be updated either. A side-effect of this setting is that succeeding events that are not suppressed + /// may trigger new unexpected events since they may trigger state changes due to monitoring instances not + /// seeing previous changes. + /// + /// The setting will instead allow state change + /// propagation to happen, including updating interaction state, but will instead suppress any associated + /// notifications. + /// + /// The current policy to be applied when processing input events marked as "handled". + /// If attempting to set this property to an unsupported + /// value. + public static InputEventHandledPolicy inputEventHandledPolicy + { + get => s_Manager.inputEventHandledPolicy; + set => s_Manager.inputEventHandledPolicy = value; + } + /// /// Add a new device by instantiating the given device layout. /// From 59b26597f5f85569840e6fbce1bfc86f89901d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Wed, 23 Apr 2025 10:40:43 +0200 Subject: [PATCH 05/21] wip --- Assets/ActionDebug.cs | 3 +-- Assets/Tests/InputSystem/CoreTests_Events.cs | 3 +++ .../InputSystem/Actions/InputActionState.cs | 16 ++++++++++++++++ .../InputSystem/InputManager.cs | 3 ++- .../InputSystem/InputManagerStateMonitors.cs | 1 + .../Plugins/DualShock/DualShockGamepadHID.cs | 1 + .../InputSystem/State/InputState.cs | 1 + 7 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Assets/ActionDebug.cs b/Assets/ActionDebug.cs index bc161e4534..b6fed188c4 100644 --- a/Assets/ActionDebug.cs +++ b/Assets/ActionDebug.cs @@ -4,7 +4,7 @@ public class ActionDebug : MonoBehaviour { public InputActionReference trigger; - + // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { @@ -20,6 +20,5 @@ private void ActionOnperformed(InputAction.CallbackContext obj) // Update is called once per frame void Update() { - } } diff --git a/Assets/Tests/InputSystem/CoreTests_Events.cs b/Assets/Tests/InputSystem/CoreTests_Events.cs index d7ea3677fe..9204007671 100644 --- a/Assets/Tests/InputSystem/CoreTests_Events.cs +++ b/Assets/Tests/InputSystem/CoreTests_Events.cs @@ -1254,6 +1254,9 @@ public void EventHandledPolicy_ShouldReflectUserSetting() public void Events_ShouldRespectHandledPolicyUponUpdate(InputEventHandledPolicy policy, int[] expectedProcessed, int[] expectedCancelled) // EDIT { + // Update setting to match desired scenario + InputSystem.inputEventHandledPolicy = policy; + // Use a boxed boolean to allow lambda to capture reference. var data = new SuppressedActionEventData(); diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs index fe8df0911c..c4ea8d0d15 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs @@ -1346,6 +1346,7 @@ void IInputStateChangeMonitor.NotifyControlStateChanged(InputControl control, do #endif SplitUpMapAndControlAndBindingIndex(mapControlAndBindingIndex, out var mapIndex, out var controlIndex, out var bindingIndex); + // CALLBACK HERE ProcessControlStateChange(mapIndex, controlIndex, bindingIndex, time, eventPtr); } @@ -1537,6 +1538,14 @@ private void ProcessControlStateChange(int mapIndex, int controlIndex, int bindi } else if (!haveInteractionsOnComposite && !isConflictingInput) { + // Skip further notification if event is handled and our policy suppress notifications. + if (eventPtr != null && eventPtr.handled && InputSystem.inputEventHandledPolicy == + InputEventHandledPolicy.SuppressNotifications) + { + return; + } + + // CALLBACK HERE ProcessDefaultInteraction(ref trigger, actionIndex); } } @@ -1939,6 +1948,7 @@ private void ProcessDefaultInteraction(ref TriggerState trigger, int actionIndex var threshold = controls[trigger.controlIndex] is ButtonControl button ? button.pressPointOrDefault : ButtonControl.s_GlobalDefaultButtonPressPoint; if (actuation >= threshold) { + // CALLBACK HERE ChangePhaseOfAction(InputActionPhase.Performed, ref trigger, phaseAfterPerformedOrCanceled: InputActionPhase.Performed); } @@ -2397,6 +2407,7 @@ private bool ChangePhaseOfAction(InputActionPhase newPhase, ref TriggerState tri } else if (actionState->phase != newPhase || newPhase == InputActionPhase.Performed) // We allow Performed to trigger repeatedly. { + // CALLBACK HERE ChangePhaseOfActionInternal(actionIndex, actionState, newPhase, ref trigger, isDisablingAction: newPhase == InputActionPhase.Canceled && phaseAfterPerformedOrCanceled == InputActionPhase.Disabled); if (!actionState->inProcessing) @@ -2491,6 +2502,9 @@ private void ChangePhaseOfActionInternal(int actionIndex, TriggerState* actionSt newState.startTime = newState.time; *actionState = newState; + //if (InputSystem.inputEventHandledPolicy == InputEventHandledPolicy.SuppressNotifications) + // return; + // Let listeners know. var map = maps[trigger.mapIndex]; Debug.Assert(actionIndex >= mapIndices[trigger.mapIndex].actionStartIndex, @@ -2509,6 +2523,7 @@ private void ChangePhaseOfActionInternal(int actionIndex, TriggerState* actionSt case InputActionPhase.Performed: { Debug.Assert(trigger.controlIndex != -1, "Must have control to perform an action"); + // CALLBACK HERE CallActionListeners(actionIndex, map, newPhase, ref action.m_OnPerformed, "performed"); break; } @@ -2562,6 +2577,7 @@ private void CallActionListeners(int actionIndex, InputActionMap actionMap, Inpu } // Run callbacks (if any) directly on action. + // CALLBACK INVOKED HERE DelegateHelpers.InvokeCallbacksSafe(ref listeners, context, callbackName, action); // Run callbacks (if any) on action map. diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs index f7a6585b63..ff60d8f63c 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs @@ -3477,7 +3477,8 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev new InputEventPtr(currentEventReadPtr), device, k_InputOnEventMarker, "InputSystem.onEvent"); // If a listener marks the event as handled, we don't process it further. - if (currentEventReadPtr->handled) + if (m_InputEventHandledPolicy == InputEventHandledPolicy.SuppressProcessing && + currentEventReadPtr->handled) { m_InputEventStream.Advance(false); continue; diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs index 4f061eb193..b1194476ff 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs @@ -391,6 +391,7 @@ internal unsafe void FireStateChangeNotifications(int deviceIndex, double intern var listener = listeners[i]; try { + // CALLBACK HERE listener.monitor.NotifyControlStateChanged(listener.control, time, eventPtr, listener.monitorIndex); } diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs index 3cb6a963ef..85325e7ba1 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs @@ -588,6 +588,7 @@ public unsafe void OnStateEvent(InputEventPtr eventPtr) InputSystem.s_Manager.DontMakeCurrentlyUpdatingDeviceCurrent(); } + // CALLBACK HERE InputState.Change(this, eventPtr); } diff --git a/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs b/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs index 787b5df377..06863027f8 100644 --- a/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs +++ b/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs @@ -75,6 +75,7 @@ public static unsafe void Change(InputDevice device, InputEventPtr eventPtr, Inp $"State format {stateFormat} from event does not match state format {device.stateBlock.format} of device {device}", nameof(eventPtr)); + // CALLBACK HERE InputSystem.s_Manager.UpdateState(device, eventPtr, updateType != default ? updateType : InputSystem.s_Manager.defaultUpdateType); } From e4e57cfc3e61fa70a7f7fb14ea8f16264ab82c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Wed, 23 Apr 2025 13:43:15 +0200 Subject: [PATCH 06/21] Modified handled evaluation in state monitors. Formatting. --- Assets/Tests/InputSystem/CoreTests_Events.cs | 2 +- .../InputSystem/Actions/InputActionState.cs | 4 ++-- Packages/com.unity.inputsystem/InputSystem/InputManager.cs | 2 +- .../InputSystem/InputManagerStateMonitors.cs | 7 ++++--- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Assets/Tests/InputSystem/CoreTests_Events.cs b/Assets/Tests/InputSystem/CoreTests_Events.cs index 9204007671..3259a2fdad 100644 --- a/Assets/Tests/InputSystem/CoreTests_Events.cs +++ b/Assets/Tests/InputSystem/CoreTests_Events.cs @@ -1256,7 +1256,7 @@ public void Events_ShouldRespectHandledPolicyUponUpdate(InputEventHandledPolicy { // Update setting to match desired scenario InputSystem.inputEventHandledPolicy = policy; - + // Use a boxed boolean to allow lambda to capture reference. var data = new SuppressedActionEventData(); diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs index c4ea8d0d15..4b76bfecdc 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs @@ -1544,7 +1544,7 @@ private void ProcessControlStateChange(int mapIndex, int controlIndex, int bindi { return; } - + // CALLBACK HERE ProcessDefaultInteraction(ref trigger, actionIndex); } @@ -2504,7 +2504,7 @@ private void ChangePhaseOfActionInternal(int actionIndex, TriggerState* actionSt //if (InputSystem.inputEventHandledPolicy == InputEventHandledPolicy.SuppressNotifications) // return; - + // Let listeners know. var map = maps[trigger.mapIndex]; Debug.Assert(actionIndex >= mapIndices[trigger.mapIndex].actionStartIndex, diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs index ff60d8f63c..dd4901ccca 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs @@ -3477,7 +3477,7 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev new InputEventPtr(currentEventReadPtr), device, k_InputOnEventMarker, "InputSystem.onEvent"); // If a listener marks the event as handled, we don't process it further. - if (m_InputEventHandledPolicy == InputEventHandledPolicy.SuppressProcessing && + if (m_InputEventHandledPolicy == InputEventHandledPolicy.SuppressProcessing && currentEventReadPtr->handled) { m_InputEventStream.Advance(false); diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs index b1194476ff..87c48e08b9 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs @@ -382,7 +382,7 @@ internal unsafe void FireStateChangeNotifications(int deviceIndex, double intern // Call IStateChangeMonitor.NotifyControlStateChange for every monitor that is in // signalled state. - eventPtr->handled = false; + var savedHandled = eventPtr->handled; for (var i = 0; i < signals.length; ++i) { if (!signals.TestBit(i)) @@ -404,8 +404,9 @@ internal unsafe void FireStateChangeNotifications(int deviceIndex, double intern // If the monitor signalled that it has processed the state change, reset all signalled // state monitors in the same group. This is what causes "SHIFT+B" to prevent "B" from - // also triggering. - if (eventPtr->handled) + // also triggering. Note that we skip this if it was already marked handled before notifying + // monitors. + if (!savedHandled && eventPtr->handled) { var groupIndex = listeners[i].groupIndex; for (var n = i + 1; n < signals.length; ++n) From 00abdcfe9b539f7dc00f34e310041d6cc68843f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Wed, 23 Apr 2025 13:45:22 +0200 Subject: [PATCH 07/21] Renamed variable --- .../InputSystem/InputManagerStateMonitors.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs index 87c48e08b9..96e75f9836 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs @@ -382,7 +382,7 @@ internal unsafe void FireStateChangeNotifications(int deviceIndex, double intern // Call IStateChangeMonitor.NotifyControlStateChange for every monitor that is in // signalled state. - var savedHandled = eventPtr->handled; + var previouslyHandled = eventPtr->handled; for (var i = 0; i < signals.length; ++i) { if (!signals.TestBit(i)) @@ -406,7 +406,7 @@ internal unsafe void FireStateChangeNotifications(int deviceIndex, double intern // state monitors in the same group. This is what causes "SHIFT+B" to prevent "B" from // also triggering. Note that we skip this if it was already marked handled before notifying // monitors. - if (!savedHandled && eventPtr->handled) + if (!previouslyHandled && eventPtr->handled) { var groupIndex = listeners[i].groupIndex; for (var n = i + 1; n < signals.length; ++n) From 9bdd2d23a3bff44a9fef45f9a5b7a5f3b400e030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Wed, 23 Apr 2025 14:14:28 +0200 Subject: [PATCH 08/21] Refactoring of names --- Assets/Tests/InputSystem/CoreTests_Events.cs | 16 ++++++++-------- .../InputSystem/Actions/InputActionState.cs | 2 +- .../Events/InputEventHandledPolicy.cs | 12 ++++++------ .../InputSystem/InputManager.cs | 8 ++++---- .../InputSystem/InputSystem.cs | 4 ++-- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Assets/Tests/InputSystem/CoreTests_Events.cs b/Assets/Tests/InputSystem/CoreTests_Events.cs index 3259a2fdad..c1e176458b 100644 --- a/Assets/Tests/InputSystem/CoreTests_Events.cs +++ b/Assets/Tests/InputSystem/CoreTests_Events.cs @@ -1229,25 +1229,25 @@ class SuppressedActionEventData public void EventHandledPolicy_ShouldReflectUserSetting() { // Assert default setting - Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressProcessing)); + Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressStateUpdates)); // Assert policy can be changed - InputSystem.inputEventHandledPolicy = InputEventHandledPolicy.SuppressNotifications; - Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressNotifications)); + InputSystem.inputEventHandledPolicy = InputEventHandledPolicy.SuppressActionUpdates; + Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressActionUpdates)); // Assert policy can be changed back - InputSystem.inputEventHandledPolicy = InputEventHandledPolicy.SuppressProcessing; - Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressProcessing)); + InputSystem.inputEventHandledPolicy = InputEventHandledPolicy.SuppressStateUpdates; + Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressStateUpdates)); // Assert setting property to an invalid value throws exception and do not have side-effects Assert.Throws(() => InputSystem.inputEventHandledPolicy = (InputEventHandledPolicy)123456); - Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressProcessing)); + Assert.That(InputSystem.inputEventHandledPolicy, Is.EqualTo(InputEventHandledPolicy.SuppressStateUpdates)); } - [TestCase(InputEventHandledPolicy.SuppressProcessing, + [TestCase(InputEventHandledPolicy.SuppressStateUpdates, new int[] { 0, 0, 1, 1}, new int[] {0, 0, 0, 1})] - [TestCase(InputEventHandledPolicy.SuppressNotifications, + [TestCase(InputEventHandledPolicy.SuppressActionUpdates, new int[] { 0, 0, 0, 0}, new int[] {0, 0, 0, 0})] [Category("Events")] [Description("ISXB-1524 Events suppressed has side-effects on actions when based on polling")] diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs index 4b76bfecdc..2ede4ad2a8 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs @@ -1540,7 +1540,7 @@ private void ProcessControlStateChange(int mapIndex, int controlIndex, int bindi { // Skip further notification if event is handled and our policy suppress notifications. if (eventPtr != null && eventPtr.handled && InputSystem.inputEventHandledPolicy == - InputEventHandledPolicy.SuppressNotifications) + InputEventHandledPolicy.SuppressActionUpdates) { return; } diff --git a/Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs b/Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs index c509ca1cbd..a8902cc19c 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Events/InputEventHandledPolicy.cs @@ -1,19 +1,19 @@ namespace UnityEngine.InputSystem.LowLevel { /// - /// Policy defining how the Input System will process instances marked as - /// . + /// Policy defining how the Input System will react to instances marked as + /// (Or marked handled via ). /// public enum InputEventHandledPolicy { /// - /// Input events will be discarded and not propagated for neither state updates nor notifications. + /// Input events will be discarded directly and not propagate for state changes. /// - SuppressProcessing, + SuppressStateUpdates, /// - /// Input events will be processed for state updates but will not trigger interaction nor phase notifications. + /// Input events will be processed for state updates but will not trigger interaction nor phase updates. /// - SuppressNotifications + SuppressActionUpdates } } diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs index dd4901ccca..f3e16896e4 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs @@ -217,8 +217,8 @@ public InputEventHandledPolicy inputEventHandledPolicy { switch (value) { - case InputEventHandledPolicy.SuppressNotifications: - case InputEventHandledPolicy.SuppressProcessing: + case InputEventHandledPolicy.SuppressActionUpdates: + case InputEventHandledPolicy.SuppressStateUpdates: m_InputEventHandledPolicy = value; break; default: @@ -1909,7 +1909,7 @@ internal void InitializeData() m_PollingFrequency = 60; // Default input event handled policy. - m_InputEventHandledPolicy = InputEventHandledPolicy.SuppressProcessing; + m_InputEventHandledPolicy = InputEventHandledPolicy.SuppressStateUpdates; // Register layouts. // NOTE: Base layouts must be registered before their derived layouts @@ -3477,7 +3477,7 @@ private unsafe void OnUpdate(InputUpdateType updateType, ref InputEventBuffer ev new InputEventPtr(currentEventReadPtr), device, k_InputOnEventMarker, "InputSystem.onEvent"); // If a listener marks the event as handled, we don't process it further. - if (m_InputEventHandledPolicy == InputEventHandledPolicy.SuppressProcessing && + if (m_InputEventHandledPolicy == InputEventHandledPolicy.SuppressStateUpdates && currentEventReadPtr->handled) { m_InputEventStream.Advance(false); diff --git a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs index d704407f55..3bbdb32aae 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs @@ -1387,14 +1387,14 @@ public static float pollingFrequency /// or to true. /// /// - /// The default setting of this property is which + /// The default setting of this property is which /// implies that events are completely suppressed which means that associated state will not be updated. /// Hence, any state dependent classes such as or associated interactions will /// not be updated either. A side-effect of this setting is that succeeding events that are not suppressed /// may trigger new unexpected events since they may trigger state changes due to monitoring instances not /// seeing previous changes. /// - /// The setting will instead allow state change + /// The setting will instead allow state change /// propagation to happen, including updating interaction state, but will instead suppress any associated /// notifications. /// From 71e7b616cf35eb58355df11083dc9d575925c76c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Wed, 23 Apr 2025 16:35:05 +0200 Subject: [PATCH 09/21] Updated rebinding UI sample to use new feature (handling policy) --- Assets/ActionDebug.cs | 19 +++++++++++++-- Assets/Samples/RebindingUI/RebindActionUI.cs | 2 +- .../Actions/InputActionRebindingExtensions.cs | 24 +++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Assets/ActionDebug.cs b/Assets/ActionDebug.cs index b6fed188c4..92c35b4856 100644 --- a/Assets/ActionDebug.cs +++ b/Assets/ActionDebug.cs @@ -1,5 +1,6 @@ using UnityEngine; using UnityEngine.InputSystem; +using UnityEngine.InputSystem.LowLevel; public class ActionDebug : MonoBehaviour { @@ -8,11 +9,23 @@ public class ActionDebug : MonoBehaviour // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { - trigger.action.performed += ActionOnperformed; + trigger.action.performed += ActionOnPerformed; + trigger.action.canceled += ActionOnCanceled; + trigger.action.started += ActionOnStarted; trigger.action.Enable(); } - private void ActionOnperformed(InputAction.CallbackContext obj) + private void ActionOnStarted(InputAction.CallbackContext obj) + { + Debug.Log("Action Started"); + } + + private void ActionOnCanceled(InputAction.CallbackContext obj) + { + Debug.Log("Action Canceled"); + } + + private void ActionOnPerformed(InputAction.CallbackContext obj) { Debug.Log("Action Performed"); } @@ -20,5 +33,7 @@ private void ActionOnperformed(InputAction.CallbackContext obj) // Update is called once per frame void Update() { + if (trigger.action.WasPerformedThisFrame()) + Debug.Log("Action Performed (Polled Event)"); } } diff --git a/Assets/Samples/RebindingUI/RebindActionUI.cs b/Assets/Samples/RebindingUI/RebindActionUI.cs index 5f750be78b..41fe2fc790 100644 --- a/Assets/Samples/RebindingUI/RebindActionUI.cs +++ b/Assets/Samples/RebindingUI/RebindActionUI.cs @@ -289,7 +289,7 @@ void CleanUp() UpdateBindingDisplay(); CleanUp(); }) - .OnMatchWaitForAnother(0.2f) + .WithSuppressedActionPropagation() .OnComplete( operation => { diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionRebindingExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionRebindingExtensions.cs index 23ca02c342..31e0bfaae0 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionRebindingExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionRebindingExtensions.cs @@ -2083,6 +2083,23 @@ public RebindingOperation OnMatchWaitForAnother(float seconds) return this; } + /// + /// Ensures state changes are allowed to propagate during rebinding but suppresses action updates. + /// The default behavior is that state changes are also suppressed during rebinding. + /// + /// + /// This is achieved by temporarily setting to + /// . This is automatically reverted when + /// the rebinding operation completes. If the policy is already set to + /// , this method has no effect. + /// + /// Reference to this rebinding operation. + public RebindingOperation WithSuppressedActionPropagation() + { + m_TargetInputEventHandledPolicy = InputEventHandledPolicy.SuppressActionUpdates; + return this; + } + /// /// Start the rebinding. This should be invoked after the rebind operation has been fully configured. /// @@ -2107,6 +2124,9 @@ public RebindingOperation Start() m_StartTime = InputState.currentTime; + m_SavedInputEventHandledPolicy = InputSystem.inputEventHandledPolicy; + InputSystem.inputEventHandledPolicy = m_TargetInputEventHandledPolicy; + if (m_WaitSecondsAfterMatch > 0 || m_Timeout > 0) { HookOnAfterUpdate(); @@ -2606,6 +2626,8 @@ private void ResetAfterMatchCompleted() UnhookOnEvent(); UnhookOnAfterUpdate(); + + InputSystem.inputEventHandledPolicy = m_SavedInputEventHandledPolicy; } private void ThrowIfRebindInProgress() @@ -2654,6 +2676,8 @@ private string GeneratePathForControl(InputControl control) private double m_StartTime; private float m_Timeout; private float m_WaitSecondsAfterMatch; + private InputEventHandledPolicy m_SavedInputEventHandledPolicy; + private InputEventHandledPolicy m_TargetInputEventHandledPolicy; private InputControlList m_Candidates; private Action m_OnComplete; private Action m_OnCancel; From b50d660eed92a835afa29b8c6aaece9a342f6a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Wed, 23 Apr 2025 16:59:31 +0200 Subject: [PATCH 10/21] Undo of previous change --- .../RebindingUI/RebindingUISampleScene.unity | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Assets/Samples/RebindingUI/RebindingUISampleScene.unity b/Assets/Samples/RebindingUI/RebindingUISampleScene.unity index 68cfad33e0..9b099358d1 100644 --- a/Assets/Samples/RebindingUI/RebindingUISampleScene.unity +++ b/Assets/Samples/RebindingUI/RebindingUISampleScene.unity @@ -1176,19 +1176,6 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &780148238 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 780148234} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 7d36843388d90a04782f5f49339e23c4, type: 3} - m_Name: - m_EditorClassIdentifier: - trigger: {fileID: 2345695455583553484, guid: 7dead05c54ca85b4681351aafd8bd03a, type: 3} --- !u!1 &861395291 GameObject: m_ObjectHideFlags: 0 From 9c6b2d8dc5bc31bc8aef8344f04e19569a947e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Wed, 23 Apr 2025 17:02:42 +0200 Subject: [PATCH 11/21] Undo previous change --- Assets/Samples/RebindingUI/RebindingUISampleScene.unity | 1 - 1 file changed, 1 deletion(-) diff --git a/Assets/Samples/RebindingUI/RebindingUISampleScene.unity b/Assets/Samples/RebindingUI/RebindingUISampleScene.unity index 9b099358d1..0908be1603 100644 --- a/Assets/Samples/RebindingUI/RebindingUISampleScene.unity +++ b/Assets/Samples/RebindingUI/RebindingUISampleScene.unity @@ -1096,7 +1096,6 @@ GameObject: - component: {fileID: 780148237} - component: {fileID: 780148236} - component: {fileID: 780148235} - - component: {fileID: 780148238} m_Layer: 0 m_Name: EventSystem m_TagString: Untagged From 2d195ed5fd4a6ccefa38eb9ce8270a57b1c89ac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Wed, 23 Apr 2025 17:11:47 +0200 Subject: [PATCH 12/21] Made input manager property internal for now --- Packages/com.unity.inputsystem/InputSystem/InputManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs index f3e16896e4..574c41d76e 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs @@ -210,7 +210,7 @@ public float pollingFrequency } } - public InputEventHandledPolicy inputEventHandledPolicy + internal InputEventHandledPolicy inputEventHandledPolicy { get => m_InputEventHandledPolicy; set From f9c61f5ee8de4eaa600ffbce7840921f8f40c85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Wed, 23 Apr 2025 21:06:05 +0200 Subject: [PATCH 13/21] Attempt to fix xml syntax error for doc --- Assets/ActionDebug.cs | 1 - Packages/com.unity.inputsystem/InputSystem/InputSystem.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/Assets/ActionDebug.cs b/Assets/ActionDebug.cs index 92c35b4856..0eddde4e6e 100644 --- a/Assets/ActionDebug.cs +++ b/Assets/ActionDebug.cs @@ -1,6 +1,5 @@ using UnityEngine; using UnityEngine.InputSystem; -using UnityEngine.InputSystem.LowLevel; public class ActionDebug : MonoBehaviour { diff --git a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs index 3bbdb32aae..d03e2abcd0 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs @@ -1398,7 +1398,6 @@ public static float pollingFrequency /// propagation to happen, including updating interaction state, but will instead suppress any associated /// notifications. /// - /// The current policy to be applied when processing input events marked as "handled". /// If attempting to set this property to an unsupported /// value. public static InputEventHandledPolicy inputEventHandledPolicy From 10d25794bdf1e430bfff320036ebc174049262e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Wed, 23 Apr 2025 21:16:58 +0200 Subject: [PATCH 14/21] Updated changelog --- Packages/com.unity.inputsystem/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index 937a8b364f..ada9c24081 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -10,6 +10,9 @@ however, it has to be formatted properly to pass verification tests. ## [Unreleased] - yyyy-mm-dd +### Added +- Added a new run-time setting `InputSystem.inputEventHandledPolicy` which allows changing how the system processes input events marked as "handled". The new alternative setting (not default) allows for allowing handled events to propagate into state changes but still suppresses action interactions from being processed. + ### Fixed - Fixed an analytics event being invoked twice when the Save button in the Actions view was pressed. [ISXB-1378](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1378) - Fixed an issue causing a number of errors to be displayed when using `InputTestFixture` in playmode tests with domain reloading disabled on playmode entry. [ISXB-1446](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1446) @@ -20,6 +23,7 @@ however, it has to be formatted properly to pass verification tests. - Fixed Input Actions code generation using locale-dependent rules when lowercasing and uppercasing strings. [ISXB-1406] - Fixed an issue when providing JoinPlayer with a specific split screen index. [ISXB-897](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-897) - Fixed an issue where an action with a name containing a slash "/" could not be found via `InputActionAsset.FindAction(string,bool)`. [ISXB-1306](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1306). +- Fixed an issue in `RebindingUISample` that fired actions bound to the same control as the target control in a rebinding process. ISXB-1524. ## [1.14.0] - 2025-03-20 From edbdbcf93eb46c1e19b245132fd78d6f931e5a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kan=20Sidenvall?= Date: Thu, 24 Apr 2025 14:16:31 +0200 Subject: [PATCH 15/21] Removed ActionDebug script from branch --- Assets/ActionDebug.cs | 38 -------------------------------------- Assets/ActionDebug.cs.meta | 2 -- 2 files changed, 40 deletions(-) delete mode 100644 Assets/ActionDebug.cs delete mode 100644 Assets/ActionDebug.cs.meta diff --git a/Assets/ActionDebug.cs b/Assets/ActionDebug.cs deleted file mode 100644 index 0eddde4e6e..0000000000 --- a/Assets/ActionDebug.cs +++ /dev/null @@ -1,38 +0,0 @@ -using UnityEngine; -using UnityEngine.InputSystem; - -public class ActionDebug : MonoBehaviour -{ - public InputActionReference trigger; - - // Start is called once before the first execution of Update after the MonoBehaviour is created - void Start() - { - trigger.action.performed += ActionOnPerformed; - trigger.action.canceled += ActionOnCanceled; - trigger.action.started += ActionOnStarted; - trigger.action.Enable(); - } - - private void ActionOnStarted(InputAction.CallbackContext obj) - { - Debug.Log("Action Started"); - } - - private void ActionOnCanceled(InputAction.CallbackContext obj) - { - Debug.Log("Action Canceled"); - } - - private void ActionOnPerformed(InputAction.CallbackContext obj) - { - Debug.Log("Action Performed"); - } - - // Update is called once per frame - void Update() - { - if (trigger.action.WasPerformedThisFrame()) - Debug.Log("Action Performed (Polled Event)"); - } -} diff --git a/Assets/ActionDebug.cs.meta b/Assets/ActionDebug.cs.meta deleted file mode 100644 index 93697c7c4a..0000000000 --- a/Assets/ActionDebug.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 7d36843388d90a04782f5f49339e23c4 \ No newline at end of file From 1baba6c7a82b9f6bf87a739b976cd0a3e60fafae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kan=20Sidenvall?= Date: Thu, 24 Apr 2025 14:24:28 +0200 Subject: [PATCH 16/21] Undo changes to UI sample actions --- .../RebindUISampleActions.inputactions | 29 ++----------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/Assets/Samples/RebindingUI/RebindUISampleActions.inputactions b/Assets/Samples/RebindingUI/RebindUISampleActions.inputactions index 662218926d..0c0478cf71 100644 --- a/Assets/Samples/RebindingUI/RebindUISampleActions.inputactions +++ b/Assets/Samples/RebindingUI/RebindUISampleActions.inputactions @@ -11,8 +11,7 @@ "id": "9d8fcbff-87d1-43ef-857e-931c84d5bd72", "expectedControlType": "Vector2", "processors": "", - "interactions": "", - "initialStateCheck": true + "interactions": "" }, { "name": "Look", @@ -20,8 +19,7 @@ "id": "ddab72da-d325-4b4c-a484-abe4f6bdf113", "expectedControlType": "Vector2", "processors": "", - "interactions": "", - "initialStateCheck": true + "interactions": "" }, { "name": "Interact", @@ -29,17 +27,7 @@ "id": "2bd60403-0923-469e-a3a4-7338b04f6bbc", "expectedControlType": "", "processors": "", - "interactions": "", - "initialStateCheck": false - }, - { - "name": "Test", - "type": "Button", - "id": "a0bbd927-54af-4ba8-be59-8470a31efd79", - "expectedControlType": "", - "processors": "", - "interactions": "", - "initialStateCheck": false + "interactions": "" } ], "bindings": [ @@ -152,17 +140,6 @@ "action": "Interact", "isComposite": false, "isPartOfComposite": false - }, - { - "name": "", - "id": "60a650d1-dafb-4f35-bfb4-94d9974472fb", - "path": "/buttonNorth", - "interactions": "", - "processors": "", - "groups": "", - "action": "Test", - "isComposite": false, - "isPartOfComposite": false } ] } From b7d8a101517ee325730ea66abb7b8b623b607ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kan=20Sidenvall?= Date: Thu, 24 Apr 2025 14:42:44 +0200 Subject: [PATCH 17/21] Removed debug comments --- .../InputSystem/Plugins/DualShock/DualShockGamepadHID.cs | 3 +-- Packages/com.unity.inputsystem/InputSystem/State/InputState.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs index 85325e7ba1..bbf8c798d7 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs @@ -587,8 +587,7 @@ public unsafe void OnStateEvent(InputEventPtr eventPtr) if (!actuated) InputSystem.s_Manager.DontMakeCurrentlyUpdatingDeviceCurrent(); } - - // CALLBACK HERE + InputState.Change(this, eventPtr); } diff --git a/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs b/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs index 06863027f8..fecc612a8a 100644 --- a/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs +++ b/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs @@ -74,8 +74,7 @@ public static unsafe void Change(InputDevice device, InputEventPtr eventPtr, Inp throw new ArgumentException( $"State format {stateFormat} from event does not match state format {device.stateBlock.format} of device {device}", nameof(eventPtr)); - - // CALLBACK HERE + InputSystem.s_Manager.UpdateState(device, eventPtr, updateType != default ? updateType : InputSystem.s_Manager.defaultUpdateType); } From 69aa686a15ab04e37b6d42a0c0b8e11fcab4d716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kan=20Sidenvall?= Date: Thu, 24 Apr 2025 14:46:20 +0200 Subject: [PATCH 18/21] Formatting --- .../InputSystem/Plugins/DualShock/DualShockGamepadHID.cs | 2 +- Packages/com.unity.inputsystem/InputSystem/State/InputState.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs index bbf8c798d7..3cb6a963ef 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/DualShock/DualShockGamepadHID.cs @@ -587,7 +587,7 @@ public unsafe void OnStateEvent(InputEventPtr eventPtr) if (!actuated) InputSystem.s_Manager.DontMakeCurrentlyUpdatingDeviceCurrent(); } - + InputState.Change(this, eventPtr); } diff --git a/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs b/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs index fecc612a8a..787b5df377 100644 --- a/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs +++ b/Packages/com.unity.inputsystem/InputSystem/State/InputState.cs @@ -74,7 +74,7 @@ public static unsafe void Change(InputDevice device, InputEventPtr eventPtr, Inp throw new ArgumentException( $"State format {stateFormat} from event does not match state format {device.stateBlock.format} of device {device}", nameof(eventPtr)); - + InputSystem.s_Manager.UpdateState(device, eventPtr, updateType != default ? updateType : InputSystem.s_Manager.defaultUpdateType); } From 7d07d89910e04200af6477eb4a66e65249599691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kan=20Sidenvall?= Date: Thu, 24 Apr 2025 14:49:49 +0200 Subject: [PATCH 19/21] Undo debug comment --- .../InputSystem/InputManagerStateMonitors.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs index 96e75f9836..17c95db457 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs @@ -391,7 +391,6 @@ internal unsafe void FireStateChangeNotifications(int deviceIndex, double intern var listener = listeners[i]; try { - // CALLBACK HERE listener.monitor.NotifyControlStateChanged(listener.control, time, eventPtr, listener.monitorIndex); } From eed66dc12017b0be43211ae8f872b6c789eb4d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kan=20Sidenvall?= Date: Thu, 24 Apr 2025 15:36:17 +0200 Subject: [PATCH 20/21] Further tweaks of logic --- .../InputSystem/Actions/InputActionState.cs | 13 +++++-------- .../InputSystem/InputManager.cs | 3 --- .../InputSystem/InputManagerStateMonitors.cs | 9 +++++---- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs index 2ede4ad2a8..f81432ab8a 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionState.cs @@ -1517,6 +1517,10 @@ private void ProcessControlStateChange(int mapIndex, int controlIndex, int bindi } } + // Check if we should suppress interaction processing + var suppressInteractionProcessing = (eventPtr != null) && eventPtr.handled && + InputSystem.inputEventHandledPolicy == InputEventHandledPolicy.SuppressActionUpdates; + // Check if we have multiple concurrent actuations on the same action. This may lead us // to ignore certain inputs (e.g. when we get an input of lesser magnitude while already having // one of higher magnitude) or may even lead us to switch to processing a different binding @@ -1538,14 +1542,7 @@ private void ProcessControlStateChange(int mapIndex, int controlIndex, int bindi } else if (!haveInteractionsOnComposite && !isConflictingInput) { - // Skip further notification if event is handled and our policy suppress notifications. - if (eventPtr != null && eventPtr.handled && InputSystem.inputEventHandledPolicy == - InputEventHandledPolicy.SuppressActionUpdates) - { - return; - } - - // CALLBACK HERE + //if (!suppressInteractionProcessing) ProcessDefaultInteraction(ref trigger, actionIndex); } } diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs index 574c41d76e..69dcbd8941 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManager.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManager.cs @@ -3923,11 +3923,8 @@ internal unsafe bool UpdateState(InputDevice device, InputUpdateType updateType, } // Notify listeners. - //if (eventPtr == null || !eventPtr.handled) // EDIT - //{ DelegateHelpers.InvokeCallbacksSafe(ref m_DeviceStateChangeListeners, device, eventPtr, k_InputOnDeviceSettingsChangeMarker, "InputSystem.onDeviceStateChange"); - //} // Now that we've committed the new state to memory, if any of the change // monitors fired, let the associated actions know. diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs index 17c95db457..6a54ab86e8 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs @@ -421,11 +421,12 @@ internal unsafe void FireStateChangeNotifications(int deviceIndex, double intern if (listeners[n].groupIndex == groupIndex && listeners[n].monitor == listener.monitor) signals.ClearBit(n); } - - // Need to reset it back to false as we may have more signalled state monitors that - // aren't in the same group (i.e. have independent inputs). - eventPtr->handled = false; } + + // Need to reset it back to false as we may have more signalled state monitors that + // aren't in the same group (i.e. have independent inputs). + if (eventPtr->handled) + eventPtr->handled = false; signals.ClearBit(i); } From c39c1c0436ffb3f2713d20e0d83e6dd13415bab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Mon, 28 Apr 2025 13:23:53 +0200 Subject: [PATCH 21/21] Fixed formatting --- .../InputSystem/InputManagerStateMonitors.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs index 6a54ab86e8..74d72d023b 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs @@ -422,7 +422,7 @@ internal unsafe void FireStateChangeNotifications(int deviceIndex, double intern signals.ClearBit(n); } } - + // Need to reset it back to false as we may have more signalled state monitors that // aren't in the same group (i.e. have independent inputs). if (eventPtr->handled)