Skip to content

Commit 71e571f

Browse files
K-Toneu-pr[bot]
andauthored
NEW: Add more genre-style tests for the input consumption rework (#2430)
Co-authored-by: u-pr[bot] <205906871+u-pr[bot]@users.noreply.github.com>
1 parent 6610131 commit 71e571f

2 files changed

Lines changed: 322 additions & 0 deletions

File tree

Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
using NUnit.Framework;
2+
using UnityEngine;
3+
using UnityEngine.InputSystem;
4+
using UnityEngine.InputSystem.Controls;
5+
6+
/// <summary>
7+
/// Genre-style shortcut examples (RTS, shooter, etc.) migrated from sample projects into the Input System test suite.
8+
/// </summary>
9+
internal partial class CoreTests
10+
{
11+
/// <summary>
12+
/// Here we have some RTS-related actions and tests. This whole thing emerged out of having to implement control groups in RTS games.
13+
/// </summary>
14+
private static InputActionMap CreateRtsExampleShortcutMap(
15+
out InputAction actionOne,
16+
out InputAction actionShiftOne,
17+
out InputAction actionControlShiftOne)
18+
{
19+
var map = new InputActionMap("RTSShortcuts");
20+
21+
actionOne = map.AddAction("One", InputActionType.Button);
22+
actionOne.AddBinding("<Keyboard>/1");
23+
24+
actionShiftOne = map.AddAction("ShiftOne", InputActionType.Button);
25+
actionShiftOne.AddCompositeBinding("OneModifier")
26+
.With("modifier", "<Keyboard>/shift")
27+
.With("binding", "<Keyboard>/1");
28+
actionShiftOne.Priority = 1;
29+
30+
actionControlShiftOne = map.AddAction("ControlShiftOne", InputActionType.Button);
31+
actionControlShiftOne.AddCompositeBinding("TwoModifiers")
32+
.With("modifier1", "<Keyboard>/ctrl")
33+
.With("modifier2", "<Keyboard>/shift")
34+
.With("binding", "<Keyboard>/1");
35+
actionControlShiftOne.Priority = 2;
36+
37+
return map;
38+
}
39+
40+
[Test]
41+
[Category("Actions Priority")]
42+
public void Actions_Priority_Genres_RTS_Key1Only_ActivatesPlainOne()
43+
{
44+
EnableActionPriorityShortcutResolution();
45+
46+
var keyboard = InputSystem.AddDevice<Keyboard>();
47+
using var map = CreateRtsExampleShortcutMap(out var actionOne, out var actionShiftOne, out var actionControlShiftOne);
48+
map.Enable();
49+
50+
Press((ButtonControl)keyboard.digit1Key);
51+
InputSystem.Update();
52+
53+
Assert.That(actionOne.IsPressed(), Is.True);
54+
Assert.That(actionShiftOne.IsPressed(), Is.False);
55+
Assert.That(actionControlShiftOne.IsPressed(), Is.False);
56+
57+
Release((ButtonControl)keyboard.digit1Key);
58+
InputSystem.Update();
59+
}
60+
61+
[Test]
62+
[Category("Actions Priority")]
63+
public void Actions_Priority_Genres_RTS_ShiftOne_SuppressesPlainOne()
64+
{
65+
EnableActionPriorityShortcutResolution();
66+
67+
var keyboard = InputSystem.AddDevice<Keyboard>();
68+
using var map = CreateRtsExampleShortcutMap(out var actionOne, out var actionShiftOne, out var actionControlShiftOne);
69+
map.Enable();
70+
71+
Press((ButtonControl)keyboard.shiftKey);
72+
Press((ButtonControl)keyboard.digit1Key);
73+
InputSystem.Update();
74+
75+
Assert.That(actionOne.IsPressed(), Is.False, "Plain 1 should not activate when Shift+1 wins.");
76+
Assert.That(actionShiftOne.IsPressed(), Is.True, "Shift+1 should activate.");
77+
Assert.That(actionControlShiftOne.IsPressed(), Is.False);
78+
79+
Release((ButtonControl)keyboard.digit1Key);
80+
Release((ButtonControl)keyboard.shiftKey);
81+
InputSystem.Update();
82+
}
83+
84+
[Test]
85+
[Category("Actions Priority")]
86+
public void Actions_Priority_Genres_RTS_ControlShiftOne_SuppressesLowerTiers()
87+
{
88+
EnableActionPriorityShortcutResolution();
89+
90+
var keyboard = InputSystem.AddDevice<Keyboard>();
91+
using var map = CreateRtsExampleShortcutMap(out var actionOne, out var actionShiftOne, out var actionControlShiftOne);
92+
map.Enable();
93+
94+
Press((ButtonControl)keyboard.ctrlKey);
95+
Press((ButtonControl)keyboard.shiftKey);
96+
Press((ButtonControl)keyboard.digit1Key);
97+
InputSystem.Update();
98+
99+
Assert.That(actionOne.IsPressed(), Is.False, "Plain 1 should not activate when Ctrl+Shift+1 wins.");
100+
Assert.That(actionShiftOne.IsPressed(), Is.False, "Shift+1 should not activate when Ctrl+Shift+1 wins.");
101+
Assert.That(actionControlShiftOne.IsPressed(), Is.True, "Ctrl+Shift+1 should activate.");
102+
103+
Release((ButtonControl)keyboard.digit1Key);
104+
Release((ButtonControl)keyboard.shiftKey);
105+
Release((ButtonControl)keyboard.ctrlKey);
106+
InputSystem.Update();
107+
}
108+
109+
/// <summary>
110+
/// The following section emerged from trying input shortcuts with some generic joystick-controlled games, platformer/scroller style.
111+
/// In those games, the move action overlaps with a plenty of special abilities.
112+
/// </summary>
113+
private static InputActionMap CreateGenericJoystickExampleShortcutMap(
114+
out InputAction actionMove,
115+
out InputAction actionJump,
116+
out InputAction actionJumpKick)
117+
{
118+
var map = new InputActionMap("JoystickExample");
119+
120+
actionMove = map.AddAction("Move", InputActionType.Value, expectedControlLayout: "Vector2");
121+
actionMove.AddBinding("<Gamepad>/leftStick");
122+
123+
actionJump = map.AddAction("Jump", InputActionType.Button);
124+
actionJump.AddBinding("<Gamepad>/buttonSouth");
125+
126+
actionJumpKick = map.AddAction("Jump Kick", InputActionType.Button);
127+
128+
actionJumpKick.AddCompositeBinding("OneModifier")
129+
.With("modifier", "<Gamepad>/leftShoulder")
130+
.With("binding", "<Gamepad>/buttonSouth");
131+
132+
actionJumpKick.Priority = 1;
133+
134+
return map;
135+
}
136+
137+
[Test]
138+
[Category("Actions Priority")]
139+
public void Actions_Priority_Genres_GenericJoystick_LeftStick_Activates_JustOneAction()
140+
{
141+
EnableActionPriorityShortcutResolution();
142+
143+
var gamepad = InputSystem.AddDevice<Gamepad>();
144+
using var map = CreateGenericJoystickExampleShortcutMap(out var actionMove, out var actionJump, out var actionJumpKick);
145+
map.Enable();
146+
147+
Set(gamepad.leftStick, Vector2.up);
148+
149+
InputSystem.Update();
150+
151+
Assert.IsTrue(actionMove.IsPressed(), "Move should be active when the left stick is tilted.");
152+
Assert.IsFalse(actionJump.IsPressed(), "Jump should not be active without X (south).");
153+
Assert.IsFalse(actionJumpKick.IsPressed(), "Jump Kick should not be active without L1+X.");
154+
155+
Set(gamepad.leftStick, Vector2.zero);
156+
InputSystem.Update();
157+
}
158+
159+
[Test]
160+
[Category("Actions Priority")]
161+
public void Actions_Priority_Genres_GenericJoystick_LeftStickAndX_Triggers_Move_And_Jump()
162+
{
163+
EnableActionPriorityShortcutResolution();
164+
165+
var gamepad = InputSystem.AddDevice<Gamepad>();
166+
using var map = CreateGenericJoystickExampleShortcutMap(out var actionMove, out var actionJump, out var actionJumpKick);
167+
map.Enable();
168+
169+
Set(gamepad.leftStick, Vector2.up);
170+
Press(gamepad.buttonSouth);
171+
172+
InputSystem.Update();
173+
174+
Assert.IsTrue(actionMove.IsPressed(), "Move should still be active while the stick is tilted.");
175+
Assert.IsTrue(actionJump.IsPressed(), "Jump should be active when X (south) is pressed.");
176+
Assert.IsFalse(actionJumpKick.IsPressed(), "Jump Kick should not be active without L1.");
177+
178+
Release(gamepad.buttonSouth);
179+
Set(gamepad.leftStick, Vector2.zero);
180+
InputSystem.Update();
181+
}
182+
183+
[Test]
184+
[Category("Actions Priority")]
185+
public void Actions_Priority_Genres_GenericJoystick_L1AndX_Only_Triggers_JumpKick()
186+
{
187+
EnableActionPriorityShortcutResolution();
188+
189+
var gamepad = InputSystem.AddDevice<Gamepad>();
190+
using var map = CreateGenericJoystickExampleShortcutMap(out var actionMove, out var actionJump, out var actionJumpKick);
191+
map.Enable();
192+
193+
Press(gamepad.leftShoulder);
194+
Press(gamepad.buttonSouth);
195+
196+
InputSystem.Update();
197+
198+
Assert.IsFalse(actionMove.IsPressed(), "Move should not be active when the stick is neutral.");
199+
Assert.IsFalse(actionJump.IsPressed(), "Jump should not consume when Jump Kick wins (priority + consume).");
200+
Assert.IsTrue(actionJumpKick.IsPressed(), "Jump Kick should be active for L1+X.");
201+
202+
Release(gamepad.buttonSouth);
203+
Release(gamepad.leftShoulder);
204+
InputSystem.Update();
205+
}
206+
207+
/// <summary>
208+
/// The following section originates from shooter games where move overlaps with a bunch of weapon controls and team interactions.
209+
/// </summary>
210+
private static InputActionMap CreateShooterExampleShortcutMap(
211+
out InputAction actionMove,
212+
out InputAction actionRunFast,
213+
out InputAction actionTeamChat)
214+
{
215+
var map = new InputActionMap("ShooterExample");
216+
217+
actionMove = map.AddAction("Move", InputActionType.Value);
218+
actionMove.AddCompositeBinding("2DVector")
219+
.With("up", "<Keyboard>/w")
220+
.With("down", "<Keyboard>/s")
221+
.With("left", "<Keyboard>/a")
222+
.With("right", "<Keyboard>/d");
223+
224+
actionRunFast = map.AddAction("Run Fast", InputActionType.Button);
225+
actionRunFast.AddCompositeBinding("OneModifier")
226+
.With("modifier", "<Keyboard>/shift")
227+
.With("binding", "<Keyboard>/w");
228+
229+
actionTeamChat = map.AddAction("Team chat", InputActionType.Button);
230+
actionTeamChat.AddCompositeBinding("TwoModifiers")
231+
.With("modifier1", "<Keyboard>/alt")
232+
.With("modifier2", "<Keyboard>/shift")
233+
.With("binding", "<Keyboard>/w");
234+
235+
actionTeamChat.Priority = 2;
236+
237+
return map;
238+
}
239+
240+
[Test]
241+
[Category("Actions Priority")]
242+
public void Actions_Priority_Genres_Shooter_Move_Only_Triggers_Move()
243+
{
244+
EnableActionPriorityShortcutResolution();
245+
var keyboard = InputSystem.AddDevice<Keyboard>();
246+
using var map = CreateShooterExampleShortcutMap(out var actionMove, out var actionRunFast, out var actionTeamChat);
247+
map.Enable();
248+
249+
Press(keyboard.wKey);
250+
InputSystem.Update();
251+
252+
Assert.IsTrue(actionMove.IsPressed(), "Move should be activated by W.");
253+
Assert.IsFalse(actionRunFast.IsPressed(), "Run Fast should not be activated by W alone.");
254+
Assert.IsFalse(actionTeamChat.IsPressed(), "Team chat should not be activated by W alone.");
255+
256+
Release(keyboard.wKey);
257+
InputSystem.Update();
258+
}
259+
260+
[Test]
261+
[Category("Actions Priority")]
262+
public void Actions_Priority_Genres_Shooter_ShiftW_Triggers_Move_And_RunFast()
263+
{
264+
EnableActionPriorityShortcutResolution();
265+
var keyboard = InputSystem.AddDevice<Keyboard>();
266+
using var map = CreateShooterExampleShortcutMap(out var actionMove, out var actionRunFast, out var actionTeamChat);
267+
map.Enable();
268+
269+
Press(keyboard.leftShiftKey);
270+
Press(keyboard.wKey);
271+
272+
InputSystem.Update();
273+
274+
Assert.IsTrue(actionMove.IsPressed(), "Move should still be activated by W.");
275+
Assert.IsTrue(actionRunFast.IsPressed(), "Run Fast should be activated by Shift+W.");
276+
Assert.IsFalse(actionTeamChat.IsPressed(), "Team chat should not be activated without Alt.");
277+
278+
Release(keyboard.wKey);
279+
Release(keyboard.leftShiftKey);
280+
InputSystem.Update();
281+
}
282+
283+
[Test]
284+
[Category("Actions Priority")]
285+
public void Actions_Priority_Genres_Shooter_AltShiftW_Only_Triggers_TeamChat()
286+
{
287+
EnableActionPriorityShortcutResolution();
288+
var keyboard = InputSystem.AddDevice<Keyboard>();
289+
using var map = CreateShooterExampleShortcutMap(out var actionMove, out var actionRunFast, out var actionTeamChat);
290+
map.Enable();
291+
292+
Press(keyboard.leftAltKey);
293+
Press(keyboard.leftShiftKey);
294+
Press(keyboard.wKey);
295+
296+
InputSystem.Update();
297+
298+
Assert.IsTrue(
299+
actionTeamChat.IsPressed() || actionTeamChat.IsInProgress(),
300+
"Team chat should trigger when Alt, Shift, and W are down together.");
301+
302+
Assert.IsFalse(actionMove.IsPressed(), "Move shouldn't be activated!");
303+
Assert.IsFalse(actionRunFast.IsPressed(), "Run Fast shouldn't be activated!");
304+
305+
Release(keyboard.leftAltKey);
306+
Release(keyboard.leftShiftKey);
307+
Release(keyboard.wKey);
308+
309+
InputSystem.Update();
310+
}
311+
}

Assets/Tests/InputSystem/CoreTests_ActionPriority_Genres.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)