Search Unity

Bug Controls Changed Event not invoking on scene change

Discussion in 'Input System' started by WarmedxMints, May 8, 2020.

  1. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    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

    Code (CSharp):
    1. public class InputTest : MonoBehaviour
    2. {
    3.     public PlayerInput playerInput;
    4.  
    5.     public InputActionAsset InputAsset;
    6.     private InputActionMap _map;
    7.  
    8.     public int buildIndex;
    9.        
    10.     private void Start()
    11.     {
    12.         playerInput.controlsChangedEvent.AddListener(test);
    13.        
    14.         _map = InputAsset.FindActionMap("Map");
    15.         _map.Enable();
    16.  
    17.         _map["Space"].performed += OnPress;
    18.         _map["Scene"].performed += OnSceneChange;
    19.     }
    20.  
    21.     private void OnDisable()
    22.     {
    23.         playerInput.controlsChangedEvent.RemoveListener(test);
    24.  
    25.         _map["Space"].performed -= OnPress;
    26.         _map["Scene"].performed -= OnSceneChange;
    27.     }
    28.  
    29.     private void OnSceneChange(InputAction.CallbackContext obj)
    30.     {
    31.         UnityEngine.SceneManagement.SceneManager.LoadScene(buildIndex);
    32.     }
    33.  
    34.     private void OnPress(InputAction.CallbackContext obj)
    35.     {
    36.         Debug.Log("Pressed");
    37.     }
    38.  
    39.     private void test(PlayerInput arg0)
    40.     {
    41.         Debug.Log("Controls Changed");
    42.     }
    43. }
     

    Attached Files:

    rubendariohh and jkolowca like this.
  2. ArmandTutu

    ArmandTutu

    Joined:
    Aug 7, 2014
    Posts:
    2
    Hello,

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

    :)
     

    Attached Files:

  3. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Sorry but no, that's not the issue. The prefab which the playerinput is on in every scene is set to invoke unity events
     
    rubendariohh likes this.
  4. GaZnoDrone

    GaZnoDrone

    Joined:
    Mar 3, 2015
    Posts:
    28
    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?
     
    Liderangel likes this.
  5. Liderangel

    Liderangel

    Joined:
    Jul 8, 2018
    Posts:
    101
    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.
     
  6. Dknighter2

    Dknighter2

    Joined:
    Aug 17, 2014
    Posts:
    44
    rubendariohh likes this.
  7. Dknighter2

    Dknighter2

    Joined:
    Aug 17, 2014
    Posts:
    44
    This bug is preventing my game from being approved by Valve for release on Steam in 2 weeks time. Please fix this asap.
     
    rubendariohh likes this.
  8. Dknighter2

    Dknighter2

    Joined:
    Aug 17, 2014
    Posts:
    44
    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.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.InputSystem;
    3.  
    4. public class Input : MonoBehaviour
    5. {
    6.     private string currentControlScheme;
    7.     public PlayerInput playerInput;
    8.  
    9.     private void Update()
    10.     {
    11.         if (playerInput.currentControlScheme != currentControlScheme)
    12.         {
    13.             OnControlSchemeChanged();
    14.             currentControlScheme = playerInput.currentControlScheme;
    15.         }
    16.     }
    17.  
    18.     public void OnControlSchemeChanged()
    19.     {
    20.         if (playerInput.currentControlScheme == "Keyboard")
    21.         {
    22.             // Keyboard code
    23.         }
    24.         else
    25.         {
    26.             // Gamepad code
    27.         }
    28.     }
    29. }
     
    rubendariohh likes this.
  9. Bingo90

    Bingo90

    Joined:
    May 26, 2019
    Posts:
    3
    Same problem here. Doesn't seem like it's fixed in the 1.1 preview builds either.
     
  10. dvoronin

    dvoronin

    Joined:
    Oct 19, 2016
    Posts:
    16
    I have the same issue, using Unity 2020.2.1f1
     
  11. adanawtn

    adanawtn

    Joined:
    Dec 6, 2020
    Posts:
    3
    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.
     
  12. DH_Sven

    DH_Sven

    Joined:
    Sep 23, 2020
    Posts:
    8
    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
    Code (CSharp):
    1.         private static void UnhookFromActionChange()
    2.         {
    3.             if (!s_OnActionChangeHooked)
    4.                 return;
    5.             InputSystem.onActionChange -= OnActionChange;
    6.             s_OnActionChangeHooked = true;
    7.         }
    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 :rolleyes:
     
  13. dvoronin

    dvoronin

    Joined:
    Oct 19, 2016
    Posts:
    16
    Great find! Tried the suggestion above & it works now. Bumping so more people can see it & we get this fixed soon.
     
    rubendariohh and WILDBoYee like this.
  14. Shizola

    Shizola

    Joined:
    Jun 29, 2014
    Posts:
    475
    I can't get the events to fire even without switching scenes.
     
  15. DH_Sven

    DH_Sven

    Joined:
    Sep 23, 2020
    Posts:
    8
    AndreaGalet and dvoronin like this.
  16. dvoronin

    dvoronin

    Joined:
    Oct 19, 2016
    Posts:
    16
    I wonder when this fix gonna grow to stable Input System release.
     
  17. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    1,148
    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... ?
     
  18. AndreaGalet

    AndreaGalet

    Joined:
    May 21, 2020
    Posts:
    97
    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.
     
    pradotech likes this.
  19. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    1,148
    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

    upload_2021-5-20_10-4-9.png
     
    Last edited: May 20, 2021
  20. dvoronin

    dvoronin

    Joined:
    Oct 19, 2016
    Posts:
    16
    @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.
     
  21. You need to use Unity 2020.3.8f1. (Well, use 2020.3 LTS in general)
     
  22. dvoronin

    dvoronin

    Joined:
    Oct 19, 2016
    Posts:
    16
  23. No, as I said, you need to use 2020.3 in order to get it.
     
  24. pradotech

    pradotech

    Joined:
    Oct 17, 2019
    Posts:
    35
    My game is based in one scene only. At the first playthrough, OnontrolsChanged is called properly and works as expected. But after reloading the scene, it stops working, requiring to restart the game. It happens in Editor as in android build. Can you share your workaround? (I'm using Unity 2020.3.12f1 and verified Input System 1.0.2)

    Edit: I figured out how to DH_Sven suggestion:
    I copied Input System package to Packages folder, then edited InputUser.cs as here: https://github.com/Unity-Technologies/InputSystem/pull/1292/files

    In Editor is working properly, hope that works in android build too.
     
    Last edited: Jun 29, 2021
  25. Wawwaa

    Wawwaa

    Joined:
    Sep 30, 2017
    Posts:
    165
    Interestingly, on Unity 2021.1.7, nothing worked for me. Even making a custom script that is a singleton which will survive scene changes and assigning events of PlayerInput.cs to that singleton methods which trigger its own delegates that are registered and unregistered by other scripts did not work on build. It works on editor, it doesn't work on build. There seems to be a deeper problem in OnControlsChanged(PlayerInput playerInput) callback in build, not in editor... Or, there might be a problem on switching action maps in build, when any scenes are destroyed - incase of the singleton approach. Hope Unity guys dig into it.
     
    Last edited: Jul 2, 2021
  26. AnAngelineer

    AnAngelineer

    Joined:
    Nov 4, 2015
    Posts:
    34
    Unity does not let me edit the Input Package files. It says it's "immuable".
     
  27. pradotech

    pradotech

    Joined:
    Oct 17, 2019
    Posts:
    35
    To edit the files you need to copy the Input System package folder (com.unity.inputsystem@x.x.x) into "Packages" folder inside your project. After that Unity will reimport Input System as a custom package, then you are able to edit the scripts.
     
  28. Wawwaa

    Wawwaa

    Joined:
    Sep 30, 2017
    Posts:
    165
    In my case, I was additively loading new scene and after that unloading the old scene. When I had PlayerInput.cs in 2 consecutive scenes, OnControlsChanged event was not called even though I did the trick told here. Then, I tried to insert a temporary scene in between those 2 consecutive scenes that have PlayerInput.cs. It worked.

    I think, when unregistering the event, system unregisters all of the registered events in the consecutive scenes. For example, scene 1 method 1 is registered, scene 2 is loaded and its method 2 is registered; right after this, scene 1 is unloaded and input system calls to unregister events, but instead of unregistering only method 1 which belongs to scene 1, it also unregisters method 2 which belongs to scene 2. Inserting a scene that does not have a PlayerInput.cs script normalizes the process. That's why it is working with insertion setup. Not an expert, but I gave lots of time for this by experimenting different setups, and this is my only explanation.
     
  29. Pnvanol

    Pnvanol

    Joined:
    Jan 11, 2016
    Posts:
    116
    I installed preview 1.0.3 but still events are not called for ondevice changed... any fix yet?
     
  30. Pnvanol

    Pnvanol

    Joined:
    Jan 11, 2016
    Posts:
    116
    How can I apply this where can I write this code?
     
  31. DH_Sven

    DH_Sven

    Joined:
    Sep 23, 2020
    Posts:
    8
    it's fixed in 1.1.0 since pre4, sadly still not fixed in 1.0.x
     
  32. DH_Sven

    DH_Sven

    Joined:
    Sep 23, 2020
    Posts:
    8
  33. Saikodan

    Saikodan

    Joined:
    Jan 13, 2015
    Posts:
    7
    Unity 2020.3.24f1, input system - 1.1.0-pre6 doesn't work. 1.2.0 doesn't work.
    I'm really lost here.
    Anyone?
     
  34. clayton_axel

    clayton_axel

    Joined:
    Dec 4, 2018
    Posts:
    3
    Unity fix this please :(
     
  35. corjn

    corjn

    Joined:
    Feb 6, 2014
    Posts:
    168
    This is still not fixed after 2 years ? Such a shame.
     
  36. JuTekPixel

    JuTekPixel

    Joined:
    Sep 17, 2018
    Posts:
    7

    Wow, this works like a charm... great solution Thanks
     
  37. rubendariohh

    rubendariohh

    Joined:
    Oct 14, 2017
    Posts:
    32
    How did you edit the Scritp? When I tried to edit it I receive an error message about a "immutable asset". Is there a way to edit an immutable asset?

    The package cache was invalidated and rebuilt because the following immutable asset(s) were unexpectedly altered:
    Packages/com.unity.inputsystem/InputSystem/Plugins/Users/InputUser.cs
     
  38. DH_Sven

    DH_Sven

    Joined:
    Sep 23, 2020
    Posts:
    8
    By making a mutable asset out of it. ;-)

    e.g. by making a local package out of it -> https://docs.unity3d.com/Manual/upm-ui-local.html
    or by forking the git repo and making the changes there and include that into the project.
     
    rubendariohh likes this.