Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I´m having a rough time trying to figure out a proper way of dealing with key mapping and key bindings in unity. The built-in unity input manager is useless to me since it doesnt support key mapping ingame and you cant acces it via script, you can only change your key bindings on the game laucher, but not ingame.

I guess I will need to create my custom InputManager to replace the unity one but im pretty much lost in this matter. So far I´m beein doing some research and now I know how to create a basic but robust input manager in C++ (thanks mainly to this tutorial http://www.gamedev.net/blog/355/entry-2250186-designing-a-robust-input-handling-system-for-games ) But as i said I dont know how to translate this into unity c#.. My first idea was to create a complete new input manager from scratch that use an xml file to store the key binding data, but I dont know if you think this is the wrong way to follow. First of all I dont even know how could I acces RawInput in unity. Checking the script documentation was of no use in this matter, i found something about keyboard events but they only work under OnGUI function and I dont know if i should use it then...

I know there are some commercial plugin out there for that solve this purpose but thats not the point, I´m trying to do it this by myselft

Could someone explain to me how could I make my own InputManager from scratch or give me some indication to put me in the right way to this?

I apologize for my bad english btw

-EDIT FOR CLARIFICATION:

Im trying to achieve just the typical key mapping menu but I must be able to access this menu ingame, i mean, via pause menu. ingame->pause menu-> options-> controls. for example, I have the jump action mapped to the space bar, In my controls menu I select remap this this action. A dialog propt and wait for me to press the new key to map to the jump action. I press ctrl (or whatever key)...and then I update the dictionary, jump action = ctrl (or whatever keycode it is). But the issue is, how do I know which key did I just pressed while the dialog waiting for a new key was active? Should I use something like:

void OnGUI() {
    Event e = Event.current;
    if (e.isKey && remapping)
        remap(action, e.keycode);

or if not just a bunch of if statements, one for each keycode of the keyboard i mean

if Input.getKey('keycode') remap(action, keycode);

what surely will work but just use about 100 if statemens

I hope I explained myself clearly now. Anyway I was doing some research before start writting any code but I will do a script what I thought so far and then post it for a better understanding.

share|improve this question
    
If you're willing to pay $20 somebody else supposedly has already solved this: forum.unity3d.com/threads/…! –  Tetrad Apr 18 '13 at 18:53
add comment

3 Answers

Unity allows you to get individual key down events via the Input.GetKey function, and the appropriate key enum. Additionally, it supports axis information via the Input.GetAxis function.

http://docs.unity3d.com/Documentation/ScriptReference/Input.GetKey.html http://docs.unity3d.com/Documentation/ScriptReference/Input.GetAxis.html http://docs.unity3d.com/Documentation/ScriptReference/KeyCode.html

If you want to build an input map around this, then you could write an input manager that sits "in between" the unity input events, and your own event system. An input map would esentially be a one to one or one to many relationship of input events, to unity key events. Updating which keys are tied to which events could be very reasonable achieved. The simplest way to do this would be to store a dictionary of KeyCodes, and a list of the events they are registered with, and simply update these event lists if necessary. Additionally, serializing this information to an xml file would not be unreasonable at all, especially with the extensive and easy to use system that .net provides.

share|improve this answer
    
I guess thats the main idea, but I´m stuck there. I mean, ok i could create my own event system but i cant acces the unity key events, I can only acces that in OnGUI function... That was what i tried at first but I realized I only could use Event.KeyCode in OnGUI() or i get an error. –  Scar4mouche6 Apr 18 '13 at 14:22
    
Your input manager should be listening to key codes directly from the unity input manager itself, did you debug the error message you got to figure out what the problem was? Event.KeyCode is probably an argument being passed to a callback. Input.GetKey is a static method that is accessible anywhere. –  Evan Apr 18 '13 at 14:45
add comment

Im not sure if this will work, I haven't actually tested it.

public abstract class KeyInputController{


  public  char forward = 'w';
  public  char backward = 's';
  public  char left = 'a';
  public  char right = 'd';

  //Add more   

  public abstract void moveForward();
  public abstract void moveBackward();   

  //Add functions for each input

  public void Update()
  {
       if(Input.inputString!="")
       {
         //only works for first input, 
         //if you want keys within the frame update,
         //you need to iterate over it, char by char.
         char input =Input.inputString[0];

         if(input == forward)
           moveForward();
         else if(input == backward)
           moveBackward();
         //Add checks for other inputs
      }
  }
}

Now you could write your keybindings to a simple text file. And just set those variables when you read them. ( havn't tried reading text/xml/json files in Unity but im sure it's possible )

The idea here is that the keys are stored in simple variables. Which you could easily change. It should be trivial then to read/write them away. So making an interface in game where you can set your keys shouldn't be a problem either.

share|improve this answer
    
thanks for the answer but I cant use inputString since that just give you ascii characters not every key. I was looking for something like vrtual keycode in win32, but i only could find Event.keyCode. At first I thought i could use it in a way similar as you said above, but for some reason Event only works under OnGUI function so i cant use it like that. Thats the main issue Im having I dont know how to access the raw input data from my keyboard so I could map the keys.. –  Scar4mouche6 Apr 18 '13 at 13:50
    
Im pretty sure every key has an ascii code. Well I honestly don't know myself though. Havnt worked much with Unity yet. –  Sidar Apr 18 '13 at 13:52
    
with inputString you can´t access special keys like ctrl, alt, shift , home,etc... It´s only for text input purposses –  Scar4mouche6 Apr 18 '13 at 14:14
add comment

You can use a Dictionary to map KeyCode to specific action, eventually you can change this at runtime:

using UnityEngine;
using System.Collections.Generic;
using System;

public class TestInput : MonoBehaviour {

    private Dictionary<KeyCode,Action> d;

    void Start () 
    {
        d = new Dictionary<KeyCode, Action>();
        d[KeyCode.A] = () => {Debug.Log("ACTION A");};
        d[KeyCode.S] = () => {Debug.Log("ACTION B");};
        d[KeyCode.I] = () => 
            {
                Action swap = d[KeyCode.A];
                d[KeyCode.A] = d[KeyCode.S];
                d[KeyCode.S] = swap;

            };
    }

    // Update is called once per frame
    void Update () {

        if (Input.GetKeyDown(KeyCode.A))
        {
            d[KeyCode.A]();

        }
        else if (Input.GetKeyDown(KeyCode.S))
        {
            d[KeyCode.S]();
        }
        else if (Input.GetKeyDown(KeyCode.I))
        {
            d[KeyCode.I]();
        }
    }
}

Btw it seems that Unity does't expose any method that returns a list of all pressed keys, so the code above isn't very elegant. Hope this help.

share|improve this answer
    
thanks for the answer, what you say was the idea i had in mind but again there is a problem with that, related with what you said about you dont have any list of pressed keys. It seems the only way yoy can acces the pressed keys is via Event.keycode and you can only do that in OnGUI(). If i want to remap a key in game i need to acces this event.keycode otherwise i wouldnt be able to detect what the new key for that action will be (unless i do one if statement for each key :S) –  Scar4mouche6 Apr 18 '13 at 16:09
    
you have to check all possible keys. Consider that you don't have to check always all the keys of the keyboard,but just the active ones. Keep a list of all binded keys in a given configuration and iterate through them. –  Heisenbug Apr 18 '13 at 16:13
    
OnGUI isn't called every frame. Btw I don't think you will have too much keys to check. And in any case, even using Input.GetAxis you need to explicitely check for every possible input at every frame. –  Heisenbug Apr 18 '13 at 16:22
    
no no, that wasnt what i meant, i was editing my comment while you were writting yours. I mean, when I want to remap a key ingame, I must wait for the new key for that specific action to be pressed and then update that key binding, but, how do i know what key did I just pressed? should i just make if statements with the whole keyboard? :S (i dont mean the keys already mapped I mean to detect a random key to be mapped next) –  Scar4mouche6 Apr 18 '13 at 16:34
    
I dont know any other way of detect which key is pressed since the only information available for this purpose is Input.inputString (and as i said below thats just for ascii text and no special keys are included) or maybe I could use event.current and I look for a keyboard event so I can see the keycode...but again, the issue here is any keyboard event call OnGUI()..i dont get what keyboard event has to do with GUI... Should I use the OnGUI() anyway or have i got any alternative? –  Scar4mouche6 Apr 18 '13 at 16:34
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.