Skip to content

Commit 61d8245

Browse files
authored
FIX: Input devices being lost up on upgrade to the new input version [ISX-2569] (#2438)
1 parent 6c7f0f6 commit 61d8245

4 files changed

Lines changed: 77 additions & 0 deletions

File tree

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99

1010
### Fixed
1111

12+
- Fixed input devices being lost (no keyboard, mouse, gamepad, etc.) after upgrading the package while the Editor is open (related to the recent fast enter playmode change). [ISX-2569]
1213
- Fixed `InputSystemProvider` disabling project-wide actions on shutdown when UI Toolkit destroys its objects mid-play. The provider now scopes its lifecycle to the UI action map only and does not disable project-wide actions [UUM-134130](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-134130)
1314
- Fixed `InputActionRebindingExtensions.GetBindingDisplayString(InputAction, InputBinding, ...)` returning an empty string for composite bindings when the binding mask filters by group [UUM-141423](https://issuetracker.unity3d.com/product/unity/issues/guid/UUM-141423)
1415
- Fixed `InputEventPtr.handled` not preventing actions from triggering when switching devices. The default event handled policy has been changed from `SuppressStateUpdates` (now deprecated) to `SuppressActionEventNotifications`, which keeps device state synchronized while suppressing action callbacks for handled events. [ISXB-1097](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1097)

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,36 @@ internal static void InitializeInEditor(bool calledFromCtor, IInputRuntime runti
162162
}
163163

164164
var existingStateManagers = Resources.FindObjectsOfTypeAll<InputSystemStateManager>();
165+
166+
// Upgrade migration: package versions up to and including 1.18 stored this state in a
167+
// ScriptableObject named InputSystemObject. That instance survives the domain reload
168+
// triggered by a package upgrade, but the renamed InputSystemStateManager type won't match
169+
// it. Adopt the surviving legacy instance's state into a new state manager so connected
170+
// devices (and other state) are preserved across the upgrade instead of being lost - native
171+
// only re-reports devices once per editor process, so there is no in-process recovery
172+
// otherwise. See ISX-2569.
173+
if (globalReset && (existingStateManagers == null || existingStateManagers.Length == 0))
174+
{
175+
var legacyObjects = Resources.FindObjectsOfTypeAll<InputSystemObject>();
176+
if (legacyObjects != null && legacyObjects.Length > 0)
177+
{
178+
var legacy = legacyObjects[0];
179+
var migrated = ScriptableObject.CreateInstance<InputSystemStateManager>();
180+
migrated.hideFlags = HideFlags.HideAndDontSave;
181+
migrated.systemState = legacy.systemState;
182+
migrated.newInputBackendsCheckedAsEnabled = legacy.newInputBackendsCheckedAsEnabled;
183+
migrated.settings = legacy.settings;
184+
migrated.exitEditModeTime = legacy.exitEditModeTime;
185+
migrated.enterPlayModeTime = legacy.enterPlayModeTime;
186+
187+
// The legacy instances are no longer needed; get rid of them so we don't migrate twice.
188+
for (var i = 0; i < legacyObjects.Length; ++i)
189+
Object.DestroyImmediate(legacyObjects[i]);
190+
191+
existingStateManagers = new[] { migrated };
192+
}
193+
}
194+
165195
if (existingStateManagers != null && existingStateManagers.Length > 0)
166196
{
167197
if (globalReset)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#if UNITY_EDITOR
2+
using UnityEngine;
3+
4+
namespace UnityEngine.InputSystem
5+
{
6+
/// <summary>
7+
/// Legacy compatibility type. Package versions up to and including 1.18 stored the domain-reload
8+
/// survival state in a hidden, <see cref="HideFlags.HideAndDontSave"/> ScriptableObject of this
9+
/// exact type and name (this type was renamed to <see cref="InputSystemStateManager"/> in 1.20).
10+
/// </summary>
11+
/// <remarks>
12+
/// When a project upgrades from such a version, that instance survives the domain reload triggered
13+
/// by the upgrade - but only if its serialized script reference still resolves. That reference is
14+
/// <c>{ fileID: 11500000, guid: &lt;this file's guid&gt; }</c>, so this file MUST keep the original
15+
/// <c>InputSystemObject.cs</c> GUID (<c>5cdce2bffd1e49bda08b3db54a031207</c>) and this MUST be the
16+
/// primary class of the file (matching the file name). If the reference fails to resolve, Unity
17+
/// drops the object during the reload and the input state - including the list of connected devices
18+
/// - is lost on upgrade, with no in-process recovery (native only re-reports devices once per editor
19+
/// process). See ISX-2569.
20+
///
21+
/// The fields below must keep the same names and serialized layout as 1.18's InputSystemObject so the
22+
/// surviving data deserializes into them. <c>InputSystemEditorInitializer.InitializeInEditor</c>
23+
/// detects a surviving instance of this type, migrates its state into a
24+
/// <see cref="InputSystemStateManager"/>, and then destroys it.
25+
/// </remarks>
26+
internal class InputSystemObject : ScriptableObject
27+
{
28+
[SerializeField] public InputSystemState systemState;
29+
[SerializeField] public bool newInputBackendsCheckedAsEnabled;
30+
[SerializeField] public string settings;
31+
[SerializeField] public double exitEditModeTime;
32+
[SerializeField] public double enterPlayModeTime;
33+
}
34+
}
35+
#endif // UNITY_EDITOR

Packages/com.unity.inputsystem/InputSystem/Editor/InputSystemObject.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)