Skip to content

Commit 596c508

Browse files
FIX: Allow default UI actions to work without setting up a project-wide actions file (ISXB-811). (#1899)
* FIX: Allow default UI actions to work without setting up a project-wide actions file (ISXB-833). Also, fix newlines not functioning correctly in uxml file. * Evaluate InputSystemProvider has an asset This makes sure that InputForUI input will not break during tests. * Add tests which use and remove project-wide actions Evaluates that there is an action asset fallback in case there are no project-wide actions. * Fix formatting issues * Don't need to pass around a member variable. * Restrict visibility of private member variable to only share what's required. * Update CHANGELOG.md * Move assertion to separate test. --------- Co-authored-by: João Freire <[email protected]>
1 parent 19cb9dc commit 596c508

File tree

4 files changed

+91
-33
lines changed

4 files changed

+91
-33
lines changed

Assets/Tests/InputSystem/Plugins/InputForUITests.cs

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,9 @@ public override void Setup()
3131
{
3232
base.Setup();
3333

34-
// Test assumes a compatible project-wide action configuration exist for UI
35-
// See CoreTests_ProjectWideActions for how its setup via build plugins.
36-
Assert.That(InputSystem.actions, Is.Not.Null,
37-
"Test is invalid since Project-wide Input System actions have not been setup for play-mode test environment");
38-
3934
m_InputSystemProvider = new InputSystemProvider();
4035
EventProvider.SetMockProvider(m_InputSystemProvider);
36+
4137
// Register at least one consumer so the mock update gets invoked
4238
EventProvider.Subscribe(InputForUIOnEvent);
4339
}
@@ -58,6 +54,15 @@ private bool InputForUIOnEvent(in Event ev)
5854
return true;
5955
}
6056

57+
[Test]
58+
[Category("InputForUI")]
59+
public void InputSystemActionAssetIsNotNull()
60+
{
61+
// Test assumes a compatible action asset configuration exists for UI
62+
Assert.IsTrue(m_InputSystemProvider.ActionAssetIsNotNull(),
63+
"Test is invalid since InputSystemProvider actions are not available");
64+
}
65+
6166
[Test]
6267
[Category("InputForUI")]
6368
public void PointerEventsAreDispatchedFromMouse()
@@ -109,12 +114,7 @@ public void TouchIsPressedAndMouseEventsAreIgnored()
109114
// Presses a gamepad left stick left and verifies that a navigation move event is dispatched
110115
public void NavigationMoveWorks()
111116
{
112-
var gamepad = InputSystem.AddDevice<Gamepad>();
113-
Update();
114-
Press(gamepad.leftStick.left);
115-
Update();
116-
Release(gamepad.leftStick.left);
117-
Update();
117+
MoveWithGamepad();
118118

119119
Assert.IsTrue(m_InputForUIEvents.Count == 1);
120120
Assert.That(m_InputForUIEvents[0] is Event
@@ -126,6 +126,16 @@ public void NavigationMoveWorks()
126126
});
127127
}
128128

129+
void MoveWithGamepad()
130+
{
131+
var gamepad = InputSystem.AddDevice<Gamepad>();
132+
Update();
133+
Press(gamepad.leftStick.left);
134+
Update();
135+
Release(gamepad.leftStick.left);
136+
Update();
137+
}
138+
129139
[Test]
130140
[Category("InputForUI")]
131141
public void SendWheelEvent()
@@ -140,6 +150,37 @@ public void SendWheelEvent()
140150
Assert.That(m_InputForUIEvents[0].asPointerEvent.scroll, Is.EqualTo(new Vector2(0, 1)));
141151
}
142152

153+
[Test]
154+
[Category("InputForUI")]
155+
[TestCase(true)]
156+
[TestCase(false)]
157+
// The goal of this test is to make sure that InputSystemProvider works with and without project-wide actions asset
158+
// so that there is no impact in receiving the necessary input events for UI.
159+
// When there are no project-wide actions asset, the InputSystemProvider should still work as it currently gets
160+
// the actions from DefaultActionsAsset().asset.
161+
public void EventProviderWorksWithAndWithoutProjectWideActionsSet(bool useProjectWideActionsAsset)
162+
{
163+
Update();
164+
if (!useProjectWideActionsAsset)
165+
{
166+
// Remove the project-wide actions asset in play mode and player.
167+
// It will call InputSystem.onActionChange and re-set InputSystemProvider.actionAsset
168+
// This the case where no project-wide actions asset is available in the project.
169+
InputSystem.s_Manager.actions = null;
170+
}
171+
Update();
172+
MoveWithGamepad();
173+
174+
Assert.IsTrue(m_InputForUIEvents.Count == 1);
175+
Assert.That(m_InputForUIEvents[0] is Event
176+
{
177+
type: Event.Type.NavigationEvent,
178+
asNavigationEvent: { type: NavigationEvent.Type.Move,
179+
direction: NavigationEvent.Direction.Left,
180+
eventSource: EventSource.Gamepad}
181+
});
182+
}
183+
143184
static void Update()
144185
{
145186
EventProvider.NotifyUpdate();

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ however, it has to be formatted properly to pass verification tests.
1111
## [Unreleased] - YYYY-MM-DD
1212

1313
### Fixed
14+
- Fixed an issue where UI interactions would not function without setting up a project-wide actions asset in Project Settings. Default UI actions are now created on the fly, if no asset for project-wide actions has been set. [ISXB-811](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-811).
1415
- Physical keyboards used on Android/ChromeOS could have keys "stuck" reporting as pressed after a long press and release [ISXB-475](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-475).
1516
- NullReferenceException thrown when right-clicking an empty Action Map list in Input Actions Editor windows [ISXB-833](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-833).
1617
- Fixed an issue where `System.ObjectDisposedException` would be thrown when deleting the last ActionMap item in the Input Actions Asset editor.

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Resources/InputActionsProjectSettings.uxml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<uie:ObjectField name="current-asset" type="UnityEngine.InputSystem.InputActionAsset, Unity.InputSystem" label="Project-wide Actions" />
99
</ui:VisualElement>
1010
<ui:VisualElement name="missing-asset-section">
11-
<ui:HelpBox text="Actions for the Input System are stored in an Action Asset. You can assign an Action Asset as project-wide in the field above to make them accessible directly through the InputSystem.actions API.\n\nClick the button below to create a new Action Asset containing default actions, which will be assigned as project-wide." message-type="Info"/>
11+
<ui:HelpBox text="Actions for the Input System are stored in an Action Asset. You can assign an Action Asset as project-wide in the field above to make them accessible directly through the InputSystem.actions API.&#10;&#10;Click the button below to create a new Action Asset containing default actions, which will be assigned as project-wide." message-type="Info"/>
1212
<ui:Button text="Create and assign a default project-wide Action Asset" name="create-asset"/>
1313
</ui:VisualElement>
1414
</ui:UXML>

Packages/com.unity.inputsystem/InputSystem/Plugins/InputForUI/InputSystemProvider.cs

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ internal class InputSystemProvider : IEventProviderImpl
1717
Configuration m_Cfg;
1818

1919
InputActionAsset m_InputActionAsset;
20+
2021
InputActionReference m_PointAction;
2122
InputActionReference m_MoveAction;
2223
InputActionReference m_SubmitAction;
@@ -79,14 +80,14 @@ public void Initialize()
7980
m_SeenTouchEvents = false;
8081

8182
m_Cfg = Configuration.GetDefaultConfiguration();
82-
RegisterActions(m_Cfg);
83+
RegisterActions();
8384

8485
InputSystem.onActionsChange += OnActionsChange;
8586
}
8687

8788
public void Shutdown()
8889
{
89-
UnregisterActions(m_Cfg);
90+
UnregisterActions();
9091

9192
m_InputEventPartialProvider.Shutdown();
9293
m_InputEventPartialProvider = null;
@@ -96,10 +97,10 @@ public void Shutdown()
9697

9798
public void OnActionsChange()
9899
{
99-
UnregisterActions(m_Cfg);
100+
UnregisterActions();
100101

101102
m_Cfg = Configuration.GetDefaultConfiguration();
102-
RegisterActions(m_Cfg);
103+
RegisterActions();
103104
}
104105

105106
public void Update()
@@ -156,6 +157,11 @@ void ResetSeenEvents()
156157
m_SeenPenEvents = false;
157158
}
158159

160+
public bool ActionAssetIsNotNull()
161+
{
162+
return m_InputActionAsset != null;
163+
}
164+
159165
//TODO: Refactor as there is no need for having almost the same implementation in the IM and ISX?
160166
void DirectionNavigation(DiscreteTime currentTime)
161167
{
@@ -573,21 +579,18 @@ void UnregisterNextPreviousAction()
573579
}
574580
}
575581

576-
void RegisterActions(Configuration cfg)
582+
void RegisterActions()
577583
{
578-
m_InputActionAsset = cfg.ActionAsset;
584+
m_InputActionAsset = m_Cfg.ActionAsset;
579585

580-
if (m_InputActionAsset != null)
581-
{
582-
m_PointAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.PointAction));
583-
m_MoveAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.MoveAction));
584-
m_SubmitAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.SubmitAction));
585-
m_CancelAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.CancelAction));
586-
m_LeftClickAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.LeftClickAction));
587-
m_MiddleClickAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.MiddleClickAction));
588-
m_RightClickAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.RightClickAction));
589-
m_ScrollWheelAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.ScrollWheelAction));
590-
}
586+
m_PointAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.PointAction));
587+
m_MoveAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.MoveAction));
588+
m_SubmitAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.SubmitAction));
589+
m_CancelAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.CancelAction));
590+
m_LeftClickAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.LeftClickAction));
591+
m_MiddleClickAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.MiddleClickAction));
592+
m_RightClickAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.RightClickAction));
593+
m_ScrollWheelAction = InputActionReference.Create(m_InputActionAsset.FindAction(m_Cfg.ScrollWheelAction));
591594

592595
if (m_PointAction != null && m_PointAction.action != null)
593596
m_PointAction.action.performed += OnPointerPerformed;
@@ -610,17 +613,22 @@ void RegisterActions(Configuration cfg)
610613
if (m_ScrollWheelAction != null && m_ScrollWheelAction.action != null)
611614
m_ScrollWheelAction.action.performed += OnScrollWheelPerformed;
612615

613-
// When adding new one's don't forget to add them to UnregisterActions
616+
// When adding new actions, don't forget to add them to UnregisterActions
614617

615-
if (m_InputActionAsset != null)
618+
if (InputSystem.actions == null)
619+
{
620+
// If we've not loaded a user-created set of actions, just enable the UI actions from our defaults.
621+
m_InputActionAsset.FindActionMap("UI", true).Enable();
622+
}
623+
else
616624
m_InputActionAsset.Enable();
617625

618626
// TODO make it configurable as it is not part of default config
619627
// The Next/Previous action is not part of the input actions asset
620628
RegisterNextPreviousAction();
621629
}
622630

623-
void UnregisterActions(Configuration cfg)
631+
void UnregisterActions()
624632
{
625633
if (m_PointAction != null && m_PointAction.action != null)
626634
m_PointAction.action.performed -= OnPointerPerformed;
@@ -673,7 +681,7 @@ public struct Configuration
673681

674682
public static Configuration GetDefaultConfiguration()
675683
{
676-
return new Configuration
684+
var config = new Configuration
677685
{
678686
ActionAsset = InputSystem.actions,
679687
PointAction = "UI/Point",
@@ -685,6 +693,14 @@ public static Configuration GetDefaultConfiguration()
685693
RightClickAction = "UI/RightClick",
686694
ScrollWheelAction = "UI/ScrollWheel",
687695
};
696+
697+
if (config.ActionAsset == null)
698+
{
699+
// Use default asset if user didn't specifically set one, so that UI functions still work (ISXB-811)
700+
config.ActionAsset = new DefaultInputActions().asset;
701+
}
702+
703+
return config;
688704
}
689705
}
690706
}

0 commit comments

Comments
 (0)