Distinguishing Between A Keypress & Keypress With Modifier

Hello, I’m trying to distinguish between a simple keypress (backquote ` (left of “1”)), and that key with a modifier key (e.g. Alt).
Using a simple operator in an if statement works well for a keypress with a modifier:

if (Input.GetKeyDown(KeyCode.Backquote) && Input.GetKey(KeyCode.LeftAlt) || Input.GetKeyDown(KeyCode.Backquote) && Input.GetKey(KeyCode.RightAlt))

But trying to register a keypress explicitly without a modifier doesn’t seem to work so well:

if (Input.GetKeyDown(KeyCode.BackQuote) && !Input.GetKey(KeyCode.LeftAlt) || Input.GetKeyDown(KeyCode.BackQuote) && !Input.GetKey(KeyCode.RightAlt))

The issue specifically here is that when using the key with a modifier, it also runs the code I want to run ONLY when a modifier isn’t held down, so I want to trigger one event with Alt+, and another with , but using the Alt+also triggers the code despite the check.
I’m sure there is a proper way to do this, to prevent the latter code being executed when Alt is held down, but I can’t find it online, anyone here know what I’m doing wrong?

If you have more than one or two dots (.) in a single statement, you’re just being mean to yourself.

How to break down hairy lines of code:

http://plbm.com/?p=248

Break it up, practice social distancing in your code, one thing per line please.

“Programming is hard enough without making it harder for ourselves.” - angrypenguin on Unity3D forums

“Combining a bunch of stuff into one line always feels satisfying, but it’s always a PITA to debug.” - Star Manta on the Unity3D forums

I’m pretty sure if statements have some kind of order of operations, which I still don’t even really remember. If you want to check each condition in a specific way, you want to use parenthesis to make sure it’s segmented properly.

It’s true that operators have a certain order, just like * / has precedence over + -, boolean operators also have an order. As you can see in the list, the highest operators have precedence over those below in the listing. operators in the same group are handled based on the associativity (either left-to-right or right-to-left). As you can see the logical “not” ! operator has the highest priority. Followed by && and finally ||.

However you made a mistake in your boolean logic as you were negating your expression.

The correct negation would be:

if (Input.GetKeyDown(KeyCode.BackQuote) && !Input.GetKey(KeyCode.LeftAlt) && !Input.GetKey(KeyCode.RightAlt))

or

if (Input.GetKeyDown(KeyCode.BackQuote) && !(Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt)))

likewise your positive case would simplify to

if (Input.GetKeyDown(KeyCode.BackQuote) && (Input.GetKey(KeyCode.LeftAlt) || !Input.GetKey(KeyCode.RightAlt)))

You should train some basic boolean logic.

a && b || a && c == a && (b || c)

// to negate b and c it would become

a && !b && a && !c == a && !(b || c) == a && !b && !c

The first example in the negative case shows, that the two “a” are redundant anyways. As Kurt said, it’s probably much simpler to combine the “alt” state in a seperate variable

bool isAlt = Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt);

if (Input.GetKeyDown(KeyCode.BackQuote) && !isAlt) // negative case

if (Input.GetKeyDown(KeyCode.BackQuote) && isAlt) // positive case
2 Likes

ps: Your if statement checks only when both alt keys are held down, in that case pressing “BackQuote” would not work. If only one or no alt key is pressed, pressing BackQuote would yield a true value. If you can’t follow the logic, you may set explicit brackets to show the order of operations and break down individual parts for a particular case. So for example only the left alt key is held down and you press BackQuote. What does each part evaluate to and what is the final value you get. Since you don’t hold down the right alt key, the second half of your if statement would yield a true value, since “not holding right alt” and “pressing BackQuote” are both true

Update: on @Kurt-Dekker advice, I split my code up, nested things a bit more, changed little else and the following seems to be working fine now, still not 100% sure why it wasn’t before.

if (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt))
        {
            if (Input.GetKeyDown(KeyCode.BackQuote))
            {
                //BQ & Alt
            }
        }
        else
        {
            if (Input.GetKeyDown(KeyCode.BackQuote))
            {
               //Just Backquote
            }
        }
1 Like