Hi,
On Windows Desktop and Android, the Saitek p990 is detected with Input.GetJoystickNames() but not on Windows10, Why?
I think this has to be the case with other controllers.
What API should be use for this?
Greetings.
Hi,
On Windows Desktop and Android, the Saitek p990 is detected with Input.GetJoystickNames() but not on Windows10, Why?
I think this has to be the case with other controllers.
What API should be use for this?
Greetings.
That is not least bit surprising since in various Windows 10 updates Microsoft has had driver problems even with their own XBOX ONE game controllers have been impacted a few times (march 2016 and summer 2016 are the main ones I recall). That is not even including Unity in the equation.
You might try a third party solution like Rewired which supports that Saitek p990 controller since it should work fine on windows 10.
The list of supported controllers is here.
http://guavaman.com/projects/rewired/docs/SupportedControllers.html
You can try the trial version of Rewired and at least see if that allows your controller to work as expected on Windows 10.
https://www.assetstore.unity3d.com/en/#!/content/21676
You can get the trial version of Rewired and see if it solves your problem.
http://guavaman.com/projects/rewired/trial.html
longroadhwy,
Thank you for your answer.
It is still amazing that an engine as important as Unity does not have perfect management of the joysticks. For example with Android when you unplug a joystick the list returned by Input.GetJoystickNames () is not updated and all management in the Unity input manager is distorted. To remedy this I had to create a plugin and use InputDevice.getDeviceIds () to have the real list of controllers, this is a waste of time.
Greetings.
I wonder if your Android issue is related to this one posted in the Rewired forum?
https://forum.unity3d.com/threads/rewired-advanced-input-for-unity.270693/page-56#post-2955607
I know what you mean. I had the same reaction when the XBOX 360 controller was not working on Windows desktop. Then if you use flight controllers you are completely blocked with Unity’s limit of 20 buttons. Then try moving to Mac and Linux with flight controllers. So that is why I use Rewired today on all of my projects.
longroadhwy,
It’s exactly that. The link speaks well of the problem.
My version is 5.5.0f3, may be that with version 5.6 it’s ok.
I will update.
Greetings.
It should work if you enable Human Interface Device (HID) capability.
Hi,
Tautvydas-Zilys,
I have updated to 5.6, on desktop and android it’s ok but now on windows10
building is going well but after the splashscreen an error occur :
System.ArgumentOutOfRangeException in mscorlib.ni.dll
I am looking for a solution.
For the moment i can’t test the joystick.
Greetings.
Probably an exception happens in your code somewhere? Debugger should give you the callstack… Either way, it’s probably not fatal and you should be able to continue past it.
Tautvydas-Zilys,
So I tested under windows10 but some joysticks are detected twice as the xbox360 controller or Tronsmart G01 while the xboxOne and the saitek are only once. I added this to the manifest:
<DeviceCapability Name="humaninterfacedevice">
<Device Id="any">
<Function Type="usage:0005 *"/>
</Device>
</DeviceCapability>
Greetings.
Tautvydas-Zilys,
A small error in the manifest:
<Capabilities>
<DeviceCapability Name="humaninterfacedevice">
<Device Id="any">
<Function Type="usage:0001 *"/>
</Device>
</DeviceCapability>
</Capabilities>
And to detect the joysticks (may not be all):
async void EnumerateHidDevices()
{
string selector = HidDevice.GetDeviceSelector(0x01, 0x05)+" OR 4";
var devices = await DeviceInformation.FindAllAsync(selector);
for (int i= 0; i < devices.Count; i++)
{
HidDevice device = await HidDevice.FromIdAsync(devices.ElementAt(i).Id, FileAccessMode.Read);
if (device == null)
continue;
device.InputReportReceived += HandleInputReportRecieved;
}
}
void HandleInputReportRecieved(HidDevice sender, HidInputReportReceivedEventArgs args)
{
//...
}
But again it’s extra work !
Greetings.
What version of Windows 10 are you using? Windows 10 home, pro or enterprise? You are using the 64-bit version of Windows I am guessing right?
Unity should generate manifest like this:
<DeviceCapability Name="humaninterfacedevice">
<Device Id="any">
<Function Type="usage:0001 0004"/>
</Device>
<Device Id="any">
<Function Type="usage:0001 0005"/>
</Device>
</DeviceCapability>
I just checked our C++ code which receives input, and it indeed uses both “0x01 0x04” and “0x01 0x05” device selectors. Does something not work after you fixed your manifest?
longroadhwy > Windows10 x64 pro.
Tautvydas-Zilys > I have always two entries in GetJoystickNames() for one xbox controller (360 or One). Its’ ok for others (saitek, tronsmart…). If i switch the tronsmart to xinput mode, it’s the same, it is recognized as an xbox controller and there are two entries in GettJoystickNames() : “xbox controller” and xbox 360 controller for windows".
Your modification of the manifest is correct mine was wrong (usage:0005 *) because all HidDevice are null.
Greetings.
Hi,
I created a personal class that handles all my joysticks under win10. I do not know if it works with all gamepads (ps3, ps4 …) but my 5 joysticks are recognized. I only use the pad in my game (UI menu) but the stick is manageable in inputReportReceived. The manifest must be modified as indicated above. If this can help:
public class Controller
{
enum ControllerDirection { None, Up, UpRight, Right, DownRight, Down, DownLeft, Left, UpLeft }
public GamepadButtons Buttons { get; private set; }
public static List<Controller> ListControllers = new List<Controller>();
static DeviceWatcher watcher;
readonly HidDevice device;
readonly string ID;
static int[] convert = { 0, 4, 8, 16, 32, 1024, 2048, 2, 1, 4096, 8192 };
ControllerDirection DirPad;
public static bool IsPressedA(int player) { return ListControllers[player].Buttons == GamepadButtons.A; }
public static bool IsPressedB(int player) { return ListControllers[player].Buttons == GamepadButtons.B; }
public static bool IsPressedX(int player) { return ListControllers[player].Buttons == GamepadButtons.X; }
public static bool IsPressedY(int player) { return ListControllers[player].Buttons == GamepadButtons.Y; }
public static float DirPadX(int player)
{
if (ListControllers[player].DirPad == ControllerDirection.Left)
return -1;
else if (ListControllers[player].DirPad == ControllerDirection.Right)
return 1;
else
return 0;
}
public static float DirPadY(int player)
{
if (ListControllers[player].DirPad == ControllerDirection.Down)
return -1;
else if (ListControllers[player].DirPad == ControllerDirection.Up)
return 1;
else
return 0;
}
public Controller(HidDevice newDevice, string id)
{
device = newDevice;
ID = id;
device.InputReportReceived += inputReportReceived;
}
//////////////////////////////////////////////////////////////////////////////////
public static void EnumerateHidDevices()
{
string selector = HidDevice.GetDeviceSelector(0x01, 0x05) + " OR 4";
watcher = DeviceInformation.CreateWatcher(selector);
watcher.Added += HandleAdded;
watcher.Removed += HandleRemoved;
watcher.Start();
}
//////////////////////////////////////////////////////////////////////////////////
static async void HandleAdded(DeviceWatcher sender, DeviceInformation args)
{
HidDevice device = await HidDevice.FromIdAsync(args.Id, FileAccessMode.Read);
if (device == null)
return;
Controller controller = new Controller(device, args.Id);
ListControllers.Add(controller);
}
//////////////////////////////////////////////////////////////////////////////////
static void HandleRemoved(DeviceWatcher sender, DeviceInformationUpdate args)
{
ListControllers.Remove(ListControllers.Find((c) => args.Id == c.ID));
}
//////////////////////////////////////////////////////////////////////////////////
void inputReportReceived(HidDevice sender, HidInputReportReceivedEventArgs args)
{
int dPad = (int)args.Report.GetNumericControl(0x01, 0x39).Value;
DirPad = (ControllerDirection)dPad;
CheckButtons(args.Report.ActivatedBooleanControls);
}
//////////////////////////////////////////////////////////////////////////////////
void CheckButtons(IReadOnlyList<HidBooleanControl> activatedBooleanControls)
{
if (activatedBooleanControls.Count > 0)
for (int i = 0; i < activatedBooleanControls.Count; i++)
if (activatedBooleanControls[i].UsageId < convert.Length)
Buttons |= (GamepadButtons)convert[activatedBooleanControls[i].UsageId];
else
Buttons = GamepadButtons.None;
else
Buttons = GamepadButtons.None;
}
}
Greetings.
Do you handle non gamepad devices (e.g. ThrustMaster T16000M joystick)?
Hi longroadhwy,
I have not tested this joystick but with the AQS string (0x04 + 0x05)
you must be able to select all game controllers :
Usage PageUsageHardware ID
Pointer 0x01 0x01 HID_DEVICE_SYSTEM_MOUSE
Mouse 0x01 0x02 HID_DEVICE_SYSTEM_MOUSE
Joystick 0x01 0x04 HID_DEVICE_SYSTEM_GAME
Game pad 0x01 0x05 HID_DEVICE_SYSTEM_GAME
Keyboard 0x01 0x06 HID_DEVICE_SYSTEM_KEYBOARD
Keypad 0x01 0x07 HID_DEVICE_SYSTEM_KEYBOARD
System control 0x01 0x80 HID_DEVICE_SYSTEM_CONTROL
Consumer audio control 0x0C 0x01 HID_DEVICE_SYSTEM_CONSUMER
Greetings