Skip to content

Commit 074b26b

Browse files
author
Rene Damm
authored
CHANGE: UI module now defaults to having DefaultInputActions (case 1359306, #1397).
1 parent 967a251 commit 074b26b

File tree

8 files changed

+295
-48
lines changed

8 files changed

+295
-48
lines changed

Assets/Tests/InputSystem/CoreTests_Actions.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,21 +1536,41 @@ public void Actions_ResettingDevice_CancelsOngoingActionsThatAreDrivenByIt()
15361536
// Create an action that performs on button *up*. This way we can tell whether
15371537
// the action is truly cancelled or whether it simply gets triggered by us
15381538
// resetting the corresponding device state.
1539-
var buttonReleaseAction = new InputAction(type: InputActionType.Button, binding: "<Gamepad>/buttonSouth",
1539+
var buttonReleaseAction = new InputAction(name: "button", type: InputActionType.Button, binding: "<Gamepad>/buttonSouth",
15401540
interactions: "press(behavior=1)");
15411541
buttonReleaseAction.Enable();
15421542

1543+
var valueAction = new InputAction(name: "value", type: InputActionType.Value, binding: "<Gamepad>/buttonSouth");
1544+
valueAction.Enable();
1545+
1546+
var passThroughAction = new InputAction(name: "passthrough", type: InputActionType.PassThrough, binding: "<Gamepad>/buttonSouth");
1547+
passThroughAction.Enable();
1548+
15431549
Press(gamepad.buttonSouth);
15441550

15451551
Assert.That(buttonReleaseAction.phase, Is.EqualTo(InputActionPhase.Started));
15461552
Assert.That(buttonReleaseAction.activeControl, Is.SameAs(gamepad.buttonSouth));
15471553

1554+
Assert.That(valueAction.phase, Is.EqualTo(InputActionPhase.Started)); // Goes back to Started after Performed.
1555+
Assert.That(valueAction.activeControl, Is.SameAs(gamepad.buttonSouth));
1556+
1557+
Assert.That(passThroughAction.phase, Is.EqualTo(InputActionPhase.Performed));
1558+
Assert.That(passThroughAction.activeControl, Is.SameAs(gamepad.buttonSouth));
1559+
15481560
using (var buttonReleaseActionTrace = new InputActionTrace(buttonReleaseAction))
1561+
using (var valueActionTrace = new InputActionTrace(valueAction))
1562+
using (var passThroughActionTrace = new InputActionTrace(passThroughAction))
15491563
{
15501564
InputSystem.ResetDevice(gamepad);
15511565

1552-
Assert.That(buttonReleaseActionTrace,
1553-
Canceled(buttonReleaseAction));
1566+
Assert.That(buttonReleaseActionTrace, Canceled(buttonReleaseAction));
1567+
Assert.That(valueActionTrace, Canceled(valueAction));
1568+
1569+
// This case is quirky. For button and value actions, the reset of the control value
1570+
// does not cause the action to start back up. For pass-through actions, that is different
1571+
// as *any* value change performs the action. So here, we see *both* a cancellation and then
1572+
// immediately a performing of the action.
1573+
Assert.That(passThroughActionTrace, Canceled(passThroughAction).AndThen(Performed(passThroughAction, value: 0f)));
15541574
}
15551575
}
15561576

Assets/Tests/InputSystem/Plugins/UITests.cs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ private static TestObjects CreateTestUI(Rect viewport = default, bool noFirstSel
109109
var systemObject = new GameObject(namePrefix + "System");
110110
objects.eventSystem = systemObject.AddComponent<TestEventSystem>();
111111
var uiModule = systemObject.AddComponent<InputSystemUIInputModule>();
112+
uiModule.UnassignActions();
112113
objects.uiModule = uiModule;
113114
objects.eventSystem.UpdateModules();
114115

@@ -182,6 +183,40 @@ private static TestObjects CreateTestUI(Rect viewport = default, bool noFirstSel
182183
return objects;
183184
}
184185

186+
[Test]
187+
[Category("UI")]
188+
public void UI_InputModuleHasDefaultActions()
189+
{
190+
var go = new GameObject();
191+
var uiModule = go.AddComponent<InputSystemUIInputModule>();
192+
193+
Assert.That(uiModule.actionsAsset, Is.Not.Null);
194+
Assert.That(uiModule.point?.action, Is.SameAs(uiModule.actionsAsset["UI/Point"]));
195+
Assert.That(uiModule.leftClick?.action, Is.SameAs(uiModule.actionsAsset["UI/Click"]));
196+
Assert.That(uiModule.rightClick?.action, Is.SameAs(uiModule.actionsAsset["UI/RightClick"]));
197+
Assert.That(uiModule.middleClick?.action, Is.SameAs(uiModule.actionsAsset["UI/MiddleClick"]));
198+
Assert.That(uiModule.scrollWheel?.action, Is.SameAs(uiModule.actionsAsset["UI/ScrollWheel"]));
199+
Assert.That(uiModule.submit?.action, Is.SameAs(uiModule.actionsAsset["UI/Submit"]));
200+
Assert.That(uiModule.cancel?.action, Is.SameAs(uiModule.actionsAsset["UI/Cancel"]));
201+
Assert.That(uiModule.move?.action, Is.SameAs(uiModule.actionsAsset["UI/Navigate"]));
202+
Assert.That(uiModule.trackedDeviceOrientation?.action, Is.SameAs(uiModule.actionsAsset["UI/TrackedDeviceOrientation"]));
203+
Assert.That(uiModule.trackedDevicePosition?.action, Is.SameAs(uiModule.actionsAsset["UI/TrackedDevicePosition"]));
204+
205+
uiModule.UnassignActions();
206+
207+
Assert.That(uiModule.actionsAsset, Is.Null);
208+
Assert.That(uiModule.point, Is.Null);
209+
Assert.That(uiModule.leftClick, Is.Null);
210+
Assert.That(uiModule.rightClick, Is.Null);
211+
Assert.That(uiModule.middleClick, Is.Null);
212+
Assert.That(uiModule.scrollWheel, Is.Null);
213+
Assert.That(uiModule.submit, Is.Null);
214+
Assert.That(uiModule.cancel, Is.Null);
215+
Assert.That(uiModule.move, Is.Null);
216+
Assert.That(uiModule.trackedDeviceOrientation, Is.Null);
217+
Assert.That(uiModule.trackedDevicePosition, Is.Null);
218+
}
219+
185220
// Comprehensive test for general pointer input behaviors.
186221
// NOTE: The behavior we test for here is slightly *DIFFERENT* than what you get with StandaloneInputModule. The reason is that
187222
// StandaloneInputModule has both lots of inconsistencies between touch and mouse input (example: touch press handling goes
@@ -3371,8 +3406,8 @@ public IEnumerator UI_WhenAppLosesAndRegainsFocus_WhileUIButtonIsPressed_UIButto
33713406

33723407
Assert.That(scene.actions.UI.Click.phase.IsInProgress(), Is.True);
33733408

3374-
var clickWasCanceled = false;
3375-
scene.actions.UI.Click.canceled += _ => clickWasCanceled = true;
3409+
var clickCanceled = 0;
3410+
scene.actions.UI.Click.canceled += _ => ++ clickCanceled;
33763411

33773412
yield return null;
33783413

@@ -3391,7 +3426,7 @@ public IEnumerator UI_WhenAppLosesAndRegainsFocus_WhileUIButtonIsPressed_UIButto
33913426
scene.leftChildReceiver.events.Clear();
33923427

33933428
runtime.PlayerFocusLost();
3394-
Assert.That(clickWasCanceled, Is.True);
3429+
Assert.That(clickCanceled, Is.EqualTo(1));
33953430
scene.eventSystem.SendMessage("OnApplicationFocus", false);
33963431

33973432
Assert.That(scene.leftChildReceiver.events, Is.Empty);

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,26 @@ however, it has to be formatted properly to pass verification tests.
1616
* This caused a regression with some setups that, for example, bound the same control multiple times in a composite using processors to alter the value of the control.
1717
* Internally, a control is now again allowed to feed into the same action through more than one binding.
1818
* However, externally the control will be mentioned on the action's `InputAction.controls` list only once.
19+
- Adding `InputSystemUIInputModule` from code now installs `DefaultInputActions`. This is equivalent to the default setup when adding the component in the editor ([case 1259306](https://issuetracker.unity3d.com/issues/input-system-ugui-button-does-not-react-when-clicked)).
20+
```CSharp
21+
var go = new GameObject();
22+
go.AddComponent<EventSystem>();
23+
var uiModule = go.AddComponent<InputSystemUIInputModule>();
24+
// uiModule.actionsAsset now has a DefaultInputActions() asset assigned to it and the various
25+
// action references point to its actions.
26+
```
27+
* `InputSystemUIInputModule.UnassignActions` has been added to remove all actions from the module en bloc.
28+
```CSharp
29+
uiModule.UnassignActions();
30+
```
1931

2032
### Fixed
2133

2234
- Fixed an issue where mixing test cases based on `InputTestFixture` (using mocked `InputSystem`) and regular test cases (using real `InputSystem`) would lead to static state leaking between test cases causing random failures and unexpected/undefined behavior ([case 1329015](https://issuetracker.unity3d.com/product/unity/issues/guid/1329015)).
35+
- Fixed `InputSystemUIInputModule.AssignDefaultActions` not assigning `trackedDeviceOrientation` and `trackedDevicePosition`.
36+
- Fixed regression introduced by [previous change](#ui_multiple_scenes_fix) where `InputSystemUIInputModule` would not disable actions correctly.
37+
- Fixed `InputAction.canceled` not getting triggered reliably for `InputActionType.PassThrough` actions when `InputSystem.ResetDevice` was called.
38+
- Fixed device resets (e.g. happening as part of focus changes) leading to only some actions bound to these devices getting cancelled instead of all of them.
2339

2440
## [1.1.0-pre.6] - 2021-08-23
2541

@@ -185,7 +201,7 @@ however, it has to be formatted properly to pass verification tests.
185201
- Fixed `AxisDeadzoneProcessor` min/max values not being settable to 0 in editor UI ([case 1293744](https://issuetracker.unity3d.com/issues/input-system-input-system-axis-deadzone-minimum-value-fallsback-to-default-value-if-its-set-to-0)).
186202
- Fixed blurry icons in input debugger, asset editor, input settings ([case 1299595](https://issuetracker.unity3d.com/issues/inputsystem-supported-device-list-dropdown-icons-present-under-project-settings-are-not-user-friendly)).
187203
- Fixed `clickCount` not being incremented correctly by `InputSystemUIInputModule` for successive mouse clicks ([case 1317239](https://issuetracker.unity3d.com/issues/eventdata-dot-clickcount-doesnt-increase-when-clicking-repeatedly-in-the-new-input-system)).
188-
- Fixed UI not working after additively loading scenes with additional InputSystemUIInputModule modules ([case 1251720](https://issuetracker.unity3d.com/issues/input-system-buttons-cannot-be-pressed-after-additively-loading-scenes-with-additional-event-systems)).
204+
- <a name="ui_multiple_scenes_fix"></a>Fixed UI not working after additively loading scenes with additional InputSystemUIInputModule modules ([case 1251720](https://issuetracker.unity3d.com/issues/input-system-buttons-cannot-be-pressed-after-additively-loading-scenes-with-additional-event-systems)).
189205
- Fixed no `OnPointerExit` received when changing UI state without moving pointer ([case 1232705](https://issuetracker.unity3d.com/issues/input-system-onpointerexit-is-not-triggered-when-a-ui-element-interrupts-a-mouse-hover)).
190206
- Fixed reference to `.inputactions` of `Player Prefab` referenced by `PlayerInputManager` being destroyed on going into play mode, if the player prefab was a nested prefab ([case 1319756](https://issuetracker.unity3d.com/issues/playerinput-component-loses-its-reference-to-an-inputactionasset)).
191207
- Fixed "Scheme Name" label clipped in "Add Control Schema" popup window ([case 1199560]https://issuetracker.unity3d.com/issues/themes-input-system-scheme-name-is-clipped-in-add-control-schema-window-with-inter-default-font)).

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

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace UnityEngine.InputSystem
88
{
99
/// <summary>
10-
/// Trigger phase of an <see cref="InputAction">action</see>.
10+
/// Trigger phase of an <see cref="InputAction"/>.
1111
/// </summary>
1212
/// <remarks>
1313
/// Actions can be triggered in steps. For example, a <see cref="SlowTapInteraction">
@@ -17,6 +17,11 @@ namespace UnityEngine.InputSystem
1717
/// the button is release before the timer expires, the action will be <see cref="Canceled"/>
1818
/// whereas if the button is held long enough, the action will be <see cref="Performed"/>.
1919
/// </remarks>
20+
/// <seealso cref="InputAction.phase"/>
21+
/// <seealso cref="InputAction.CallbackContext.phase"/>
22+
/// <seealso cref="InputAction.started"/>
23+
/// <seealso cref="InputAction.performed"/>
24+
/// <seealso cref="InputAction.canceled"/>
2025
public enum InputActionPhase
2126
{
2227
/// <summary>
@@ -26,18 +31,16 @@ public enum InputActionPhase
2631

2732
/// <summary>
2833
/// The action is enabled and waiting for input on its associated controls.
29-
/// </summary>
30-
/// <remarks>
34+
///
3135
/// This is the phase that an action goes back to once it has been <see cref="Performed"/>
3236
/// or <see cref="Canceled"/>.
33-
/// </remarks>
37+
/// </summary>
3438
Waiting,
3539

3640
/// <summary>
3741
/// An associated control has been actuated such that it may lead to the action
38-
/// being triggered.
39-
/// </summary>
40-
/// <remarks>
42+
/// being triggered. Will lead to <see cref="InputAction.started"/> getting called.
43+
///
4144
/// This phase will only be invoked if there are interactions on the respective control
4245
/// binding. Without any interactions, an action will go straight from <see cref="Waiting"/>
4346
/// into <see cref="Performed"/> and back into <see cref="Waiting"/> whenever an associated
@@ -53,7 +56,7 @@ public enum InputActionPhase
5356
///
5457
/// <see cref="Started"/> can be useful for UI feedback. For example, in a game where the weapon can be charged,
5558
/// UI feedback can be initiated when the action is <see cref="Started"/>.
56-
/// </remarks>
59+
///
5760
/// <example>
5861
/// <code>
5962
/// fireAction.started +=
@@ -78,18 +81,55 @@ public enum InputActionPhase
7881
/// }
7982
/// </code>
8083
/// </example>
84+
///
85+
/// By default, an action is started as soon as a control moves away from its default value. This is
86+
/// the case for both <see cref="InputActionType.Button"/> actions (which, however, does not yet have to mean
87+
/// that the button press threshold has been reached; see <see cref="InputSettings.defaultButtonPressPoint"/>)
88+
/// and <see cref="InputActionType.Value"/> actions. <see cref="InputActionType.PassThrough"/> does not use
89+
/// the <c>Started</c> phase and instead goes straight to <see cref="Performed"/>.
90+
///
91+
/// For <see cref="InputActionType.Value"/> actions, <c>Started</c> will immediately be followed by <see cref="Performed"/>.
92+
///
93+
/// Note that interactions (see <see cref="IInputInteraction"/>) can alter how an action does or does not progress through
94+
/// the phases.
95+
/// </summary>
8196
Started,
8297

8398
/// <summary>
99+
/// The action has been performed. Leads to <see cref="InputAction.performed"/> getting called.
84100
///
101+
/// By default, a <see cref="InputActionType.Button"/> action performs when a control crosses the button
102+
/// press threshold (see <see cref="InputSettings.defaultButtonPressPoint"/>), a <see cref="InputActionType.Value"/>
103+
/// action performs on any value change that isn't the default value, and a <see cref="InputActionType.PassThrough"/>
104+
/// action performs on any value change including going back to the default value.
105+
///
106+
/// Note that interactions (see <see cref="IInputInteraction"/>) can alter how an action does or does not progress through
107+
/// the phases.
108+
///
109+
/// For a given action, finding out whether it was performed in the current frame can be done with <see cref="InputAction.WasPerformedThisFrame"/>.
110+
///
111+
/// <example>
112+
/// <code>
113+
/// action.WasPerformedThisFrame();
114+
/// </code>
115+
/// </example>
85116
/// </summary>
86-
/// <seealso cref="InputAction.performed"/>
87117
Performed,
88118

89119
/// <summary>
120+
/// The action has stopped. Leads to <see cref="InputAction.canceled"/> getting called.
121+
///
122+
/// By default, a <see cref="InputActionType.Button"/> action cancels when a control falls back below the button
123+
/// press threshold (see <see cref="InputSettings.defaultButtonPressPoint"/>) and a <see cref="InputActionType.Value"/>
124+
/// action cancels when a control moves back to its default value. A <see cref="InputActionType.PassThrough"/> action
125+
/// does not generally cancel based on input on its controls.
126+
///
127+
/// An action will also get canceled when it is disabled while in progress (see <see cref="InputAction.Disable"/>).
128+
/// Also, when an <see cref="InputDevice"/> that is
90129
///
130+
/// Note that interactions (see <see cref="IInputInteraction"/>) can alter how an action does or does not progress through
131+
/// the phases.
91132
/// </summary>
92-
/// <seealso cref="InputAction.canceled"/>
93133
Canceled
94134
}
95135
}

0 commit comments

Comments
 (0)