(New Input System) Check if Binding Already Exists in Input Action Asset

I have this code here used to change key bindings on button press.

public void StartButtonRemapping(InputActionReference actionToRebind)
    {
        //Debug.Log("Successful Rebinding! "+ System.Environment.NewLine +"The reference before any changing: " + actionToRebind + " -- and it's action: " + actionToRebind.action);
        if (actionToRebind == null)
            return;
        actionToRebind.action.Disable();
        KeyBindButton.text = "...";

        rebindOperation = actionToRebind.action.PerformInteractiveRebinding().OnMatchWaitForAnother(0.1f).WithControlsExcluding("Mouse").WithCancelingThrough("<Keyboard>/escape").
        OnCancel(operation =>
        {
           
            KeyBindButton.text = "[" + actionToRebind.action.GetBindingDisplayString().ToUpper() + "]";
            actionToRebind.action.Enable();
            Debug.Log("The reference after a failed change: " + actionToRebind + " -- and it's action: " + actionToRebind.action);
            rebindOperation.Dispose();
            operation.Dispose();
        }).
        OnComplete(operation =>
        {
            KeyBindButton.text = "[" + actionToRebind.action.GetBindingDisplayString().ToUpper() + "]";
            actionToRebind.action.Enable();
            Debug.Log("The reference after a successful change: " + actionToRebind + " -- and it's action: " + actionToRebind.action);
            rebindOperation.Dispose();
            operation.Dispose();
        }).
        Start();
        //Debug.Log("The reference after everything: " + actionToRebind + " -- and it's action: " + actionToRebind.action);
    }

The part that I need help with is determining whether the input chosen to rebind to already exists for another key. If so, I would want to set the previously already bind to null so that the player can see that the key they changed the binding to already existed for another binding and would have to change it to a new key.

Did you ever find a solution for this? I’ve been trawling through the API with no luck

In case anyone stumbles on this, I found a solution, I was overcomplicating it: Simply store a reference to the previous binding and compare against the the list of bindings on the action map. In my case, I’m only allowing one binding per action, you’ll need a little more work to be done if you need multiple. This should be enough for you to work it out:

PS: I’m not happy with having to change the binding back to the previous one (noted with a comment in the code), but couldn’t find a better option. If anyone knows an alternative, let me know

private void finishRebinding(InputActionRebindingExtensions.RebindingOperation operation, InputAction actionToRebind, InputBinding prevBinding)
{
    operation.Cancel();
    actionToRebind.Enable();
    operation.Dispose();

    if (isBindingInUse(actionToRebind))
    {
        //Next line is the ugly one
        actionToRebind.ChangeBinding(0).To(prevBinding);
        rebindCancelled?.Invoke();
    }
    else
    {
        rebindComplete?.Invoke();
    }         
}

private bool isBindingInUse(InputAction actionToRebind)
{
    var newBinding = actionToRebind.bindings[0];

    var bindings = actionToRebind.actionMap.bindings;
    foreach (var binding in bindings)
    {
        if (binding.action == newBinding.action)
            continue;
        if (binding.effectivePath == newBinding.effectivePath)
            return true;
    }

    return false;
}
4 Likes