Controls Changed Event not invoking on scene change

Hello, I am not sure if this is a bug or if I am doing something wrong. However, as stated in the title, when I change scenes the ControlsChangedEvent from the PlayerInput component is not firing. I have tried using SendMessage and C# events with the same result.

My player index remains the same between scenes as it is a single-player game and the Device Lost and Device Regained events fire when they should. There is also no issue with my inputs being read.

As the project is quite large, to eliminate anything else in the project causing issues, I made a new project with one script to read two inputs and add a listener to the unity event controlsChangedEvent.

When loading the first scene, all is good. Once you change scenes, the inputs work but the event does not invoke.

Here is the simple script I threw together. All I did was put that on a gameobject with the PlayerInput Component and duplicated the scene changing the buildIndex int on the second scene so I could switch back and forth while testing. I have also attached a zipped file containing the test project.

Thanks

public class InputTest : MonoBehaviour
{
    public PlayerInput playerInput;

    public InputActionAsset InputAsset;
    private InputActionMap _map;
  
    public int buildIndex;
       
    private void Start()
    {
        playerInput.controlsChangedEvent.AddListener(test);
       
        _map = InputAsset.FindActionMap("Map");
        _map.Enable();

        _map["Space"].performed += OnPress;
        _map["Scene"].performed += OnSceneChange;
    }

    private void OnDisable()
    {
        playerInput.controlsChangedEvent.RemoveListener(test);

        _map["Space"].performed -= OnPress;
        _map["Scene"].performed -= OnSceneChange;
    }

    private void OnSceneChange(InputAction.CallbackContext obj)
    {
        UnityEngine.SceneManagement.SceneManager.LoadScene(buildIndex);
    }

    private void OnPress(InputAction.CallbackContext obj)
    {
        Debug.Log("Pressed");
    }

    private void test(PlayerInput arg0)
    {
        Debug.Log("Controls Changed");
    }
}

5819068–616534–Input Test.zip (24.3 KB)

2 Likes

Hello,

To solve this problem, you just need to set “Behavior” parameter of your PlayerInput on “Invoke Unity Events” !

:slight_smile:

5923997--633098--CapturePlayerInput.PNG

Sorry but no, that’s not the issue. The prefab which the playerinput is on in every scene is set to invoke unity events

1 Like

I was able to reproduce it, does seem like a bud. I was registering my method on enable and deregistering on disable.
I tried using the same Player in my initial scene throughout the scene by making it DoNotDestroy and tried it out. It worked that way.
Is it possible for you to change it to such implementation at this time?

1 Like

Same here, I could reproduce it on scene change. Even if you unsubscribe from the event OnDestroy or a C# Destructor it still won’t get called.
In the meantime I solved it using GaZnoDrone solution. But it is a bug nonetheless.

Still not fixed… Rene-Damm

1 Like

This bug is preventing my game from being approved by Valve for release on Steam in 2 weeks time. Please fix this asap.

1 Like

Ok, this is a temporary way to detect it yourself until there is a fix. You could probably swap out Update for Coroutine looping on a timer for better performance but this way works for me.

using UnityEngine;
using UnityEngine.InputSystem;

public class Input : MonoBehaviour
{
    private string currentControlScheme;
    public PlayerInput playerInput;

    private void Update()
    {
        if (playerInput.currentControlScheme != currentControlScheme)
        {
            OnControlSchemeChanged();
            currentControlScheme = playerInput.currentControlScheme;
        }
    }

    public void OnControlSchemeChanged()
    {
        if (playerInput.currentControlScheme == "Keyboard")
        {
            // Keyboard code
        }
        else
        {
            // Gamepad code
        }
    }
}
1 Like

Same problem here. Doesn’t seem like it’s fixed in the 1.1 preview builds either.

I have the same issue, using Unity 2020.2.1f1

I’m having a similar issue where Vector2 value from the mouse position and the action bound to the left mouse button stops updating on scene change. It’s a single-player game, and I tried using DoNotDestroyOnLoad as well as just instantiating a prefab in the next scene. The rest of the inputs work fine, but it just stops reading the mouse.

I have the same problem. Spend a bit of time to figure out what’s going on and it turns out it’s a pretty simple/obvious issue (once you’ve found it… which took a bit longer tahtn I like to admin).

Anyway the issue is in InputUser

        private static void UnhookFromActionChange()
        {
            if (!s_OnActionChangeHooked)
                return;
            InputSystem.onActionChange -= OnActionChange;
            s_OnActionChangeHooked = true;
        }

Settting s_OnActionChangeHooked to false here fixes the issue. This seems pretty obvious if you look at the other Unhook methods there as all of them set their respective s_On…Hooked to false, except in that case → most likely a mistake and not intentional.

What is the best way to get that fix into the Input system?
For now I’m hoping that @Rene-Damm sees this post :roll_eyes:

6 Likes

Great find! Tried the suggestion above & it works now. Bumping so more people can see it & we get this fixed soon.

2 Likes

I can’t get the events to fire even without switching scenes.

Just a quick update. My Fix should be in a future Input System release.
See FIX: InputUser stopping to send ControlsChanged notification. by Rene-Damm · Pull Request #1296 · Unity-Technologies/InputSystem · GitHub

2 Likes

I wonder when this fix gonna grow to stable Input System release.

Hey guys, i have never managed successfully use “onControlsChanged” callbacks…

I am looking into way to get a callback when player switches to keyboard, gamepad steering wheel etc…
Is this callback the way to go and exactly i suppose to use it !?

Could you please explain how to use this… ?

Yes, this is the right way to do it, but it doesn’t work right now, the issue is that when you load another scene while you are in game the callback stop working. We are waiting for the next input system update/patch that fix the issue.
So if you are gonna use only one scene i will explain how to use it.

1 Like

Hey thanks… but it turns out that it works for me even if i change a scene now…
The reason it didn’t worked before is that i had that optional Gamepad entry in Keyboard control scheme… after i removed the Gamepad entry that’s visible in the image, the system started to reports when i start using the keyboard or the gamepad or even a steering wheel, even if i load another scene, at least in editor. I didn’t try in builds ! That’s on the latest 1.1.0 preview 3

7158211--856966--upload_2021-5-20_10-4-9.png

@Vagabond How did you manage to install 1.1.0 preview version? It does not show up for me in Package Manager.

P.S. Yes I have Preview packages enabled in Settings.