Skip to content

FIX: PlayerInput does not work with C# wrappers (ISXB-1535) #2188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,21 @@ coverage:
round: down
range: "50...70"
status:
patch: true
patch:
default:
target: auto
threshold: 1%
base: auto
if_ci_failed: success
informational: true
only_pulls: true
default_rules:
flag_coverage_not_uploaded_behavior: exclude
project:
default:
target: auto
threshold: 1%
base: auto
base: auto
if_ci_failed: success
informational: true
only_pulls: true
Expand Down
51 changes: 47 additions & 4 deletions Assets/Tests/InputSystem/CoreTests_Editor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2893,9 +2893,9 @@ public void Editor_WhenRunUpdatesInEditModeIsEnabled_InputActionsTriggerInEditMo
private static void DisableProjectWideActions()
{
#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
// If the system has project-wide input actions they will also trigger enable/disable via
// play mode change triggers above. Hence we adjust extra variable to compensate of
// state allocated by project-wide actions.
// If the system has project-wide input actions they will start enabled once InputSystem.Reset() is called and
// be disabled entering EditMode. Hence, we adjust extra variable to compensate ofstate allocated by
// project-wide actions.
if (InputSystem.actions)
{
Assert.That(InputActionState.s_GlobalState.globalList.length, Is.EqualTo(1));
Expand All @@ -2905,6 +2905,39 @@ private static void DisableProjectWideActions()
#endif
}

[Test]
[Category("Editor")]
public void Editor_InitializeInEditor_EnablesProjectWideActions()
{
#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
if (InputSystem.actions != null)
{
// Asserts that project wide actions are enabled by default.
// Before the test is run, InputSystem.Reset() is called which will enable them.
// It can be interpreted as a mock of the behavior that happens when `InitializeInEditor()` is called.
Assert.That(InputSystem.actions.enabled, Is.True);

// Calling exit play mode callbacks will disable them
InputSystem.OnPlayModeChange(PlayModeStateChange.ExitingPlayMode);
InputSystem.OnPlayModeChange(PlayModeStateChange.EnteredEditMode);

Assert.That(InputSystem.actions.enabled, Is.False);

// Calling enter play mode callbacks will not re-enable them per default. They are only
// enabled when `InputSystem.InitializeInEditor()` is called, which happens before these callbacks.
// Note: Project-wide actions are disabled at this point. These next lines are added to make sure we
// establish behavior that project-wide actions should be enabled only once
// `InputSystem.InitializeInEditor()` is called. Before this test was introduced, project-wide actions were
// enabled after entering play mode again which would lead to a different behavior than Player
// builds.
InputSystem.OnPlayModeChange(PlayModeStateChange.ExitingEditMode);
InputSystem.OnPlayModeChange(PlayModeStateChange.EnteredPlayMode);

Assert.That(InputSystem.actions.enabled, Is.False);
}
#endif
}

[Test]
[Category("Editor")]
public void Editor_LeavingPlayMode_DestroysAllActionStates()
Expand All @@ -2918,6 +2951,15 @@ public void Editor_LeavingPlayMode_DestroysAllActionStates()

// Enter play mode.
InputSystem.OnPlayModeChange(PlayModeStateChange.ExitingEditMode);

#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS

// This simulates enabling project-wide actions, which is done before just before entering play mode,
// called from InputSystem.InitializeInEditor().
if (InputSystem.actions)
InputSystem.actions.Enable();
#endif

InputSystem.OnPlayModeChange(PlayModeStateChange.EnteredPlayMode);

DisableProjectWideActions();
Expand All @@ -2934,7 +2976,8 @@ public void Editor_LeavingPlayMode_DestroysAllActionStates()
InputSystem.OnPlayModeChange(PlayModeStateChange.EnteredEditMode);

Assert.That(InputActionState.s_GlobalState.globalList.length, Is.Zero);
Assert.That(InputSystem.s_Manager.m_StateChangeMonitors[0].listeners[0].control, Is.Null); // Won't get removed, just cleared.
// Won't get removed, just cleared.
Assert.That(InputSystem.s_Manager.m_StateChangeMonitors[0].listeners[0].control, Is.Null);
}

[Test]
Expand Down
62 changes: 59 additions & 3 deletions Assets/Tests/InputSystem/CoreTests_ProjectWideActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
using NUnit.Framework;
using UnityEngine.InputSystem;
using UnityEngine.TestTools;
using UnityEngine;
using System.Collections;

#if UNITY_EDITOR
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.InputSystem.Editor;
#endif // UNITY_EDITOR

Expand Down Expand Up @@ -101,10 +102,10 @@ public void ProjectWideActions_IsAutomaticallyAssignedFromPersistedAsset_WhenRun
Assert.That(InputSystem.actions, Is.Not.Null);

// In editor play-mode we may as well verify that the asset has the expected name
#if UNITY_EDITOR
#if UNITY_EDITOR
var expectedName = InputActionImporter.NameFromAssetPath(AssetDatabase.GetAssetPath(InputSystem.actions));
Assert.That(InputSystem.actions.name, Is.EqualTo(expectedName));
#endif
#endif
}

[Test]
Expand Down Expand Up @@ -140,6 +141,61 @@ public void ProjectWideActions_AppearInEnabledActions()

// TODO Modifying the actions object after being assigned should also enable newly added actions?
}

[Category(TestCategory)]
[Test]
[TestCase("Player", true, Description = "PlayerInput using project-wide actions can have default action map set " +
"enabled, and all others disabled.")]
[TestCase(null, false, Description = "PlayerInput using project wide actions has all action maps of project-wide " +
"actions disabled, if there is no default action map assigned.")]
public void ProjectWideActions_CanEnableCurrentActionMapOfPlayerInput(string actionMapName, bool expectedResult)
{
var keyboard = InputSystem.AddDevice<Keyboard>();
var go = new GameObject("PlayerInput");

go.SetActive(false);
var playerInput = go.AddComponent<PlayerInput>();
playerInput.actions = InputSystem.actions;
// Default action map to be enabled. All others are expected to be disabled since InputSystem.actions.Disable()
// will be called.
playerInput.defaultActionMap = actionMapName;

// PWA actions assigned to playerInput start enabled
Assert.That(playerInput.actions.enabled, Is.True);
Assert.That(ReferenceEquals(playerInput.actions, InputSystem.actions));

#if UNITY_EDITOR
InputSystem.OnPlayModeChange(PlayModeStateChange.ExitingEditMode);
#endif

// This makes sure to call PlayerInput.OnEnable()
go.SetActive(true);

// This mimics usings to disabling actions on Start/Awake.
InputSystem.actions.Disable();

if (!string.IsNullOrEmpty(actionMapName))
playerInput.SwitchCurrentActionMap("Player");

Assert.That(playerInput.actions.enabled, Is.EqualTo(expectedResult));

// We do this on the editor to make sure project-wide actions maintain the enabled state
// after entering PlayMode.
#if UNITY_EDITOR
InputSystem.OnPlayModeChange(PlayModeStateChange.EnteredPlayMode);
Assert.That(playerInput.actions.enabled, Is.EqualTo(expectedResult));
#endif

if (!string.IsNullOrEmpty(actionMapName))
Assert.That(playerInput.currentActionMap.enabled, Is.EqualTo(expectedResult));

// Check state of all action maps in the asset
Assert.That(InputSystem.actions.FindActionMap("Player").enabled, Is.EqualTo(expectedResult));
Assert.That(InputSystem.actions.FindActionMap("UI").enabled, Is.False);

//NOTE: Asset actions are considered enabled even if a single action map is enabled
Assert.That(playerInput.actions.enabled, Is.EqualTo(expectedResult));
}
}

#endif
37 changes: 19 additions & 18 deletions Assets/Tests/InputSystem/Plugins/PlayerInputTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.actionMaps.Count, Is.EqualTo(prefabPlayerInput.actions.actionMaps.Count));
Assert.That(player.actions, Is.SameAs(prefabPlayerInput.actions));
Assert.That(player.devices, Is.EquivalentTo(new[] { gamepad }));
Assert.That(player.currentControlScheme, Is.EqualTo("Gamepad"));
}
Expand Down Expand Up @@ -395,21 +395,6 @@ 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<PlayerInput>();

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()
Expand All @@ -424,12 +409,12 @@ public void PlayerInput_AssigningNewActionsToPlayer_DisablesExistingActions()
playerInput.actions = actions1;

Assert.That(playerInput.actions.actionMaps[0].enabled, Is.True);
Assert.That(actions1.actionMaps[0].enabled, Is.False);
Assert.That(actions2.actionMaps[0].enabled, Is.False);

playerInput.actions = actions2;

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);
}

[Test]
Expand Down Expand Up @@ -497,6 +482,22 @@ public void PlayerInput_DuplicatingActions_AssignsNewInstanceToUI()
Assert.That(playerInput2.actions, Is.SameAs(ui2.actionsAsset));
}

[Test]
[Category("PlayerInput")]
public void PlayerInput_ActionFromCodeGeneratedActionIsTheSameBeingReferenced()
{
var go = new GameObject();

var playerInput = go.AddComponent<PlayerInput>();
var ui = go.AddComponent<InputSystemUIInputModule>();
var defaultActions = new DefaultInputActions();

playerInput.uiInputModule = ui;
playerInput.actions = defaultActions.asset;

Assert.That(defaultActions.UI.Submit == playerInput.actions.FindAction("Submit"), Is.True);
}

[Test]
[Category("PlayerInput")]
public void PlayerInput_CanPassivateAndReactivateInputBySendingMessages()
Expand Down
1 change: 1 addition & 0 deletions Packages/com.unity.inputsystem/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ however, it has to be formatted properly to pass verification tests.
- Fixed PlayerInput component automatically switching away from the default ActionMap set to 'None'.
- Fixed a console error being shown when targeting visionOS builds in 2022.3.
- Fixed a Tap Interaction issue with analog controls. The Tap interaction would keep re-starting after timeout. [ISXB-627](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-627)
- Fixed PlayerInput component not working with C# Wrappers (ISXB-1535). This reverted changes done to fix [ISXB-920](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-920) but users can now fix it themselves.

## [1.14.0] - 2025-03-20

Expand Down
Loading