How to let player set hotkeys?

How can I detect input and store it in a struct for example?

The mechanic I’m looking for is when you press for a hotkey remap, and a prompt comes up
“press any key combination”

including ctrl+shift+E for example

then this would be stored to a struct?

then how would I detect that this combination was pressed by the player without having a if ( input.keycode ) nest for every possible combination?

Thanks

You basically have to set up a framework for it yourself. Here’s a simple example using the new input system:

using UnityEngine.InputSystem;

public struct Hotkey
{
    public Key key;

    public bool alt;
    public bool ctrl;
    public bool shift;

    public Hotkey(Key key, bool alt = false, bool ctrl = false, bool shift = false)
    {
        this.key = key;
        this.alt = alt;
        this.ctrl = ctrl;
        this.shift = shift;
    }

    public bool WasPressed()
    {
        var result = true;

        if (!Keyboard.current[key].wasPressedThisFrame) result = false;
        if (alt && !Keyboard.current.altKey.wasPressedThisFrame) result = false;
        if (ctrl && !Keyboard.current.ctrlKey.wasPressedThisFrame) result = false;
        if (shift && !Keyboard.current.shiftKey.wasPressedThisFrame) result = false;

        return result;
    }
}
Hotkey hk = new Hotkey(Key.E, false, true, true);
if (hk.WasPressed())
{
    // do stuff
}
1 Like

and then i iterate through a list of all hotkeys that are assigned on update?

void Update(){
for( int i = 0, i < hotkeyList.count, i++){

if (hotkeyList[i].WasPressed()){

hotkeyList[i].ExecuteBoundMethod();
}

}

}

something like this?

thanks for the help, one last question, how do I listen for a key input?

like if I make a coroutine and I am waiting for the player to input a key

while(hk.key == null){

hk.key = ? //waiting for key press? 

yield return null;

}

You just check the input key every frame and then yield. But honestly, responding to input within a coroutine feels wrong to me. It would probably work but you should consider putting the input in Update and whatever coroutine that you need running can then while over some bool like didPlayerPressJump or whatever.

But generally speaking: coroutines are a terrible system for running game logic. They have their use as a simple kind of event that waits for a while and then does something. I practically never use them for anything but deferred execution. Once you find yourself calling StopCoroutine to StartCoroutine another, you should move away from coroutines altogether because in most cases this means trying to implement a statemachine with coroutines, and that’ll be terrible to manage and debug as you have no concrete “I’m in this state” variable to check for.

1 Like