Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Changing Keys at Runtime

Discussion in 'Input System' started by Synpse, Oct 17, 2019.

  1. Synpse

    Synpse

    Joined:
    Mar 19, 2018
    Posts:
    20
    Hello everyone.
    I am upgrading from my custom input manager to Unity's new input manager and I'd like to know if it is possible to change keybindings at runtime with it?

    If yes, any ideas how?
     
  2. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    1,779
  3. Synpse

    Synpse

    Joined:
    Mar 19, 2018
    Posts:
    20
    First of all thank you for the reply.

    Just to make sure if I got that right, the "ApplyBindingOverride()" changes keybindings on start and "PerformInteractiveRebinding()" changes keybindings on runtime?

    I've checked the documentation but I'm finding it to be very confusing.
     
  4. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,764
    As the documentation says, the PerformInteractiveRebinding will wait for an input from the user and binds it. Just like you see in other games.
    When you call the ApplyBindingOverride method, you need to provide the new binding path in parameter.
     
  5. Synpse

    Synpse

    Joined:
    Mar 19, 2018
    Posts:
    20
    Oh okay, so one returns a path and the other one takes that path as its parameter and applies it?
     
  6. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,764
    Nope.
    Code (CSharp):
    1. myAction.ApplyBindingOverride(newBindingPath);
    You as the developer give a new binding. For example previously you saved some user choosing to disk. You read it back from the disk and set the binding.

    Code (CSharp):
    1. var rebindOperation = actionToRebind.PerformInteractiveRebinding()
    2.                    // To avoid accidental input from mouse motion
    3.                    .WithControlsExcluding("Mouse")
    4.                    .OnMatchWaitForAnother(0.1f)
    5.                    .Start();
    This (or similar) will be waiting for the user during the game to give an input to rebind the action. Which you later can store on disk or in game save or whatever.

    So one will rebind without user action, the other will rebind whatever the player chooses.
     
    andreiagmu and Synpse like this.
  7. Synpse

    Synpse

    Joined:
    Mar 19, 2018
    Posts:
    20
    I get it now. Thank you!
     
  8. lucvw_1975

    lucvw_1975

    Joined:
    Dec 7, 2014
    Posts:
    19
    I hope someone reads this message, but I have a problem with changing the bindings and I don't know what's the reason... This is my code:

    Code (CSharp):
    1. InputBinding newPath = new InputBinding("<Keyboard>/enter");
    2. _input.GamePlay.Fire.ApplyBindingOverride(newPath);
    But this doesn't work. The path stays the same, whatever I try... :/ Is there someone who can shed some light on this issue ? Thanks ! :)
     
    LeoLopesPlayKids likes this.
  9. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    815
    I second that this is super confusing, because there is both a ChangeBinding and a ApplyBindingOverride.

    upload_2021-2-11_21-13-10.png
    Neither do anything, im calling this on a generated class's action, and the old binding still responds, the new one is ignored.


    I have to say the input system API is very counter intuitive... @Rene-Damm what are we doing wrong?
     
    emredesu likes this.
  10. ClpsPLUG

    ClpsPLUG

    Joined:
    Apr 16, 2017
    Posts:
    12
    I've got it to work on Unity 2020.2.1f1 by the following code. The trick may be to specify the original path/group, like this:

    Code (CSharp):
    1.  
    2. inputAction.ApplyBindingOverride(new InputBinding
    3. {
    4.     // Explicitly target the original one by its path - this code assumes that Control Scheme is present
    5.     // and is named "Keyboard," whose only binding is a keyboard key.
    6.     // I believe you could also specify `groups` instead (Control Scheme required.)
    7.     path = inputAction.bindings.First(b => b.groups == "Keyboard").path,
    8.     overridePath = overridePath,  // e.g. <keyboard>/enter
    9. });
    10.  
    Apparently, it is expected at this point that
    inputAction.path
    stays the same.
    Rather, check
    inputAction.overridePath
    and
    inputAction.effectivePath
    . If those points to what you have specified, then it should work.

    I wonder if one can just do
    $"<Keyboard>/{InputSystem.Key.EnumValue}"
    to specify the
    overridePath
    , though. I hope that's the case.
     
  11. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    815
    I reported this as an issue, and got the following response:

     
    andreiagmu and ATpartytime like this.