From 0c77ea46bed33d343de3e37fc52035eab9a4e120 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Fri, 21 Feb 2025 14:00:04 +0100 Subject: [PATCH 01/16] Fixed enabling all action maps for project wide actions overrides playerinput --- Packages/com.unity.inputsystem/InputSystem/InputSystem.cs | 3 ++- .../InputSystem/Plugins/PlayerInput/PlayerInput.cs | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs index abbdf80abf..ce37fcf472 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs @@ -3035,7 +3035,8 @@ private static void EnableActions() if (actions == null) return; - actions.Enable(); + if (!actions.enabled) + actions.Enable(); } private static void DisableActions(bool triggerSetupChanged = false) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index 997f7e20d2..96c0405551 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -954,6 +954,10 @@ public void ActivateInput() m_InputActive = true; + // reset state to default, only one action map is enabled at the initial state + // Project wide actions may have enabled action maps + actions.Disable(); + // If we have no current action map but there's a default // action map, make it current. if (m_CurrentActionMap == null && m_Actions != null && !string.IsNullOrEmpty(m_DefaultActionMap)) From f6480e7ae69cf94ccddba165453f0cde9e9e6b55 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Fri, 21 Feb 2025 14:14:47 +0100 Subject: [PATCH 02/16] added changelog --- Packages/com.unity.inputsystem/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index acfff14510..57d2a4363c 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -10,6 +10,9 @@ however, it has to be formatted properly to pass verification tests. ## [Unreleased] - yyyy-mm-dd +### Fixed +- Fixed an issue where all action maps were enabled initially for project wide actions, which overrode the PlayerInput action map configuration. [ISXB-920](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-920) + ## [1.13.1] - 2025-02-18 ### Fixed From d9e3b6a732fb510d98eee526ba4e94ccf4b38ff5 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Mon, 24 Feb 2025 13:12:02 +0100 Subject: [PATCH 03/16] added nullcheck --- .../InputSystem/Plugins/PlayerInput/PlayerInput.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index 96c0405551..bcdbfdc9a3 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -956,7 +956,8 @@ public void ActivateInput() // reset state to default, only one action map is enabled at the initial state // Project wide actions may have enabled action maps - actions.Disable(); + if (m_Actions != null) + m_Actions.Disable(); // If we have no current action map but there's a default // action map, make it current. From 6afc84a89cba1d624f0f31af897ef7db5b276993 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Mon, 24 Feb 2025 15:17:50 +0100 Subject: [PATCH 04/16] changed to duplicate actions for playerinput instead of using project wide action asset directly --- .../InputSystem/InputSystem.cs | 3 +-- .../Plugins/PlayerInput/PlayerInput.cs | 24 ++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs index ce37fcf472..abbdf80abf 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs @@ -3035,8 +3035,7 @@ private static void EnableActions() if (actions == null) return; - if (!actions.enabled) - actions.Enable(); + actions.Enable(); } private static void DisableActions(bool triggerSetupChanged = false) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index bcdbfdc9a3..6c3fd21c12 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -1373,19 +1373,16 @@ private void InitializeActions() if (m_Actions == null) return; + // don't use project wide action asset for player input, but duplicate it + if (InputSystem.actions != null && InputSystem.actions.Equals(m_Actions)) + DuplicateActionsForPlayer(); + // Check if we need to duplicate our actions by looking at all other players. If any // has the same actions, duplicate. for (var i = 0; i < s_AllActivePlayersCount; ++i) if (s_AllActivePlayers[i].m_Actions == m_Actions && s_AllActivePlayers[i] != this) { - var oldActions = m_Actions; - m_Actions = Instantiate(m_Actions); - for (var actionMap = 0; actionMap < oldActions.actionMaps.Count; actionMap++) - { - for (var binding = 0; binding < oldActions.actionMaps[actionMap].bindings.Count; binding++) - m_Actions.actionMaps[actionMap].ApplyBindingOverride(binding, oldActions.actionMaps[actionMap].bindings[binding]); - } - + DuplicateActionsForPlayer(); break; } @@ -1435,6 +1432,17 @@ private void InitializeActions() m_ActionsInitialized = true; } + private void DuplicateActionsForPlayer() + { + var oldActions = m_Actions; + m_Actions = Instantiate(m_Actions); + for (var actionMap = 0; actionMap < oldActions.actionMaps.Count; actionMap++) + { + for (var binding = 0; binding < oldActions.actionMaps[actionMap].bindings.Count; binding++) + m_Actions.actionMaps[actionMap].ApplyBindingOverride(binding, oldActions.actionMaps[actionMap].bindings[binding]); + } + } + private void UninitializeActions() { if (!m_ActionsInitialized) From 98dec351d392c84e35b2b0cb244b735a27afac6e Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Mon, 24 Feb 2025 15:52:04 +0100 Subject: [PATCH 05/16] always duplicate action assets for PlayerInput to avoid manipulating the original that might be used elsewhere --- .../InputSystem/Plugins/PlayerInputTests.cs | 10 +++++----- .../Plugins/PlayerInput/PlayerInput.cs | 17 +++++------------ 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs index 7bf1d5ee81..edbed7c684 100644 --- a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs +++ b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs @@ -149,11 +149,11 @@ public void PlayerInput_CanUseSameActionsForUIInputModule() eventSystemGO.SetActive(true); playerGO.SetActive(true); - Assert.That(actions.FindActionMap("Gameplay").enabled, Is.True); - Assert.That(actions.FindActionMap("UI").enabled, Is.True); - Assert.That(actions["UI/Navigate"].controls, Is.Empty); - Assert.That(actions["UI/Point"].controls, Is.EquivalentTo(new[] { mouse.position })); - Assert.That(actions["UI/Click"].controls, Is.EquivalentTo(new[] { mouse.leftButton })); + Assert.That(player.actions.FindActionMap("Gameplay").enabled, Is.True); + Assert.That(player.actions.FindActionMap("UI").enabled, Is.False); + Assert.That(uiModule.actionsAsset["UI/Navigate"].controls, Is.Empty); + Assert.That(uiModule.actionsAsset["UI/Point"].controls, Is.EquivalentTo(new[] { mouse.position })); + Assert.That(uiModule.actionsAsset["UI/Click"].controls, Is.EquivalentTo(new[] { mouse.leftButton })); } [Test] diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index 6c3fd21c12..41fbdebd53 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -1373,18 +1373,11 @@ private void InitializeActions() if (m_Actions == null) return; - // don't use project wide action asset for player input, but duplicate it - if (InputSystem.actions != null && InputSystem.actions.Equals(m_Actions)) - DuplicateActionsForPlayer(); - - // Check if we need to duplicate our actions by looking at all other players. If any - // has the same actions, duplicate. - for (var i = 0; i < s_AllActivePlayersCount; ++i) - if (s_AllActivePlayers[i].m_Actions == m_Actions && s_AllActivePlayers[i] != this) - { - DuplicateActionsForPlayer(); - break; - } + // don't use original asset, duplicate it. + // this avoids operating on the project wide action asset + // this also avoids operating on assets that are shared between multiple players + // and to not change assets that are used in other places (InputSystemUIInputModule) + DuplicateActionsForPlayer(); #if UNITY_INPUT_SYSTEM_ENABLE_UI if (uiInputModule != null) From 4f6438150d57949c92dc171cddcdcde3b74d60e1 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Mon, 24 Feb 2025 15:58:18 +0100 Subject: [PATCH 06/16] undo editing test --- Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs index edbed7c684..7bf1d5ee81 100644 --- a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs +++ b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs @@ -149,11 +149,11 @@ public void PlayerInput_CanUseSameActionsForUIInputModule() eventSystemGO.SetActive(true); playerGO.SetActive(true); - Assert.That(player.actions.FindActionMap("Gameplay").enabled, Is.True); - Assert.That(player.actions.FindActionMap("UI").enabled, Is.False); - Assert.That(uiModule.actionsAsset["UI/Navigate"].controls, Is.Empty); - Assert.That(uiModule.actionsAsset["UI/Point"].controls, Is.EquivalentTo(new[] { mouse.position })); - Assert.That(uiModule.actionsAsset["UI/Click"].controls, Is.EquivalentTo(new[] { mouse.leftButton })); + Assert.That(actions.FindActionMap("Gameplay").enabled, Is.True); + Assert.That(actions.FindActionMap("UI").enabled, Is.True); + Assert.That(actions["UI/Navigate"].controls, Is.Empty); + Assert.That(actions["UI/Point"].controls, Is.EquivalentTo(new[] { mouse.position })); + Assert.That(actions["UI/Click"].controls, Is.EquivalentTo(new[] { mouse.leftButton })); } [Test] From ae27089095824234d2a438a2c76b7f7141c537cb Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Mon, 24 Feb 2025 16:00:11 +0100 Subject: [PATCH 07/16] reset --- .../Plugins/PlayerInput/PlayerInput.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index 41fbdebd53..6c3fd21c12 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -1373,11 +1373,18 @@ private void InitializeActions() if (m_Actions == null) return; - // don't use original asset, duplicate it. - // this avoids operating on the project wide action asset - // this also avoids operating on assets that are shared between multiple players - // and to not change assets that are used in other places (InputSystemUIInputModule) - DuplicateActionsForPlayer(); + // don't use project wide action asset for player input, but duplicate it + if (InputSystem.actions != null && InputSystem.actions.Equals(m_Actions)) + DuplicateActionsForPlayer(); + + // Check if we need to duplicate our actions by looking at all other players. If any + // has the same actions, duplicate. + for (var i = 0; i < s_AllActivePlayersCount; ++i) + if (s_AllActivePlayers[i].m_Actions == m_Actions && s_AllActivePlayers[i] != this) + { + DuplicateActionsForPlayer(); + break; + } #if UNITY_INPUT_SYSTEM_ENABLE_UI if (uiInputModule != null) From 1655b7fcbab420a532856f5db8ddc77bf6a60fb4 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Tue, 25 Feb 2025 13:36:37 +0100 Subject: [PATCH 08/16] always duplicate PlayerInput action assets and removed redundant pjwd actions enabling calls --- .../InputSystem/Plugins/PlayerInputTests.cs | 10 +++--- .../InputSystem/InputSystem.cs | 9 ----- .../Plugins/PlayerInput/PlayerInput.cs | 33 +++++-------------- 3 files changed, 14 insertions(+), 38 deletions(-) diff --git a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs index 7bf1d5ee81..1c3ab01ee1 100644 --- a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs +++ b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs @@ -149,11 +149,11 @@ public void PlayerInput_CanUseSameActionsForUIInputModule() eventSystemGO.SetActive(true); playerGO.SetActive(true); - Assert.That(actions.FindActionMap("Gameplay").enabled, Is.True); - Assert.That(actions.FindActionMap("UI").enabled, Is.True); - Assert.That(actions["UI/Navigate"].controls, Is.Empty); - Assert.That(actions["UI/Point"].controls, Is.EquivalentTo(new[] { mouse.position })); - Assert.That(actions["UI/Click"].controls, Is.EquivalentTo(new[] { mouse.leftButton })); + Assert.That(player.actions.FindActionMap("Gameplay").enabled, Is.True); + Assert.That(uiModule.actionsAsset.FindActionMap("UI").enabled, Is.True); + Assert.That(uiModule.actionsAsset["UI/Navigate"].controls, Is.Empty); + Assert.That(uiModule.actionsAsset["UI/Point"].controls, Is.EquivalentTo(new[] { mouse.position })); + Assert.That(uiModule.actionsAsset["UI/Click"].controls, Is.EquivalentTo(new[] { mouse.leftButton })); } [Test] diff --git a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs index abbdf80abf..ad9c7ad671 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs @@ -3609,12 +3609,6 @@ internal static void InitializeInEditor(IInputRuntime runtime = null) // this would cancel the import of large assets that are dependent on the InputSystem package and import it as a dependency. EditorApplication.delayCall += ShowRestartWarning; -#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS - // Make sure project wide input actions are enabled. - // Note that this will always fail if entering play-mode within editor since not yet in play-mode. - EnableActions(); -#endif - RunInitialUpdate(); k_InputInitializeInEditorMarker.End(); @@ -3657,9 +3651,6 @@ internal static void OnPlayModeChange(PlayModeStateChange change) case PlayModeStateChange.EnteredPlayMode: s_SystemObject.enterPlayModeTime = InputRuntime.s_Instance.currentTime; s_Manager.SyncAllDevicesAfterEnteringPlayMode(); - #if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS - EnableActions(); - #endif // UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS break; case PlayModeStateChange.ExitingPlayMode: diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index 6c3fd21c12..daef812874 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -956,7 +956,7 @@ public void ActivateInput() // reset state to default, only one action map is enabled at the initial state // Project wide actions may have enabled action maps - if (m_Actions != null) + if (m_Actions) m_Actions.Disable(); // If we have no current action map but there's a default @@ -1373,18 +1373,14 @@ private void InitializeActions() if (m_Actions == null) return; - // don't use project wide action asset for player input, but duplicate it - if (InputSystem.actions != null && InputSystem.actions.Equals(m_Actions)) - DuplicateActionsForPlayer(); - - // Check if we need to duplicate our actions by looking at all other players. If any - // has the same actions, duplicate. - for (var i = 0; i < s_AllActivePlayersCount; ++i) - if (s_AllActivePlayers[i].m_Actions == m_Actions && s_AllActivePlayers[i] != this) - { - DuplicateActionsForPlayer(); - break; - } + // duplicate action asset to not operate on the original (as it might be used outside - eg project wide action asset or UIInputModule) + var oldActions = m_Actions; + m_Actions = Instantiate(m_Actions); + for (var actionMap = 0; actionMap < oldActions.actionMaps.Count; actionMap++) + { + for (var binding = 0; binding < oldActions.actionMaps[actionMap].bindings.Count; binding++) + m_Actions.actionMaps[actionMap].ApplyBindingOverride(binding, oldActions.actionMaps[actionMap].bindings[binding]); + } #if UNITY_INPUT_SYSTEM_ENABLE_UI if (uiInputModule != null) @@ -1432,17 +1428,6 @@ private void InitializeActions() m_ActionsInitialized = true; } - private void DuplicateActionsForPlayer() - { - var oldActions = m_Actions; - m_Actions = Instantiate(m_Actions); - for (var actionMap = 0; actionMap < oldActions.actionMaps.Count; actionMap++) - { - for (var binding = 0; binding < oldActions.actionMaps[actionMap].bindings.Count; binding++) - m_Actions.actionMaps[actionMap].ApplyBindingOverride(binding, oldActions.actionMaps[actionMap].bindings[binding]); - } - } - private void UninitializeActions() { if (!m_ActionsInitialized) From b05b5e86ccdcbb413f4af7db7015cff3a3e5c23c Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Thu, 27 Feb 2025 17:27:28 +0100 Subject: [PATCH 09/16] fix tests and copying of asset --- .../InputSystem/Plugins/PlayerInputTests.cs | 22 +++++++------- .../Plugins/PlayerInput/PlayerInput.cs | 29 ++++++++++++++----- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs index 1c3ab01ee1..4f1a525b9b 100644 --- a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs +++ b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs @@ -391,7 +391,8 @@ public void PlayerInput_CanAssignActionsToPlayer() var actions = InputActionAsset.FromJson(kActions); playerInput.actions = actions; - Assert.That(playerInput.actions, Is.SameAs(actions)); + Assert.That(playerInput.actions.actionMaps.Count, Is.EqualTo(actions.actionMaps.Count)); + Assert.That(playerInput.actions.actionMaps[0].name, Is.EqualTo(actions.actionMaps[0].name)); } [Test] @@ -407,13 +408,13 @@ public void PlayerInput_AssigningNewActionsToPlayer_DisablesExistingActions() playerInput.defaultActionMap = "gameplay"; playerInput.actions = actions1; - Assert.That(actions1.actionMaps[0].enabled, Is.True); - Assert.That(actions2.actionMaps[0].enabled, Is.False); + Assert.That(playerInput.actions.actionMaps[0].enabled, Is.True); + Assert.That(actions1.actionMaps[0].enabled, Is.False); playerInput.actions = actions2; - Assert.That(actions1.actionMaps[0].enabled, Is.False); - Assert.That(actions2.actionMaps[0].enabled, Is.True); + Assert.That(actions2.actionMaps[0].enabled, Is.False); + Assert.That(playerInput.actions.actionMaps[0].enabled, Is.True); } [Test] @@ -1714,7 +1715,8 @@ InputDevice[] AddDevices() // Make sure that no cloning of actions happened on the prefab. // https://fogbugz.unity3d.com/f/cases/1319756/ - Assert.That(playerPrefab.GetComponent().actions, Is.SameAs(playerPrefabActions)); + + Assert.That(playerPrefab.GetComponent().actions.actionMaps.Count, Is.EqualTo(playerPrefabActions.actionMaps.Count)); Assert.That(playerPrefab.GetComponent().m_ActionsInitialized, Is.False); } @@ -2421,13 +2423,13 @@ public void PlayerInput_DelegatesAreUpdate_WhenActionMapAddedAfterAssignment() // Disable the asset while adding another action map to it as none // of the actions in the asset can be enabled during modification // - actionAsset.Disable(); + playerInput.actions.Disable(); var keyboard = InputSystem.AddDevice(); - var newActionMap = actionAsset.AddActionMap("NewMap"); + var newActionMap = playerInput.actions.AddActionMap("NewMap"); var newAction = newActionMap.AddAction("NewAction"); newAction.AddBinding("/k", groups: "Keyboard"); - actionAsset.AddControlScheme("Keyboard").WithRequiredDevice(); - actionAsset.Enable(); + playerInput.actions.AddControlScheme("Keyboard").WithRequiredDevice(); + playerInput.actions.Enable(); playerInput.currentActionMap = newActionMap; playerInput.ActivateInput(); diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index daef812874..a36ba8ca8b 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -344,6 +344,8 @@ public InputActionAsset actions m_Actions = value; + CopyActionAsset(); + if (m_Enabled) { ClearCaches(); @@ -1373,14 +1375,13 @@ private void InitializeActions() if (m_Actions == null) return; - // duplicate action asset to not operate on the original (as it might be used outside - eg project wide action asset or UIInputModule) - var oldActions = m_Actions; - m_Actions = Instantiate(m_Actions); - for (var actionMap = 0; actionMap < oldActions.actionMaps.Count; actionMap++) - { - for (var binding = 0; binding < oldActions.actionMaps[actionMap].bindings.Count; binding++) - m_Actions.actionMaps[actionMap].ApplyBindingOverride(binding, oldActions.actionMaps[actionMap].bindings[binding]); - } + + for (var i = 0; i < s_AllActivePlayersCount; ++i) + if (s_AllActivePlayers[i].m_Actions == m_Actions && s_AllActivePlayers[i] != this) + { + CopyActionAsset(); + break; + } #if UNITY_INPUT_SYSTEM_ENABLE_UI if (uiInputModule != null) @@ -1428,6 +1429,18 @@ private void InitializeActions() m_ActionsInitialized = true; } + private void CopyActionAsset() + { + // duplicate action asset to not operate on the original (as it might be used outside - eg project wide action asset or UIInputModule) + var oldActions = m_Actions; + m_Actions = Instantiate(m_Actions); + for (var actionMap = 0; actionMap < oldActions.actionMaps.Count; actionMap++) + { + for (var binding = 0; binding < oldActions.actionMaps[actionMap].bindings.Count; binding++) + m_Actions.actionMaps[actionMap].ApplyBindingOverride(binding, oldActions.actionMaps[actionMap].bindings[binding]); + } + } + private void UninitializeActions() { if (!m_ActionsInitialized) From acf62250238f62b81c4de9498978ca84909cb8d1 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Thu, 27 Feb 2025 17:31:17 +0100 Subject: [PATCH 10/16] revert deleting comment --- .../InputSystem/Plugins/PlayerInput/PlayerInput.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index a36ba8ca8b..b4eaf77daf 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -1376,6 +1376,8 @@ private void InitializeActions() return; + // Check if we need to duplicate our actions by looking at all other players. If any + // has the same actions, duplicate. for (var i = 0; i < s_AllActivePlayersCount; ++i) if (s_AllActivePlayers[i].m_Actions == m_Actions && s_AllActivePlayers[i] != this) { From 9c6cda3baba580443707dd964dabef69f8600e7a Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Thu, 27 Feb 2025 17:32:51 +0100 Subject: [PATCH 11/16] added comment --- .../InputSystem/Plugins/PlayerInput/PlayerInput.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index b4eaf77daf..6e91f5ae91 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -344,6 +344,7 @@ public InputActionAsset actions m_Actions = value; + // copy action asset for the first player too so that the original asset stays untouched CopyActionAsset(); if (m_Enabled) @@ -1375,7 +1376,6 @@ private void InitializeActions() if (m_Actions == null) return; - // Check if we need to duplicate our actions by looking at all other players. If any // has the same actions, duplicate. for (var i = 0; i < s_AllActivePlayersCount; ++i) From 67002de1233c9d8128f0b29737ae6136a40f08a1 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Fri, 28 Feb 2025 11:07:45 +0100 Subject: [PATCH 12/16] adjusted copying of asset to work for prefabs too --- .../Tests/InputSystem/Plugins/PlayerInputTests.cs | 4 ++-- .../InputSystem/Plugins/PlayerInput/PlayerInput.cs | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs index 4f1a525b9b..b4b22c3dff 100644 --- a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs +++ b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs @@ -55,7 +55,7 @@ public void PlayerInput_CanInstantiatePlayer() Assert.That(player, Is.Not.Null); Assert.That(player.playerIndex, Is.EqualTo(0)); - Assert.That(player.actions, Is.SameAs(prefabPlayerInput.actions)); + Assert.That(player.actions.actionMaps.Count, Is.EqualTo(prefabPlayerInput.actions.actionMaps.Count)); Assert.That(player.devices, Is.EquivalentTo(new[] { gamepad })); Assert.That(player.currentControlScheme, Is.EqualTo("Gamepad")); } @@ -108,7 +108,6 @@ public void PlayerInput_CanLinkSpecificDeviceToUI() var ui = prefab.AddComponent(); player.uiInputModule = ui; player.actions = InputActionAsset.FromJson(kActions); - ui.actionsAsset = player.actions; InputSystem.AddDevice(); InputSystem.AddDevice(); @@ -117,6 +116,7 @@ public void PlayerInput_CanLinkSpecificDeviceToUI() var gamepad = InputSystem.AddDevice(); var instance = PlayerInput.Instantiate(prefab, pairWithDevices: gamepad); + ui.actionsAsset = instance.actions; Assert.That(instance.devices, Is.EquivalentTo(new[] { gamepad })); Assert.That(ui.actionsAsset.devices, Is.EquivalentTo(new[] { gamepad })); diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index 6e91f5ae91..b84c990437 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -342,10 +342,13 @@ public InputActionAsset actions UninitializeActions(); } + var didChange = m_Actions != null; + m_Actions = value; - // copy action asset for the first player too so that the original asset stays untouched - CopyActionAsset(); + if (didChange || m_Enabled) + // copy action asset for the first player so that the original asset stays untouched + CopyActionAsset(); if (m_Enabled) { @@ -1812,6 +1815,13 @@ void Reset() #endif + private void Awake() + { + // If an action asset is assigned copy it to avoid modifying the original asset. + if (m_Actions != null) + CopyActionAsset(); + } + private void OnEnable() { m_Enabled = true; From 0e4b64b8c6210bcc0daf0305b403e4462ad84414 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Fri, 28 Feb 2025 12:45:17 +0100 Subject: [PATCH 13/16] disabling all maps is not necessary anymore with copy --- .../InputSystem/Plugins/PlayerInput/PlayerInput.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index b84c990437..2e9b2056ee 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -960,11 +960,6 @@ public void ActivateInput() m_InputActive = true; - // reset state to default, only one action map is enabled at the initial state - // Project wide actions may have enabled action maps - if (m_Actions) - m_Actions.Disable(); - // If we have no current action map but there's a default // action map, make it current. if (m_CurrentActionMap == null && m_Actions != null && !string.IsNullOrEmpty(m_DefaultActionMap)) From 8fab5a9ab776a04d2af38f02828d0001872aa858 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Fri, 28 Feb 2025 13:00:13 +0100 Subject: [PATCH 14/16] added new test to proof the first PlayerInput ActionAsset is copied --- .../Tests/InputSystem/Plugins/PlayerInputTests.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs index b4b22c3dff..fabbfe89b4 100644 --- a/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs +++ b/Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs @@ -395,6 +395,21 @@ public void PlayerInput_CanAssignActionsToPlayer() Assert.That(playerInput.actions.actionMaps[0].name, Is.EqualTo(actions.actionMaps[0].name)); } + [Test] + [Category("PlayerInput")] + public void PlayerInput_CopiesActionAssetForFirstPlayer() + { + var go = new GameObject(); + var playerInput = go.AddComponent(); + + var actions = InputActionAsset.FromJson(kActions); + playerInput.actions = actions; + + Assert.That(playerInput.actions.actionMaps.Count, Is.EqualTo(actions.actionMaps.Count)); + Assert.That(playerInput.actions.actionMaps[0].name, Is.EqualTo(actions.actionMaps[0].name)); + Assert.That(playerInput.actions.GetInstanceID(), !Is.EqualTo(actions.GetInstanceID())); + } + [Test] [Category("PlayerInput")] public void PlayerInput_AssigningNewActionsToPlayer_DisablesExistingActions() From ce0a9a5b4b6578e2ee3ded2918cd80c4cf539a74 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Fri, 28 Feb 2025 15:29:17 +0100 Subject: [PATCH 15/16] renamed copy function --- .../InputSystem/Plugins/PlayerInput/PlayerInput.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs index 2e9b2056ee..9468230bab 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/PlayerInput/PlayerInput.cs @@ -348,7 +348,7 @@ public InputActionAsset actions if (didChange || m_Enabled) // copy action asset for the first player so that the original asset stays untouched - CopyActionAsset(); + CopyActionAssetAndApplyBindingOverrides(); if (m_Enabled) { @@ -1379,7 +1379,7 @@ private void InitializeActions() for (var i = 0; i < s_AllActivePlayersCount; ++i) if (s_AllActivePlayers[i].m_Actions == m_Actions && s_AllActivePlayers[i] != this) { - CopyActionAsset(); + CopyActionAssetAndApplyBindingOverrides(); break; } @@ -1429,7 +1429,7 @@ private void InitializeActions() m_ActionsInitialized = true; } - private void CopyActionAsset() + private void CopyActionAssetAndApplyBindingOverrides() { // duplicate action asset to not operate on the original (as it might be used outside - eg project wide action asset or UIInputModule) var oldActions = m_Actions; @@ -1814,7 +1814,7 @@ private void Awake() { // If an action asset is assigned copy it to avoid modifying the original asset. if (m_Actions != null) - CopyActionAsset(); + CopyActionAssetAndApplyBindingOverrides(); } private void OnEnable() From 93a4c691067c61bb351594c2c95713dfe3c6ae47 Mon Sep 17 00:00:00 2001 From: Rita Merkl Date: Mon, 3 Mar 2025 12:57:08 +0100 Subject: [PATCH 16/16] enable actions on entered playmode --- Packages/com.unity.inputsystem/InputSystem/InputSystem.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs index ad9c7ad671..eb7a35dcd7 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs @@ -3651,6 +3651,9 @@ internal static void OnPlayModeChange(PlayModeStateChange change) case PlayModeStateChange.EnteredPlayMode: s_SystemObject.enterPlayModeTime = InputRuntime.s_Instance.currentTime; s_Manager.SyncAllDevicesAfterEnteringPlayMode(); +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + EnableActions(); +#endif // UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS break; case PlayModeStateChange.ExitingPlayMode: