I’ve run into another problem… I’ve got my entire input manager built, but I’m having trouble identifying joysticks by id. The only function I’ve found for determining anything about connected joysticks is Input.GetJoystickNames which returns a string of joysticks connected since run. I was using this returned string to get names of controllers for the config screen to let users choose which player is using which controller. I also use this name list to determine which joysticks are in which positions (joy 0 - joy 3) and map to players accordingly. (I’m also planning on having default joystick config profiles based on the joystick name so I can set up decent defaults for more popular game controllers.)
PROBLEM: My entire house of cards just came falling down because I’ve determined the order of joysticks returned by Input.GetJoystickName DOES NOT relate to the order the joysticks are handled by unity. For example, a joystick in the returned name array in position [0] does not always equal the unity mapped Joystick1 (Input.GetKey(Joystick1Button0)). SOMETIMES it does, but sometimes it doesn’t. (Try connecting 3 or 4 different model controllers, doing a Input.GetJoystickNames to see your list of controllers, then poll all the joysticks while pressing buttons on various controllers and see how the mapping doesn’t always match.)
Is there any other way to determine what controllers are connected and what their respective unity joystick number is?
Example of how joystick names do not always match joystick ids:
// Slap this code onto an object in the scene then press buttons
// I recommend you test with 3-4 controllers (different models) for best effect
function Awake() {
var names : String[] = Input.GetJoystickNames();
Debug.Log("Connected Joysticks:");
for(var i : int = 0; i < names.length; i++) {
Debug.Log("Joystick" + (i + 1) + " = " + names[i]);
}
}
function Update() {
DebugLogJoystickButtonPresses();
}
private function DebugLogJoystickButtonPresses() : void {
var joyNum : int = 1; // start at 1 because unity calls them joystick 1 - 4
var buttonNum : int = 0;
var keyCode : int = 350; // start at joy 1 keycode
// log button presses on 3 joysticks (20 button inputs per joystick)
// NOTE THAT joystick 4 is not supported via keycodes for some reason, so only polling 1-3
for(var i : int = 0; i < 60; i++) {
// Log any key press
if(Input.GetKeyDown(keyCode+i)) Debug.Log("Pressed! Joystick " + joyNum + " Button " + buttonNum + " @ " + Time.time);
buttonNum++; // Increment
// Reset button count when we get to last joy button
if(buttonNum == 20) {
buttonNum = 0;
joyNum++; // next joystick
}
}
}
Unity Script Reference - Input.GetJoystickNames states:
Because the joystick id does not always map to the corresponding entry in the GetJoystickNames array, this statement in the Unity docs appears to be incorrect. I can see no way to use the names returned by this array as there’s no way to relate them to an individual controller.
The above test was done with all controllers connected to the system from program start, nothing removed. Therefore I’m confident it’s a bug and I’ve reported it. However, even if that bug is fixed in the future, there will still be a case of id mismatching if a controller is ever removed while the program is running. Ex: 3 controllers connected, controller id 1 is unplugged. Now GetJoystickNames() returns a 2 element array, 0 = id 0, 1 = id 2. Again, no way to associate a name with a joystick. There MUST be a way to access joysticks by id, THEN get name from that.
Update: Controller order seems to change depending on which USB controller the joysticks are plugged into. (In the off chance one of the dev team reads this, that may be somewhere to start testing.)
All these limitations with the Input class are seriously messing up my plans to have a good input experience for multiple players on one system.
Another example of the problems with Unity’s input handling:
I mentioned in my posts above that I was searching for a way to hot-plug controllers during the game and never found any way to do it. Here’s a real-world scenario that WILL cause big headaches for players, even in a single player game – Player is using Xbox 360 wireless controller or another wireless controller. Player pauses game and gets up to do something for 20 minutes. Controller shuts off. Unity drops controller from list. Player comes back and reconnects. Unity ignores the new controller. Player cannot control game anymore and is forced to quit with mouse/keyboard and re-run the game.
I’ve been working with unity for almost 2 years now and have found it to be all around great, but the Input class is just sorely lacking.