Search Unity

The value of Input.GetAxis("") gets stuck when Xbox controller is disconnected...

Discussion in 'Editor & General Support' started by el-RERS, Jul 6, 2018.

  1. el-RERS

    el-RERS

    Joined:
    Jul 12, 2014
    Posts:
    9
    Hello everyone, big problem here with Unity 2018.1:

    So my PC game can be controlled with either a keyboard or an Xbox controller. I want to give my players the option to disconnect the xbox controller and continue playing with the keyboard if they wanted to, the problem is, if the player happens to disconnect the controller while still pushing the left stick, the value of Input.GetAxis("") (either "Horizontal" or "Vertical") gets stuck and there is no way to get it back to zero unless the controller is reconnected.

    I already tried with Input.ResetInputAxes(), this will, indeed, cancel all button presses in the controller, but in the case of Input.GetAxis(""), it will return back to zero only for one frame, after that, it returns to the value in which it was stuck on...

    This can also happen if the player disconnects the controller while still pushing the analogue and then replaces it for another type of xbox controller, the value of the axis of the previous controller gets stuck and the new one can't get it back to 0

    Is there any way for a disconnected controller to stop giving value to Input.GetAxis("") ?? Kind of a cliffnote here: In the Editor, the value gets 'unstucked' if I interact with the Editor in any way (By selecting a gameobject or pausing the game view for example.... so what gives???? )

    Thanks in advance! and sorry for the bad english :(
     
  2. tsibiski

    tsibiski

    Joined:
    Jul 11, 2016
    Posts:
    604
    So I may be biased on this, but I always wrap the Input class with a custom Input. This would allow you to set a flag in your extension class that would block this behavior while the controller is disconnected.

    For example:

    Code (CSharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. using System.Runtime.InteropServices;
    5.  
    6. namespace UnityEngine {
    7.  
    8.     public static class UserInput {
    9.  
    10.         private static KeyCode _keyDown { get; set; }
    11.         private static string _keyPressed { get; set; }
    12.         private static float _keyDownTime { get; set; }
    13.         private static float _keyPressedTime { get; set; }
    14.         private static float _keyDownDuration { get; set; }
    15.         private static float _keyPressedDuration { get; set; }
    16.  
    17.         public static void SimulateKeyDown(KeyCode keyDown, int duration = 1) {
    18.  
    19.             _keyDown = keyDown;
    20.             _keyDownTime = Time.time;
    21.             _keyDownDuration = duration;
    22.  
    23.         }
    24.  
    25.         public static void SimulatePress(string keyPress, int duration = 1) {
    26.  
    27.             _keyPressed = keyPress;
    28.             _keyPressedTime = Time.time;
    29.             _keyPressedDuration = duration;
    30.  
    31.         }
    32.  
    33.         public static bool GetKeyDown(KeyCode key) {
    34.  
    35.             if(Time.time - _keyDownTime < _keyDownDuration) {
    36.  
    37.                 return _keyDown == key;
    38.  
    39.             } else {
    40.  
    41.                 return Input.GetKeyDown(key);
    42.  
    43.             }
    44.  
    45.         }
    46.  
    47.         public static bool GetButton(string key) {
    48.  
    49.             float time = Time.time;
    50.             if(time - _keyPressedTime < _keyPressedDuration) {
    51.  
    52.                 return _keyPressed == key;
    53.  
    54.             } else {
    55.  
    56.                 return Input.GetButton(key);
    57.  
    58.             }
    59.  
    60.         }
    61.  
    62.     }
    63.  
    64. }
    65.  
    Here I have abstracted various functions from Input. If you were to set a custom flag - maybe a property that keeps return "is the controller disconnected?", and have this value override whatever Input returns, then your problem would be solved. And implementing this is as simple as adding additional needed abstraction functions to the above script, and updating all Input.cs references in your code to UserInput.cs.

    Additionally, if there are any things you don't need to abstract or extend, just reference Input directly through the UserInput script. So you don't have to worry about losing out on any functionality until implementing an extension method.

    Note that this is an old version of this script. I updated it with a much better form that handles a list of all currently-pressed keys. But I am not finding it at the moment. So this will have to do.