Search Unity

Input.GetKey if not any

Discussion in 'Scripting' started by gerdich, Oct 16, 2016.

  1. gerdich

    gerdich

    Joined:
    Feb 19, 2016
    Posts:
    10
    I'm not yet a scripter of Unity3d. But I am reading the documentation to become one.

    Is there a function to know if any key has been pressed?
    I only see functions to know if this or that key has been pressed. But it is very time consuming to ask every keystroke if there is no key pressed.

    The same for the GetButton. Is there any function to know if any button has been pressed? If no button has been pressed there is no necessity to ask the system about every single button pressed.
     
    TaleOf4Gamers and DonLoquacious like this.
  2. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Well, congratulations on deciding to move fully into scripting/programming. As someone more experienced in this new venture you've chosen, I feel it's my duty to introduce you to a fantastic resource that all programmers get used to utilizing very very quickly. Check here for details.

    Look forward to seeing you around!
     
    Baste and TaleOf4Gamers like this.
  3. absolute_disgrace

    absolute_disgrace

    Joined:
    Aug 28, 2016
    Posts:
    253
  4. gerdich

    gerdich

    Joined:
    Feb 19, 2016
    Posts:
    10
    Thank you! That'it!
    But it would be even better if there was also a function that indicates if there is a new keydown even if there are still some keys held.
     
    Last edited: Oct 17, 2016
  5. absolute_disgrace

    absolute_disgrace

    Joined:
    Aug 28, 2016
    Posts:
    253
    Thats why there is two. The first link 'Input.anyKey' simply checks if a key is down right now. The 2nd Link, Input.anyKeyDown', is a boolean that is true only the first time you check that key for that press. It will return false until either that key is released and repressed, or if another key is pressed.
     
  6. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    The documentation seems to read otherwise:

    Doesn't mean the documentation is right. But welcome to another aspect of learning to program - sometimes you just have to test things to see how they behave.
     
  7. gerdich

    gerdich

    Joined:
    Feb 19, 2016
    Posts:
    10
    I am not asking for an exotic function but for a very important and basic one.

    For the moment the main problem is solved and I can write Apps with 1 keystroke at the time. With the variables of anyKeyDown and anyKey.

    But today the use of many keystrokes at the same time is standard. Gamining keyboards are sold with the feature that many keystrokes are hit at the same time.

    In this case these both variables are not enough and I have again to poll every frame every keystroke that interests me. That is not practicable for simple mobile devices. I need a variable that indicates to me a keydown even if other keys are pressed. Also anykeyup would be useful.
     
  8. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    With scripting based on keypresses, I find it's better practice to explicitly state what key you are listening for, and the ONLY time to use AnyKey is when you absolutely do not care which key is pressed ("Press any key to continue" situations)
    For key combo's, you usually want to use Input.GetKey for the modifier key (ctrl, shift, etc) and Input.GetKeyDown for the modified key.
    I.E.
    Code (csharp):
    1. if(Input.GetKey(Keycode.Shift) && Input.GetKeyDown(KeyCode.A)) //Will execute when the shift key is being held and the A key is pressed
    2. {
    3.     //Stuff
    4. }
    You can also nest your if statements so that, for example, holding down the shift key will do something, and when you press another key while still holding it down, something else happens.

    Code (csharp):
    1. if(Input.GetKey(KeyCode.Shift))
    2. {
    3.     //Sprint
    4.     if(Input.GetKeyDown(KeyCode.Q))
    5.     {
    6.         //Dodge roll left
    7.     }
    8. }
     
    DonLoquacious likes this.
  9. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Yeah, I've never heard of a use-case in which an "anyKeyDown" event is desired while already holding down other keys, so I humbly disagree with the "not exotic" and "very basic" statements. The reason for there not being an "anyKeyUp" function is likewise because there simply hasn't been any reason for it. No requests means not a priority. You could just check the Input.inputString value and parse the result if you really want to do it without polling the keys individually though, I suppose.

    If you gave us more info for your specific use-case, we can probably assist in working around it, but likely the solution is just nested input trees as Vedrit suggested. If you aren't sure which keys need to apply to which functionality, then use "buttons" instead and then change them dynamically in the Input class as needed.
     
  10. gerdich

    gerdich

    Joined:
    Feb 19, 2016
    Posts:
    10
    I humbly disagree with Vedrit and Lysander.

    Polling is very timeconsuming, if you have a big routine. You have hundreds of frames per second, but in average only a keystroke every five seconds.

    It is true that anykey and similar have no sense if you are only interested in one keystroke. But if you have dozens of key- and mouse button strokes the handling routine becomes very important and cannot be reduced to a tree structure with one main element. Instead it has to be handled in a Switch-like structure.

    The ONLY way to reduce the load is accurate information if any key has been stroke or released.

    If the handling routine is triggered by such an information even a relatively long handling routine is no problem. Because it happens relatively seldom.

    In the event driven programming model you don't have this difficulty because events are only emitted if anything has happened.
    But in a polling oriented programming model you have to provide enough variables to prevent such overload.
     
  11. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    You are over thinking it. Unity does the device polling for you. You are just querying Unity to see if a particular button was down - you have to do that somewhere - and Unity is just checking its data that it received from the input device in whatever method Unity chose to do it. Regardless, you are spending time optimizing something that very rarely even needs to be thought about in terms of performance.
     
  12. gerdich

    gerdich

    Joined:
    Feb 19, 2016
    Posts:
    10
    Yes! Unity does the device polling. But asking every frame if a key has been stroke is also a highlevel polling. Instead of asking everytime for every of hundreds of keys if they have been stroke is time consuming.

    The variables anyKey and anyKeyDown are a good beginning if one keystrokes follows the other. But if you have multiple keystrokes at the same time they are not enough.

    I have necessarily to know if a new key goes down even if there are already some keys down. Else I would need highlevel polling again.
     
  13. Dave-Carlile

    Dave-Carlile

    Joined:
    Sep 16, 2012
    Posts:
    967
    Either Unity does that, or you do it. Unity doesn't currently do it, which leaves you one option.

    You still haven't described exactly what your end goal is - why do you need this functionality? What are you trying to accomplish? Be specific.

    Most keyboard hardware is only capable of reporting 3 or 4 simultaneous keys. So it's possible what you want can't even be done physically. So tell us why you want this.

    You might take a look at Rewired in the asset store. It's a complete replacement for Unity's input system and allows runtime key configuration among many other things. Perhaps it also implements what you're looking for.
     
  14. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    I have never found a case where having a 1000 if statements in Update would cause any noticeable delay when conditions were not met (Keys weren't pressed) so I don't see the problem.
    Are you currently experiencing low framerates? As it's been suggested to me, try something and use the profiler. If optimizing needs to be done, then worry about it then, not before.
     
    Dave-Carlile and Kalladystine like this.
  15. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Unity's input system is old and in desperate need of updating. Its currently on the plan to be fixed eventually. You have a few options
    • Wait for the release of the new input system
    • Deal with the limitations of the current input system and poll every frame
    • Use a third party input system like Rewired
    No point complaining about what Unity should be. It currently isn't that. You need to deal with whats in front of you.
     
    absolute_disgrace likes this.
  16. gerdich

    gerdich

    Joined:
    Feb 19, 2016
    Posts:
    10
    BoredMormon: I'm happy to hear about a new input system. I'm not complaining but I make constructive propositions that can easily be realized.

    Dave-Carlile: I'm not speaking about the number of keys simultanely pressed (even two is to much for anyKey and anyKeyDown). I'm speaking about the number of keys the handling routine is interested in. That are very much. One for up, one for down, one for left, one for right, one for jump, one for menu, one for help...

    All those keys you have to verify separately in every frame if you have no accurate information about any key pressed.
     
  17. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Yeah. Unfortunately the Input system has been a weak spot in Unity for a long time. I'd expect the new system to deal with a lot of the problems you have raised. But its not likely to be out soon enough to matter.
     
  18. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    You do, and the keys are enumerations that work well in switches, not string values, so the checking is quite fast. I'm a huge fan of event-based designs, but meh.

    If you really want, you can create an OnGUI function in a new script (the only time I'm going to recommend this outside of editor extensions) and, since that is driven by the event system, you can check there if any input is being received this frame and use that to run the "check for input" function instead of having it in Update (or broadcast an event that input's being received, etc...). It receives events twice per frame if memory serves, and I haven't used it in so long that I can't give you any more information than that, but it should be a good starting point.

    @BoredMormon probably knows how that would work.
     
  19. Kalladystine

    Kalladystine

    Joined:
    Jan 12, 2015
    Posts:
    227
    Definitely look into the new input system - the part about ActionMaps in particular is (I think) an attempt to solve an issue like yours. Your feedback would definitely be valuable there (you can start here).
    Although it might not be out soon, it is (theoretically) usable. You could at least try it out and see if it appears to may solve your concerns.
     
  20. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Its been a long time. I'd forgotten you could do that. But OnGUI is slightly superior for waiting for a generic keypress. OnGUI does give you the keycode for the button that was pushed. I use this technique for setting up run time configurable input.

    https://docs.unity3d.com/ScriptReference/Event-keyCode.html

    Be warned, it might end up performing slower than simply polling every key of interest yourself. Profile it just to be sure.