I would like to create a method that concatenates the “input events” with the “key pressed”… I explain:
//storized input events
var onDown = Input.GetKeyDown;
var onPress = Input.GetKey;
var onUp = Input.GetKeyUp;
//storized input type
var keyFORWARD = KeyCode.W;
var keyLEFT = KeyCode.A;
var keyBACKWARD = KeyCode.S;
var keyRIGHT = KeyCode.D;
var keyCROUCH = KeyCode.C;
var keySPACE = KeyCode.Space;
var keySHIFT = KeyCode.LeftShift;
var keyStatus = GetKeyStatus("onDown", "keyFORWARD");
Debug.Log("KeyStatus: " + keyStatus);
The method should recreate the complete command line
Input.GetKeyDown(KeyCode.W)
//get the used key
public GetKeyStatus(string KeyAction, string KeyVal)
{
string keyStatus = KeyAction+"("+KeyVal+")" ;
return keyStatus;
}
Well, I’ve never come across this problem but I’ll give it a shot.
First off, Input.GetKey and its variants return a bool if that key was pressed. This means that you can get any other information from this function besides true or false. You can use the method, which will return a string for the current input from the keyboard:
Input.inputString
You could then try using Input.GetButton since that uses a string for its argument.
I don’t know if this helps, or answers your question, but I honestly don’t know the extent to which what you’re trying is possible.
You can’t get what you want with strings. Once your code is compiled, your program doesn’t really have a concept of “The function named onDown” - everything is through memory addresses and such.* So you can’t tell your program to take a string and find the method with that name, because it doesn’t know.
I would like to point out that there seems to be very little point of doing what you’re wanting to do - you’re actually increasing the amount of code you need to write to check any given input.
You can use the first 14 lines of code, and then simply do this, though:
if (onDown(keyFORWARD) ) {
Debug.Log("onDown(keyFORWARD)) was true");
}
And this would indeed save you a little bit of code.
There is an exception known as Reflection, which more or less reverse-looks-up pieces of code by name. But it’s slow, it’s unreliable, and it doesn’t work on many platforms, so don’t use it unless you really know what you’re doing. It also violates a lot of principles of good data design, so don’t use it. In my career I’ve only found it useful for debug and editor code.
but he’s not checking input… hes just wants to composite a string. I do agree that there seems little point to what he is doing but he never did say what exactly he’s using it for.
and if it is to check for input (even though this is not the way to do it), there is merit to encapsulating the calls.
“Slow” is relative and really mostly applies to Invoke. even then you can Create a Delegate out of a MethodInfo and the result is a call thats <5% slower than direct calls, which in my book is plenty fast enough. Unity uses Reflection all over the place (especially with UnityEvents) and applies this technique so as not to lose performance. You can check out Jon Skeet’s blog about this if you want to know more and see the comparisons.
Unreliable? I wouldn’t ever say that. It does exactly what its designed to do, every time. Complicated, and usually overkill? Sure, those are terms I’d usually use to describe it, but never unreliable. Also Reflection is supported on most platforms, any platform that supports Mono or a C# to C++ transpiler. This includes all Standalones (to as early as 2003), recent iOS and Android, web and all recent consoles. the only platforms I would say give trouble is the Windows Store, Windows Phone 8, and the much older platforms.
The issue is we’re not sure what you want cause you haven’t told us.
we’re all going off assumptions. I can make educated guess and if my assumption is correct then yes it is totally possible (and without the need for reflection). so tell us what you’re trying to do.
When I use a word like “unreliable” for coding, I don’t necessarily mean that it will fail randomly. What I mean is that it will be more likely to fail than the alternative, including in how well the technique compensates for human error.
If you make a typo in compiled code, you’ll know it immediately because it’ll create a compile-time error. No matter how complicated your project, or how deep into your game the code is where you made the mistake, you can double-click and go right to the error, and just fix it.
If you make a typo on reflection-dependent code, you won’t know until you try to execute that particular bit of code. If your testing methodology isn’t bulletproof, it’s very possible that a rarely-run piece of code might get all the way to deployment without being noticed.
since always it just doesn’t support Emit which is rarely needed, if ever. the rest of the Reflection API is fully supported
What you’re talking about is the difference between Syntactic(compile) and Semantic(runtime) errors. which isn’t specific to Reflection. you’re right in that if your testing isn’t good enough then it can break at runtime. but how does that make Reflection the unique case. that can happen to any class.
//can cause null reference exception! doesn't get caught by the compiler!
transform.GetComponent<Collider>().bounds
Theres more than one way to do this, and they all have their own specific benefits. This has the benefit for being tweakable via the inspector and via code at runtime.
You could also do it via function delegates.
private Dictionary<string,System.Func<KeyCode,bool>keyMethods;
private void Start()
{
keyMethods = new Dictionary<string,System.Func<KeyCode,bool>
{
{"OnDown", Input.GetKeyDown},
{"OnUp", Input.GetKeyUp},
{"WhilePressed", Input.GetKey}
}
}
private void Update()
{
if(keyMethods["OnDown"](KeyCode.Space))
// space was pressed this frame.
}