As far as I tested on my PC, the order between InputAction.controls
and InputAction.AddBinding()
is same.
However, does anyone know if the order is always guaranteed?
For example, I’d like to know following is guaranteed or not.
var inputAction = new InputAction();
inputAction.AddBinding("<Keyboard>/z");
inputAction.AddBinding("<Keyboard>/x");
inputAction.AddBinding("<Keyboard>/c");
inputAction.AddBinding.Enable();
When we use this instance :
inputAction.controls[0].IsPressed() // Is this always guaranteed "<Keyboard>/z" pressed ?
inputAction.controls[1].IsPressed() // Is this always guaranteed "<Keyboard>/x" pressed ?
inputAction.controls[2].IsPressed() // Is this always guaranteed "<Keyboard>/c" pressed ?
In InputAction
class documentation (following), I couldn’t find it is guaranteed or not. So I’d like to know the reference URL if available.
https://docs.unity3d.com/Packages/com.unity.inputsystem@1.12/api/UnityEngine.InputSystem.InputAction.html
Only as long as you are not removing bindings and inserting other values. To make sure you are accessing the right bindings (in outlook to modify the bindings during runtime) you can compare the paths.
1 Like
Only as long as you are not removing bindings and inserting other values.
Thank you for replying! I’m relieved!
To make sure you are accessing the right bindings (in outlook to modify the bindings during runtime) you can compare the paths.
Following is supplementary information about this:
Before I post this topic, I also checked the path
property, but the path name is a bit different when I did AddBinding().
(e.g., <Keyboard>/a
changes /Keyboard/a
in path
property.)
To compare this, I think we need to write some parse script.
(e.g., compare after removing <
, >
, and /
.)
The parse script would be simple, but I thought it’s a little tedious.
Anyway, I’m going to compare directly with index-based when I don’t need to removing/inserting other binds to the target InputAction
instance.
You can also declare them directly in this layout “/Keyboard/x”, so you don’t need any parsing.
1 Like
Thank you for replying again, but I’m sorry I just remembered it was the gamepad when I tested before.
I just tested again and it works correct with keyboard and mouse.
However, it doesn’t work with gamepad.
For example, following
inputAction.AddBinding("/Gamepad/buttonSouth");
inputAction.AddBinding("/Gamepad/dpad/right");
doesn’t work, so it seems we need to write like as following.
inputAction.AddBinding("<Gamepad>/buttonSouth");
inputAction.AddBinding("<Gamepad>/dpad/right");
But it would be changed the path value to the device name of the currently used gamepad, like as following.
/XInputControllerWindows/buttonSouth
/XInputControllerWindows/dpad/right
I would not like to use device specific name (such as XInputControllerWindows
) when AddBinding()
.
So, at least in the case of gamepad, it seems that parsing would be necessary.
After looking at this thread twice I have to take back what I said and correct my statement:
I overlooked that you are accessing the controls with the index of the binding. In fact various controls can map back to one binding. (Eg you have a binding anyKey → gamepad, keyboard and mouse buttons can map to this binding and multiple controls will depict this)
For example:
<Keyboard>/*
controls that map to this:
<Keyboard>/a
<Keyboard>/b
....
… you see where this is going.
So instead what you want is to find the matching control /controls for the binding. You can search for controls matching a path explicitly, then you can simply see if any of these found controls was actuated.
You can use this code for example:
fireAction.AddBinding("<Keyboard>/d");
// you can also use InputSystem.FindControls() here, in case there are multiple controls mapping to one binding possible
var c = InputSystem.FindControl("<Keyboard>/d");
fireAction.controls.First(control => control == c)?.IsPressed();
Sorry for the initial confusing answer, I overlooked something essential there. I hope this helps really now.
1 Like
Thank you for replying politely again and again, I really appreciated your kindness!
I also noticed that the result of <Gamepad>/buttonSouth
would be like as <Keyboard>/*
on your reply when I connected 2 or more gamepads to my PC … like as:
/XInputControllerWindows/buttonSouth
/SwitchProControllerHID/buttonSouth
So I’d also like to need to find the matching controls.
On my use case, InputSystem.FindControl()
on your reply is the “opposite” of what I’d like to do.
However, thanks to your information, I have a better understanding about the “path” of the Input Systems, so, finally I could find InputControlPath.Matches()
method in the document.
I have rewrited my code using InputControlPath.Matches()
with iteration of controls
, and now it works exactly I expected. It’s useful and no parsing required.
Thank you so much!
1 Like
InputControlPath.Matches() is a good choice, I am happy you found a way to build the optimal solution for your case. 
1 Like