Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Input Conditional - Possible to identify *WHICH* expression evaluated to True?

Discussion in 'Scripting' started by blake_leblanc, Jul 28, 2021.

  1. blake_leblanc

    blake_leblanc

    Joined:
    May 20, 2021
    Posts:
    4
    When working with Input methods, and resolving conditionals, is it possible to know WHICH of the conditional expressions caused a True evaluation?

    For example, I'd like to check and see if certain particular keys are released, and if so, then use that released key in a subsequent method call.

    Right now, I'm breaking out each of them separately, like

    Code (CSharp):
    1. If (Input.GetKeyUp(KeyCode.A)) {
    2.     methodCall(KeyCode.A);
    3. }
    Code (CSharp):
    1. If (Input.GetKeyUp(KeyCode.B)) {
    2.     methodCall(KeyCode.B);
    3. }
    ... etc

    Is it possible to do combine them into something like

    Code (CSharp):
    1. If (Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.B) || Input.GetKeyUp(KeyCode.C) ...) {
    2.     methodCall(<Whatever above keycode evaluated to True>);
    3. }
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Write a custom method that outputs the result (I'm going to write it in an overload fashion to avoid using a param array which causes gc allocations):
    Code (csharp):
    1. public static class InputExt
    2. {
    3.     public static bool GetKeyUp(out KeyCode result, KeyCode a, KeyCode b)
    4.     {
    5.         if(Input.GetKeyUp(a))
    6.         {
    7.             result = a;
    8.             return true;
    9.         }
    10.         else if(Input.GetKeyUp(b))
    11.         {
    12.             result = b;
    13.             return true;
    14.         }
    15.         else
    16.         {
    17.             result = default(KeyCode);
    18.             return false;
    19.         }
    20.     }
    21.  
    22.     public static bool GetKeyUp(out KeyCode result, KeyCode a, KeyCode b, KeyCode c)
    23.     {
    24.         if(Input.GetKeyUp(a))
    25.         {
    26.             result = a;
    27.             return true;
    28.         }
    29.         else if(Input.GetKeyUp(b))
    30.         {
    31.             result = b;
    32.             return true;
    33.         }
    34.         else if(Input.GetKeyUp(c))
    35.         {
    36.             result = c;
    37.             return true;
    38.         }
    39.         else
    40.         {
    41.             result = default(KeyCode);
    42.             return false;
    43.         }
    44.     }
    45. }
    Used:
    Code (csharp):
    1. KeyCode key;
    2. if(InputExt.GetKeyUp(out key, KeyCode.A, KeyCode.B, KeyCode.C))
    3. {
    4.     methodCall(key);
    5. }
    ...

    Also I'd suggest instead of doing this setup where you test actual keycode you instead make a wrapper around it. Instead used the named inputs, or even try out the newer advanced input library that Unity released.

    This way you can allow the user to configure what's what. If they hate space as the fire button, they can make it whatever. And then you just test for "fire" instead.

    ...

    Finally what is methodCall doing with the keycode anyways? Why can't it just use Input.GetKeyUp?
     
    Last edited: Jul 28, 2021
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,814
    And building on top of all the good stuff Lord provides above, if this is anything more than just a little throwaway test, you should set yourself up for winning by divorcing input intent from actual result as much as possible.

    Do it in separate steps:

    1. gather all user intent to local variables

    2. process user intent to semantic meanings

    3. act on semantic meaning

    eg,

    if firekeypress:
    --> firekey was pressed!

    if (firekey was pressed AND you_can_fire):
    ---> successful fire intent processed

    if (successful fire intent)
    ---> actually fire the gun
     
  4. blake_leblanc

    blake_leblanc

    Joined:
    May 20, 2021
    Posts:
    4
    Interesting, thank you @lordofduct ! I'll give that a try!

    I'm not sure if it has a technical term, but I'm essentially needing to resolve "chorded" key presses that trigger rotation coroutines.

    So for example (using random keys to keep it simple), if the user holds down B, then adds A, then adds C, the last held key (C) is what takes precedence and its associated Lerp rotation will resolve.

    If he then removes B, so he's only holding down A and C, the C is what will be considered "active" so it will "stay" where it is.

    But if he instead removes C, so he is holding B and A, the A will be considered "active" and its associated Lerp rotation will resolve.

    In practice, this is more of a way to "safeguard" against messy trailing key presses/releases so that only one coroutine is in play at any given moment.
     
    Last edited: Jul 28, 2021
  5. blake_leblanc

    blake_leblanc

    Joined:
    May 20, 2021
    Posts:
    4
    Thank you @Kurt-Dekker !
     
    Kurt-Dekker likes this.