Reputation: 23
When programming with C/C++ I sometimes used to have a dictionary with references to functions according to the specified keys. However, I don't really know how to have something similar in C# allowing me dynamic keys.
I'm working on Unity and I'd like for exemple to invoke a function when I press left mouse click on my Unity project, is it possible ?
I'd really appreciate every comments on this.
Upvotes: 2
Views: 7102
Reputation: 125435
You can use Dictionary<KeyCode, System.Action>
signature to accomplish that. Get all the code codes and store them into an array with System.Enum.GetValues(typeof(KeyCode));
. You can then pair your keys with your functions with keyCodeToFuncDic.Add(KeyCode.YourKeyCode, YourFunction);
In the Update
function, use for loop to loop over the KeyCodes
stored in the beginning. Check if any of those keys is pressed. If pressed, check if it is in the Dictionary
. If the that KeyCode
exist in the dictionary, use the pressed key to Invoke
the function in the Dictionary
value, which will eventually call the function that is stored in the Dictionary
.
Code:
Dictionary<KeyCode, System.Action> keyCodeToFuncDic = new Dictionary<KeyCode, System.Action>();
Array allKeyCodes;
void Start()
{
//Get all codecodes
allKeyCodes = System.Enum.GetValues(typeof(KeyCode));
//Register Keycodes to functios
keyCodeToFuncDic.Add(KeyCode.Mouse0, myFunction); //Left mouse
keyCodeToFuncDic.Add(KeyCode.Mouse1, myFunction2); //Right mouse
}
void myFunction()
{
Debug.Log("Left Mouse Clicked");
}
void myFunction2()
{
Debug.Log("Right Mouse Clicked");
}
void Update()
{
foreach (KeyCode tempKey in allKeyCodes)
{
//Check if any key is pressed
if (Input.GetKeyDown(tempKey))
{
//Check if the key pressed exist in the dictionary key
if (keyCodeToFuncDic.ContainsKey(tempKey))
{
//Debug.Log("Pressed" + tempKey);
//Call the function stored in the Dictionary's value
keyCodeToFuncDic[tempKey].Invoke();
}
}
}
}
Upvotes: 1
Reputation: 15847
When I see "dynamic keys" I think for something else like having a dynamic
type be the key for the dictionary. However what you need can be easily achieved. In C# "pointers to functions" are called delegates
(but way better than C pointers to functions) thus you need a dictionary that has the char
type as the key and one of those delegates as the value. In .net framework 4.0 and above there are predefined generic delegates called Func<T...>
and Action<T...>
. Basically if you want your function to return a value you will use Func
and the Action
will be used in the place of a void
method.
So you can have something like this:
var keyMap = new Dictionary<char, Func<string, bool>>()
{
{'w', MoveUp},
{'s', MoveDown},
{'a', s => true}, // using lambda expression
{
'd', delegate(string s)
{
if (string.IsNullOrWhiteSpace(s) == false)
{
//
}
return true;
}
} // using anonymous method
};
// then you can call those like this
var allow = keyMap['w']("some input");
if (allow)
{
// ....
}
public bool MoveUp(string input)
{
return true;
}
public bool MoveDown(string input)
{
return true;
}
Here are the docs https://msdn.microsoft.com/en-us/library/bb549151(v=vs.110).aspx
Upvotes: 1
Reputation: 1774
I think you can use this: First define a Delegate for your task (Jobs assigned to keys press in your example):
public delegate void MyJob();
Then define your dictionary:
Dictionary<string, MyJob> myBinding = new Dictionary<string, MyJob>()
{
{ "left", delegate() { Console.WriteLine("Left Key pressed"); } },
{ "right", delegate() { Console.WriteLine("Right Key pressed"); } },
{ "up", delegate() { Console.WriteLine("Up Key pressed"); } },
{ "down", delegate() { Console.WriteLine("Down Key pressed"); } }
};
And finally use it:
public void Mapper(string pressedKey)
{
myBinding[pressedKey]();
}
I hope this help you to solve your problem. If you need to more detail let me know.
Upvotes: 4