Joystick Runtime Plug/Unplug Detection

Hello,
I am using Unity 5.2.2 and checking at each frame if :

Input.GetJoystickNames().Length > 0

the issue is that this thing works one-way only. If I start the game without a Joystick, it detects whether a Joystick gets plugged in. If at this point I unplug the Joystick, that array doesn’t change and its length is still 1.
I’d like to know if any of you sirs know how to do correct runtime plug/unplug detection of joystick. Unity makes a warning appear on the console when joystick is unplugged, so I’m pretty sure there must be a way to catch that event, but I don’t seem to find it!

The Joystick I am using is a XBOX 360 controller.

For people who stumble upon this same problem, there is a way to do it within Unity.

As correctly stated by @Alakanu that the size of the string array does not reduce by one when disconnecting a controller, Unity does set the specific controller entry back to an empty string. So by simply checking if the entry is empty or not, you are able to determine when a controller gets connected / disconnected.

Example Code:

//Get Joystick Names
string[] temp = Input.GetJoystickNames();

//Check whether array contains anything
if(temp.Length > 0)
{
    //Iterate over every element
    for(int i =0; i < temp.Length; ++i)
    {
        //Check if the string is empty or not
        if(!string.IsNullOrEmpty(temp*))*

{
//Not empty, controller temp is connected
Debug.Log("Controller " + i + " is connected using: " + temp*);*
}
else
{
//If it is empty, controller i is disconnected
//where i indicates the controller number
Debug.Log(“Controller: " + i + " is disconnected.”);

}
}
}

I recommend you do not run this code every frame, but at a set interval (eg every 2 seconds) instead to save on performance.
Hope it helps!
Kind Regards,
Alex

I used system APIs to solve this problem. I leave my code here hoping it will help someone in the future. This works with xbox joystick, I haven’t tested with other gamepads since I don’t own any.

PlayerIndex singlePlayer = (PlayerIndex)0;
GamePadState testState = GamePad.GetState(singlePlayer);

if (testState.IsConnected)
{
    //joystick is connected
}
else
{
     //joystick is not connected
}

In my case I ended up implementing my own InputManager using Win32’s RawInput API in C++. This way you can detect disconnections and handle them yourself. You can even differentiate between multiple mice this way - And the multiple mice was the motivation to do so…

Here is sample implementation but for mice. Alter is to suit your needs. It properly detects XBOX Gamepads. There is the code needed to register for gamepads, but then you should read on since this example was intended to be used only for mice.

C++ DLL: RawInput Multiple mice - Pastebin.com C# script: RawInput Wrapper for Unity3d - Pastebin.com

Note that in Editor, Unity steals RawInput devices very feequently. I did not had any issues in a build, however.

I fashioned something similar to the accepted answer last year but just polished it to deal with controllers connecting and disconnecting.
This is tested and working when one type of controller is connected. I’m sure some wonkiness will happen if you have multiple different controllers plugged in.

Declare some variables:

    public bool playstationController, xboxController, keyboard;
    public string[] currentControllers;
    public float controllerCheckTimer = 2;
    public float controllerCheckTimerOG  = 2;

Then here’s a function I call when I want to check what’s currently connected:

 public void ControllerCheck()
    {
        System.Array.Clear(currentControllers, 0, currentControllers.Length);
        System.Array.Resize<string>(ref currentControllers, Input.GetJoystickNames().Length);
        int numberOfControllers = 0;
        for (int i = 0; i < Input.GetJoystickNames().Length; i++)
        {
            currentControllers _= Input.GetJoystickNames()*.ToLower();*_

if ((currentControllers == “controller (xbox 360 for windows)” || currentControllers == “controller (xbox 360 wireless receiver for windows)” || currentControllers == “controller (xbox one for windows)”))
{
xboxController = true;
keyboard = false;
playstationController = false;
}
else if (currentControllers == “wireless controller”)
{
playstationController = true; //not sure if wireless controller is just super generic but that’s what DS4 comes up as.
keyboard = false;
xboxController = false;
}
else if (currentControllers == “”)
{
numberOfControllers++;
}
}
if (numberOfControllers == Input.GetJoystickNames().Length)
{
keyboard = true;
xboxController = false;
playstationController = false;
}
}

As @AG_Alex mentioned, it’s not a good idea to do this in Update. I setup a timer so that if there’s no input, a timer ticks down and when it hits zero, it calls the ControllerCheck function.
if (!Input.GetButtonDown(“SingleFlap”) && !Input.GetButton(“MultiFlap”))
{
controllerCheckTimer -= Time.deltaTime;
if (controllerCheckTimer <= 0)
{
ControllerCheck();
controllerCheckTimer = controllerCheckTimerOG;
}
}
else
{
controllerCheckTimer = controllerCheckTimerOG;
}

The issue with the code snippets I’ve seen when searching for a solution is that Unity jumbles the order of connected devices. For example, if the 0th joystick is empty (keyboard), the 1st joystick is detected as being XBox, and the 2nd joystick is empty, at the end of the for loop you may not get what you wanted (i.e. an XBox controller is connected, but the last Joystick Unity detected is empty), so you may be SoL.
The basic idea with this function is to increment a temporary number each time the JoystickName comes back empty (keyboard or mouse or whatever else Unity decides is empty). Keyboard is only set to true if all of the connected Joysticks are empty. Otherwise, one of the other ones is set to true. I think this is a pretty good fix until Unity sorts out its joystick detection.
Cheers,
Eric G.

There is a little trick (not so tricky) that I’ve done though, i’m not sure if it’ll work for every console. But hey, it works on mine. Here’s the code.

 void Start() {
        StartCoroutine(delayCheck());
    }

    IEnumerator delayCheck() {
        yield return new WaitForSecondsRealtime(2f);
        for(int i = 0; i < Input.GetJoystickNames().Length; i++) {
            if (!string.IsNullOrEmpty(Input.GetJoystickNames()*)) {*

Debug.Log(“Joystick Connected”);
i = Input.GetJoystickNames().Length;
joystickDialogue = true;
} else {
Debug.Log(“Joystick Disconnected”);
i = Input.GetJoystickNames().Length;
joystickDialogue = false;
}
}
StopAllCoroutines();
StartCoroutine(delayCheck());
}
You might be in shock why I created my own version of “return”. Well, I don’t know why but, Unity returns both connected and disconnected without it.

This unplugged problem is same arisen by my joystick. it sometimes plugged in or sometimes not unplugged simultaneously. Then I find the solution of this to update my driver and my USB driver is older so I also update it after that this problem has not arisen with me. You can also try this. If anyone has the Router related problem like Wifi issue, Android device connection issue and any kind of wireless issue follow Linksys Router Support for help.