Difference between InputBindings and InputControls ?

Hello,

I’m currently trying to get all the bindings at the beginning of my game, in order to display them to the player.

In order to do that, I need some informations from each InputBinding (action and path), but I also need the displayName, which is located in the InputControl.

But, when I try to loop on each InputControl on the variable controls of an InputAction, I only get the first binding for each InputAction.

For example, when I run this piece of code

ReadOnlyArray<InputAction> playerActions = inputActions.Player.Get().actions;

foreach (InputAction act in playerActions)
{
    Debug.Log(act.name + " controls: " + act.controls.ToArray().Length);
    Debug.Log(act.name + " bindings: " + act.bindings.ToArray().Length);
}

With these bindings in my Player action map

I print this:

I don’t understand why there isn’t the same amount of controls and bindings in each InputAction.
If it’s normal, can you explain me the difference between an InputBinding and an InputControl and how can I get the displayName of each binding ?

Thanks,
Kevin B.

4780661--456017--upload_2019-7-24_16-18-24.png

I managed to print this from the code below… not sure if that helps

4781978--456263--upload_2019-7-24_16-20-45.png

        var aa = playerInput.actions.actionMaps[0].bindings.ToArray();

        foreach (var item in aa)
        {
            print(item.path);
        }

Thanks for your reply, but that’s not exactly what I want. In fact, there’s a difference between a binding and the display name. For example, I’ve got the key “W” binded on the action “Jump”, but the display name is “Z” because I’ve got an AZERTY keyboard (and I want to display that name to the player).

Hello,
Is there anyone who could help me on this problem ?

Thank you

An InputBinding is a specification that can be used to look up InputControls at runtime and connect them to actions.

The binding’s path is an abstract kind of specification. Sort of like a regular expression or a file system path like “C:*.txt”. At runtime, a path may match arbitrary many (including none at all) controls. For example, say you have a touchscreen, a tablet, and a mouse connected to your machine. Then “/press” will match three controls at runtime. One “press” control from each of the pointer devices.

As for getting from paths to display names, this is missing a wrapper API ATM and thus still requires jumping through several hoops. I have a PR in flight which may land in time for 1.0 that is intended to address this. If it does, you can convert paths for display like so

var displayName = InputControlPath.ToHumanReadableString(
    myAction.bindings[0].effectivePath,
    InputControlPath.HumanReadableStringOptions.OmitDevice);

ToHumanReadableString() has been available for a while. However, the version that’s currently in the package does not take display names into account and will thus return somewhat “unnatural” looking results.

1 Like

Similarly, is there a way to get the ‘Composite Part’ of an InputAction from the callback context? For example, in the image below there are multiple Movement bindings configured. Regardless of which binding is being used by the player I’d like to read the ‘Composite Part’, ex. ‘Up’ when the player wants to move up. So far I’ve only been able to read the ‘Composite Type’ from input actions (in this example ‘2D Vector’), which I don’t want.

From the input actions JSON blob it looks like the name value should be accessible for input bindings, I just haven’t found how to access those values from InputAction.CallbackContext.

$ grep '"name": "up"' Assets/InputActions/PlayerInput.inputactions -A2
"name": "up",
"id": "9fc8c042-184c-4029-afc9-33c4f81d9877",
"path": "<Keyboard>/w",
--
"name": "up",
"id": "0d9addd7-fa3d-4850-a38e-9841169ef6c8",
"path": "<Keyboard>/upArrow",
--
"name": "up",
"id": "097f6f5f-6ee0-40d4-ba77-ee0f4adac400",
"path": "<Gamepad>/dpad/up",
--
"name": "up",
"id": "7b8c9225-35da-47f8-831e-1b650d4f5ccf",
"path": "<Gamepad>/leftStick/up",

ATM no, there isn’t an exposed API for that. What you’re looking for is probably the equivalent of InputBindingCompositeContext.ReadValue() which reads a value from a specific part of the composite (which in turn may read a value from several controls). That particular API is only available to composites themselves ATM, though.

Could you describe your use case a little more?

Yeah sure, thanks for taking the time to reply. My use case is that I have multiple bindings (ex. WASD, ArrowKeys, Dpad, etc.) for a single action (ex. Movement). When the player presses any of the movement buttons the value is being read like so:

direction = context.ReadValue<Vector2>();

Which is pretty straightforward.

But I also want to know which relative direction (up, down, left, right) the button press maps to. It looks like the composite type provides a convenient way to easily get the relative direction of the button press. I’m migrating from the old input system where I’d previously do something like this:

Input.GetButtonDown("Vertical") && Input.GetAxis("Vertical") > 0

to achieve the same thing. I could probably do something similar, but it looked like composite type provided the data I want without having to code a solution for each direction, and more importantly not worry about which binding the player was using (since the composite type was the same for all directional bindings (ex. ‘Up’)).

@kayroice Thank you for the details. Helps a lot.

My thought is, wouldn’t in this case the information you’re looking for be readily available from the vector you are reading?

direction = context.ReadValue<Vector2>();

var upIsPressed = direction.y > 0;
var downIsPressed = direction.y < 0;
var leftIsPressed = direction.x < 0;
var rightIsPressed = direction.x > 0;

Yes, I’m currently doing the equivalent with the old input system (ie. the example above using Input.GetAxis() > 0), and can do the same thing using the new input system. It’d be really nice though to have a convenience method that provided access to the shared composite type across bindings. That would eliminate having to write code that evaluated the direction. Also, as a user when seeing the composite type in the Input Action UI I assumed that there’d be a method to access it; I probably won’t be the last to make that assumption. Not a big deal though, but it’d be nice to have. Thanks for looking into this.

Made note of it and will take a look after 1.0.

Thanks, much appreciated!