Skip to content

Commit f68a3a5

Browse files
author
Rene Damm
authored
FIX: PlayerInput not hot-pairing devices without control schemes (#930).
1 parent fe48560 commit f68a3a5

File tree

6 files changed

+196
-77
lines changed

6 files changed

+196
-77
lines changed

Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,32 @@ public void PlayerInput_CanBeUsedWithoutControlSchemes()
257257
Assert.That(playerInput.devices, Has.Count.EqualTo(2));
258258
Assert.That(playerInput.devices, Has.Exactly(1).SameAs(gamepad));
259259
Assert.That(playerInput.devices, Has.Exactly(1).SameAs(keyboard));
260+
261+
// Make sure that we restore pairing even if the device goes
262+
// away temporarily.
263+
264+
InputSystem.RemoveDevice(gamepad);
265+
266+
Assert.That(playerInput.devices, Has.Count.EqualTo(1));
267+
Assert.That(playerInput.devices, Has.Exactly(1).SameAs(keyboard));
268+
269+
InputSystem.AddDevice(gamepad);
270+
271+
Assert.That(playerInput.devices, Has.Count.EqualTo(2));
272+
Assert.That(playerInput.devices, Has.Exactly(1).SameAs(gamepad));
273+
Assert.That(playerInput.devices, Has.Exactly(1).SameAs(keyboard));
274+
275+
// Also, if we add another device now, it should get picked up, too. Note that
276+
// this is special about the case of not using control schemes. When having control
277+
// schemes, we switch in single-player entirely based on control schemes. When *not*
278+
// having control schemes, we greedily grab everything that is compatible with the
279+
// bindings we have.
280+
var gamepad2 = InputSystem.AddDevice<Gamepad>();
281+
282+
Assert.That(playerInput.devices, Has.Count.EqualTo(3));
283+
Assert.That(playerInput.devices, Has.Exactly(1).SameAs(gamepad));
284+
Assert.That(playerInput.devices, Has.Exactly(1).SameAs(gamepad2));
285+
Assert.That(playerInput.devices, Has.Exactly(1).SameAs(keyboard));
260286
}
261287

262288
[Test]

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ however, it has to be formatted properly to pass verification tests.
2525
- Fixed missing custom editors for `AxisDeadzoneProcessor` and `StickDeadzoneProcessor` that link `min` and `max` values to input settings.
2626
- Fixed actions ending up being disabled if switching to a control scheme that has no binding for the action (case 1187377).
2727
- Fixed part of composite not being bound leading to subsequent part bindings not being functional (case 1189867).
28+
- Fixed `PlayerInput` not pairing devices added after it was enabled when not having control schemes.
29+
* This problem would also show in the `SimpleDemo` sample when having the `CustomDeviceUsages` sample installed as well. Gamepads would not get picked up in that case.
2830
- Fixed `ArgumentNullException` when adding a device and a binding in an action map had an empty path (case 1187163).
2931
- Fixed bindings that are not associated with any control scheme not getting enabled with other control schemes as they should.
3032

Packages/com.unity.inputsystem/InputSystem/InputManager.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Reflection;
54
using UnityEngine.InputSystem.Composites;
65
using UnityEngine.InputSystem.Controls;
76
using Unity.Collections.LowLevel.Unsafe;
@@ -10,7 +9,6 @@
109
using UnityEngine.InputSystem.Processors;
1110
using UnityEngine.InputSystem.Interactions;
1211
using UnityEngine.InputSystem.Utilities;
13-
using Unity.Collections;
1412
using UnityEngine.InputSystem.Layouts;
1513

1614
#if UNITY_EDITOR

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,18 +981,23 @@ public static IEnumerable<string> ListProcessors()
981981
/// </code>
982982
/// </example>
983983
/// </remarks>
984+
/// <exception cref="ArgumentNullException">Delegate reference is <c>null</c>.</exception>
984985
/// <seealso cref="devices"/>
985986
/// <seealso cref="AddDevice{TDevice}"/>
986987
/// <seealso cref="RemoveDevice"/>
987988
public static event Action<InputDevice, InputDeviceChange> onDeviceChange
988989
{
989990
add
990991
{
992+
if (value == null)
993+
throw new ArgumentNullException(nameof(value));
991994
lock (s_Manager)
992995
s_Manager.onDeviceChange += value;
993996
}
994997
remove
995998
{
999+
if (value == null)
1000+
throw new ArgumentNullException(nameof(value));
9961001
lock (s_Manager)
9971002
s_Manager.onDeviceChange -= value;
9981003
}
@@ -1013,17 +1018,22 @@ public static event Action<InputDevice, InputDeviceChange> onDeviceChange
10131018
/// to have handled the command. If a command is handled by a delegate in the list, it will
10141019
/// not be sent on to the runtime.
10151020
/// </remarks>
1021+
/// <exception cref="ArgumentNullException">Delegate reference is <c>null</c>.</exception>
10161022
/// <seealso cref="InputDevice.ExecuteCommand{TCommand}"/>
10171023
/// <seealso cref="IInputRuntime.DeviceCommand"/>
10181024
public static event InputDeviceCommandDelegate onDeviceCommand
10191025
{
10201026
add
10211027
{
1028+
if (value == null)
1029+
throw new ArgumentNullException(nameof(value));
10221030
lock (s_Manager)
10231031
s_Manager.onDeviceCommand += value;
10241032
}
10251033
remove
10261034
{
1035+
if (value == null)
1036+
throw new ArgumentNullException(nameof(value));
10271037
lock (s_Manager)
10281038
s_Manager.onDeviceCommand -= value;
10291039
}
@@ -1990,6 +2000,7 @@ public static int FindControls<TControl>(string path, ref InputControlList<TCont
19902000
/// (see <see cref="InputState.AddChangeMonitor(InputControl,IInputStateChangeMonitor,long)"/>
19912001
/// are usually a more efficient and convenient way to set this up.
19922002
/// </remarks>
2003+
/// <exception cref="ArgumentNullException">Delegate reference is <c>null</c>.</exception>
19932004
/// <seealso cref="QueueEvent(InputEventPtr)"/>
19942005
/// <seealso cref="InputEvent"/>
19952006
/// <seealso cref="Update"/>
@@ -1998,11 +2009,15 @@ public static event Action<InputEventPtr, InputDevice> onEvent
19982009
{
19992010
add
20002011
{
2012+
if (value == null)
2013+
throw new ArgumentNullException(nameof(value));
20012014
lock (s_Manager)
20022015
s_Manager.onEvent += value;
20032016
}
20042017
remove
20052018
{
2019+
if (value == null)
2020+
throw new ArgumentNullException(nameof(value));
20062021
lock (s_Manager)
20072022
s_Manager.onEvent -= value;
20082023
}

0 commit comments

Comments
 (0)