I want to add customizable controls into my game, so that the player can set up whatever control scheme they want.
The ideal way I see this is that the player selects an action in the menu and then are prompted to “press a key to assign.” Then whatever key they press gets assigned to that action.
But is there any simple and reasonable way to scan through any and every key?
I suppose I could create a script that checks every single input and returns the first one that gets pressed. But that’s a LOT of keys to check; there are hundreds of keycodes that Unity can respond to, plus gamepad buttons.
Is there perhaps an existing function in Unity to just return the next “any” key a player presses?
And if not, is there some other reasonable method that won’t require a script cycling through hundreds of keys?
You can query something like Input.inputString for ASCII codes but you can’t get things like CTRL/SHIFT, etc.
I would just iterate ALL the possible KeyCode and whichever one you see an Input.GetKeyDown() on, that’s what the user hit, store that KeyCode.
You can iterate them all cheesely like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IterateEnumValues : MonoBehaviour
{
void Start ()
{
List<KeyCode> AllKeys = new List<KeyCode>();
foreach( var kc in System.Enum.GetValues(typeof(KeyCode)))
{
AllKeys.Add( (KeyCode)kc);
}
Debug.Log( "Found " + AllKeys.Count.ToString() + " keycodes in the KeyCode enum.");
}
}
But you might not want all of them available, so you might want to print out those enums to a file and then curate it yourself to decide what to allow. You can always print them with kc.ToString() above. In my version of Unity I see 321 keycodes.
I don’t think that input string would be very helpful, simply because it only returns a string. In order to use that within my system I’d have to turn that into a keycode, which would need something like a switch statement that iterates through every single key anyway.
The example code you wrote would just be a list that duplicates the keycodes. But I suppose I could do something like…
foreach( var kc in System.Enum.GetValues(typeof(KeyCode)))
{
if (Input.GetKeyDown(kc) == true){
// stuff
}
}
…but at the same time, that would create some bunk results. I know there are keycodes for gamepad buttons from “any controller” and also from specific controller numbers, so if the player were using a controller it would get a positive result for two different keycodes.
But I could start with this and try to work out some of the problems.
EDIT: I don’t suppose there is some sort of existing method for checking if a keycode pertains to a controller or other specific device? so I could respond to (or ignore) controller inputs without having to iterate through every “joystick” keycode individually? I don’t see anything within Input nor Keycode, so I doubt it, but I might as well ask.
I would seriously think about if I can put the new Input System into my game if I need this. They actually have a sample how to do it. You get it “almost for free” (you don’t have to do a ton of things yourself to achieve it).
I didn’t know there was a new input system coming out. I just watched their introduction video they made last year; I like this system and I’m looking forward to it. The way they handle actions is already how I set up my control system within my game; it will be nice to have that build in to the engine itself now.
But… I think I’m going to wait for them to finish development before I start using it. Maybe I’ll change my mind, but I think I’m not going to switch until after I release the demo I’m working on.
I used the “Rewired” plugin from the asset store in a previous project, and it includes a way to remap keys at runtime (among other features). There’s a pre-made screen specifically for this purpose you can just use if you want (with some limited reskinning options), or there’s also supposedly reasonable functions you can use for building your own (I haven’t tried).
Probably some other assets with similar features you could look for if you are so inclined.
That said, if the ONLY thing stopping you from building your own is that you don’t like the idea of querying for hundreds of different keys in a single frame, I wouldn’t worry about that.
Also note that the standard Unity pre-launch window (which you can choose to turn on or off) includes a tab for rebinding keys if you use Unity’s old input system. Those can’t be changed while the game is running, though.
Well, define “finish”. A software or a library is never “finished”. They are out (1.0 prod).
But, it is only true if you care about the standards: mouse/keyboard, standard XBox (360, One, etc) and PSx or other “generic” controllers.
They haven’t built an extensive library around non-standard controllers, so to support those, you will need to define them yourself (also you can find the examples in the samples).
I’m not as much concerned about the impact of running those checks in runtime as I’m concerned about writing literally hundreds of lines of code because I need one line for every key.