- Home /
want to convert too many if statements into 1 switch case statement. error help.
so if statements are like followif (Input.GetKey("w")) { player moves forward }
similar if statements for player move backward, move sideways, rotate, etc
I want to convert it into switch case statement(if possible). not that if statement doesnt work, but because it looks messy, script turned huge, also, I'm new at programming and I want to learn new things.
this is how I attempted to do itswitch (Input.GetKey("")) { case w: player moves forward; break; }
but it says the name w doesnt exist in current context. and when I add "" to w in case "w": it says cant convert string to bool.
so can I not use switch case statement like I just did? or can I? what am I doing wrong here? please help. thanks in advanced.
Answer by JVene · Aug 08, 2018 at 06:54 PM
Kudos on realizing that Update should be kept clean. The natural tendencies of student programmers will create a mess out of Update. That appears to be among the primary interests in your question.
First, trust the compiler to make calls to methods fast. Instead of creating a huge mess in Update, one (of many) simple techniques is to organize the work put in Update in various methods which break the work into more reasonable sections. Update (and FixedUpdate) represent a slice of time, at a moment where it is appropriate to perform various tasks. This is so generic that just about everything you're likely to code goes in one of these two, at least at first.
One approach to help is to create a function which determines what input is given, returning a value (perhaps from an enumeration or just an integer) which can apply to a switch. The form of a switch is like this:
switch( n )
{
case 0: .....; break;
case 1: .....; break;
case 2: .....; break;
}
If n is negative, or > 2, this example switch does nothing. The ellipses indicate where some code would go, and each case ends in a break (which means that's the end of this case). The numbers 0, 1 and 2 can be replaced by other constant values (you'll need to study C#, I'm sure you know).
If you read the documentation on GetKey, the method returns a bool. You have nothing upon which to base a switch. If you have only a few keys to test, you could create a method which performs the "if/elseif" kind of table of tests, returning a value which switch can use. This makes things a bit cleaner and more organized.
There is one other approach you can try. This depends a lot on the nature of your needs from keyboard input, so I can't say, from what little info is in your question, if this will work for you, but it may at least be a useful technique to understand.
Unity's Input class has a property field called "inputString". In each call to Update, this is, in theory, filled with the keys pressed since the last update call. It is the closest thing Unity provides which is basically "GetLastKeysPressed()", which identifies the keys on the keyboard, not just a bool testing for each possible key. It can work a little like this (imagination can provide a number of ways to use this):
public int getKey()
{
if ( Input.anyKey )
{
if ( Input.inputString.Length > 0 ) return Input.inputString[ 0 ];
}
return 0;
}
Let me be clear here, this is not code you can just paste and use, this is an example of what you can start with and expand to your purposes. Read the documentation on Unity's Input class, specifically about inputString. There's a slight "gotcha" you have to deal with. The string can contain "\n" or "\b", representing "Enter" and "Backspace". Otherwise, this only gets you ASCII characters, not language independent characters or special characters other than backspace or Enter.
There one more slight "gotcha" - if the user presses multiple keys between calls to Update, inputString can contain several keys. You have to decide what you want to do if that's the case, but if you don't handle it, it may seem like keys are being "lost", when they are merely being hit very fast. There are ways to deal with this, typically by looping through the inputString and using all the keys you find there. The method I hint to above won't do that - it merely returns a single key. You have to think, study and fashion your own solution to these issues if inputString is otherwise useful to you.
As a quick example of how to deal with multiple keys, consider
if ( Input.anyKey )
{
foreach( char c in Input.inputString )
{
if ( c >= 'A' && c <='Z' ) ProcessKey( c );
}
}
This snippet of code loops through all keys in inputString, calling ProcessKey only on capital letters found (skipping numbers, special characters, lower case letters, etc.)
The proposed method ProcessKey could then be a switch, with cases like this:
public void ProcessKey( int c )
{
switch( c )
{
case 'A': ....; break;
case 'W': ....; break;
}
}
This would be a switch based on the capital letters A and W. Again, ellipses indicate code you write, possibly just a call to a method that does what should be done when A (or W) is pressed.
The use of "anyKey" may be incorrect for you situation. It is a test for when a key is down, and it includes the mouse buttons (but of course, they don't append to inputString). However, it is possible for inputString to have content even if anyKey is false, because Update might be firing late or slowly, and by the time this function fires, there could be data in inputString, but no key is actually down. You have to think, experiment and tune for your particular situation and requirement. Perhaps you just need to check for the length of inputString, and consume the appropriate characters it contains. I'm not experimenting with the code snippets I've posted, they're just suggestions for you to explore.
wow thank you. I learned a lot more from your answer than a youtube tutorial. yes I will try all these methods, even if it doesnt work, I will learn something new. thanks.
Answer by Bunny83 · Aug 08, 2018 at 06:14 PM
That's not possible. A switch statement requires a value as input and each case is decided by the one single value given. The GeyKey method requires a parameter that specifies which key state it should return. The actual return value is just a boolean which can only be true or false. There is no way around seperate if statements.