Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
6
Question by DaveA · Mar 30, 2011 at 11:37 PM · eventkeyrepeat

Any way to key JUST keydown and JUST keyup events?

I'm trying to determine when keys are really going down and really going up. They Event stuff of course has these events, but, as it says in the docs for KeyDown:

"This event is sent repeatedly depending on the end user's keyboard repeat settings."

So I'm getting a whole slew of 'keydown' events, just by holding a key down. This is false for my purposes, because the key is already down.

I could make an array to hold key up/down status for all keys, then have it ignore key-down events until it sees a key-up for each key.

Is there an easier way?

Late Update: It's buggy too, so best option at this point is a hybrid, see http://answers.unity3d.com/questions/51293/mac-keys-not-showing-up-or-very-strangely

Comment
Add comment · Show 5
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Justin Warner · Mar 30, 2011 at 11:42 PM 0
Share

I don't know if this'd work... But, can you get the key down, but also if the key isn't just get down? If that makes sense... I don't know if that'd work... You'd have to test it, sorry =/... But good question imo.

avatar image DaveA · Mar 31, 2011 at 12:12 AM 0
Share

Thanks, not sure what you mean though. I really need to monitor the whole keyboard, and I'm trying to avoid testing each and every key explicitly.

avatar image AngryOldMan · Mar 31, 2011 at 02:55 AM 0
Share

Am i right in assu$$anonymous$$g that if you changed the options on your keyboard to single press events and not press/hold that you would achieve the effect you want? eg in a word document if you hold a key 11111111111111 it repeats, with your change of settings it would only do it once no matter how long you held it down? Some of the answers here seem to mislead my understanding of the question. Seriously though, you're a pro and there are only a few people who have a higher rep than you, answers to your knowledge-filled question are hard to come by.

avatar image DaveA · Mar 31, 2011 at 07:29 AM 0
Share

Thanks. Yes, I don't ask questions lightly. Yes, my computer is set to repeat, but I can't change that on everyone's machine. I was hoping there was another option (like Update/Get$$anonymous$$eyDown, but more like GetAny$$anonymous$$eyDown with a parameter telling which key went down, or some option to set like 'Input.autoRepeat = false')

avatar image zulubo · Aug 04, 2014 at 05:44 PM 0
Share

Thanks Everyone! I really needed this one. Super helpful!

6 Replies

· Add your reply
  • Sort: 
avatar image
7

Answer by Bunny83 · Apr 28, 2011 at 01:24 AM

edit
Since the links i posted don't work anymore (even the question id has changed, probably happend when UA switched to qato) here's a working solution which is pretty straight forward ;)

 // C#
 void OnGUI()
 {
     Event e = Event.current;
     if (e.type == EventType.KeyDown)
     {
         if (Input.GetKeyDown(e.keyCode))
         {
             Debug.Log("Down: " + e.keyCode);
         }
     }
     if (e.type == EventType.KeyDown)
     {
         Debug.Log("Up: " + e.keyCode);
     }
 }

You can't prevent the KeyDown event from happening at the systems repeat rate. Even on windows you'll get a WM_KEYDOWN for each repeated key. However the message contains a bit-flag if the key was down previously. Unfortunately this information isn't transferred into the Event system.

However in combination with Input.GetKeyDown you can easily filter out the repeated events.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Major0 · Aug 01, 2015 at 08:09 PM 0
Share

Hey @Bunny83. As usual you save the day :P Thanks for your advice on writing my own Icon loader (converting .ICO to .PNG) I guess that's the way it should be done.

On another note regarding this question here, your answer emphasized that currently the best way to detect $$anonymous$$B input is through Event.keyCode... Because using Input.Get$$anonymous$$ey and its variations in Update() proved to be unworthy since it merely checks for input flags each FRA$$anonymous$$E only (doesn't detect the button being pressed the moment it's actually pressed).

I could use what you used in OnGUI and implement a switch statement on e.type to handle different case ($$anonymous$$eyDown, $$anonymous$$eyUp etc..) BUT I am trying to do this using uGUI

I have been poking around for implementing this logic in uGUI but so far there's ISubmitHandler which works for submit key only, and IUpdateSelectedHandler which seems to be a candidate superhero: Example from uGUI's InputField source code

Though I have no idea how this would happen. If you could shed some light on using OnUpdateSelected for keyboard input detection I would be REALLY glad. Because without this I would actually have to use deprecated OnGUI with uGUI lol

avatar image Bunny83 · Aug 16, 2015 at 09:24 AM 1
Share

@$$anonymous$$ajor0: Sorry for the late reply, i wasn't home the last two weeks ^^.

I think you have a wrong view on how things actually work in Unity ^^. The scripting environment in Unity runs on a single thread, the main thread. So everything happens in a successive fashion. There's no "in-between" event, ever.

Even in a "normal" windows application (actually a unity windows standalone build is such an application) you don't get in between events. A windows application has a message queue. The system will generate and queue messages into that queue. The application has to poll the queue at some point in the main loop to actually read those messages. This is called the message pump as it usually just calls Peek$$anonymous$$essage / Get$$anonymous$$essage and pass the information to the proper handler.

Unity actually works exactly the same way. At the start of the main look Unity will process the systems message queue and create it's own "message" type for each event. That "message" is a Event in Unity. So Unity just copies over the system events into it's own queue at the start of a frame. This queue is processed automatically and will call OnGUI for each Event in the queue.

In the past OnGUI was the only way to access those events. However since the new GUI system the Event class has a new static method called PopEvent. This method can be used to manually poll and remove a queued event from the queue. All you have to do is create a variable of type "Event" and initialize it with an empty new Event(). When you call PopEvent and passing your empty event instance, the method will copy the information of the next queued event into your variable and remove the event from the queue. If the method returns true it successfully read an event. If it returns false the queue is empty.

PopEvent has one big disadvantage over OnGUI: There can only be one script that uses a PopEvent loop as it removes the Events from the queue. OnGUI can be processed by multiple script.

The third-party framework NGUI actually used OnGUI to read the keyboard events. As you can see in the code you've linked above the new GUI system uses a PopEvent loop. Of course a GUI system usually only has one active element which will receive all system events so that's usually not a problem.

Anyways, you won't get a better response time using OnGUI or PopEvent. All input is still gathered at the beginning of a frame and that information will be constant during that frame. If during a frame new events happens, it won't be visible until the next frame after Unity has read it's own message queue and make it available to it's own event system.

In a frame-driven system you don't want self-changing states during a frame.

avatar image Major0 · Aug 23, 2015 at 10:16 AM 0
Share

@Bunny83 Thank you so much for the beautifully elaborated description on how Unity handles events! Gotta love exploring low-level concepts and how things work in the background!

Using PopEvent()sadly prevented other uGUI components from taking Input as you said since it pops the event from the queue. This is not a big problem since I have a hasFocus flag so it's not like I am popping the event from the EventQueue every frame -- just when the focus is on my custom uGUI element. Nevertheless, I reverted back to OnGUI and things are going quite well now!

Wish I could transform your comment into an answer to my question here but unfortunately that is not possible. So if you are not going to copy-paste your answer there in the following days (cuz I want you to take the credit for it) then I am going to do it myself and mention your name there :)

avatar image
1

Answer by Matthew 5 · Mar 31, 2011 at 12:02 AM

var KeyDown:boolean = false;

function Update () { if (Input.GetKeyDown("c")) {

(if !KeyDown) {

doSomething

KeyDown = true; //turns off the loop

}

if (Input.GetKeyUp("c")) {

(if KeyDown) {

doSomething

KeyDown = flase; //turns off the loop.. again

}

}

That is a quick work around..

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DaveA · Mar 31, 2011 at 12:13 AM 0
Share

Would this even compile? I've not seen this syntax before.

avatar image Matthew 5 · Mar 31, 2011 at 12:16 AM 0
Share

its messy, let me clean it up.

avatar image Matthew 5 · Mar 31, 2011 at 12:21 AM 0
Share

though.. once you trigger the false statement; it will stop the lines of 'doSomething' .. so make a method and in that method, after it does what it needs todo, add $$anonymous$$eyDown = true;

avatar image DaveA · Mar 31, 2011 at 12:22 AM 0
Share

Yeah, this is basically what I meant, but since I need to monitor all keys, I'd have to have an array of $$anonymous$$eyDown to check thus. I'm going ahead with that unless/until something simpler comes along. I'll vote for an option on the feedback forum (like that will ever happen!)

avatar image Matthew 5 · Mar 31, 2011 at 12:26 AM 0
Share

Goodluck man, is there any way you can go about fixing your keyboard issue, Get$$anonymous$$eyDown should only fire on one frame.

Otherwise, Im glad this helped and accept an answer so people can see its been solved.

$$anonymous$$atty

Show more comments
avatar image
1

Answer by miketucker · Sep 04, 2013 at 01:11 PM

here is a more elegant solution:

     void OnGUI()
     {
         Event e = Event.current;
         if (e.isKey && e.type == EventType.KeyUp){
             switch(e.keyCode){
                 case KeyCode.Space: Debug(); break;
                 case KeyCode.UpArrow: ShiftUp(); break;    
             }
         }
     }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Qwerty · Mar 31, 2011 at 12:04 AM

Hey,

You can use :

if(Input.GetKeyDown("c")){ //do stuff }

if(Input.GetKeyUp("c")){ //do stuff }

Even better though, you can use axes if these are game controls (especially if used constantly) with Edit > Project Settings > Input Then:

 Input.GetAxis("AxisName")

And when all else fails (which it should not here), you can always result to good old true or false (or as I like 1=true , 0=false) such as:

//Your trigger happens: ItsGoing = 1;

if(ItsGoing == 1){ //Only do this when its 1, then reset back to 0 ItsGoing = 0; }

Hope this helps!

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Matthew 5 · Mar 31, 2011 at 12:15 AM 0
Share

The problem he was having is that his PC sends $$anonymous$$eyDown every frame due to his PC setup, unlike normally it would only send on the first frame it happens.

avatar image Qwerty · Mar 31, 2011 at 12:55 AM 0
Share

ooh, now I understand. yes he will need to use some kind of true false system then like you suggested under this.

avatar image
0

Answer by AngryOldMan · Mar 31, 2011 at 03:09 AM

i think what mattyk means is

var KeyDown:boolean = false;

function Update () { if (Input.GetKeyDown("y")) { if (KeyDown == false) { Debug.Log ("Key is being pressed"); KeyDown = true; } }

 if (Input.GetKeyUp("y"))
 {
     Debug.Log ("Key has been unpressed");
     KeyDown = false;
 }

}

but like you mentioned this will have to be specified for each key giving you possibly 20-30 variables and copies of this script, which doesnt sound like a day of fun making. I'l be watching via favorites to see if you get a hardcode solution.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

How to define the number of times of an event? 1 Answer

Making a repeating event that detects if you are in the rain? 3 Answers

event for key release 3 Answers

Particle Collision / Trigger not being reported to On_xx Event 1 Answer

Animation Event Lag 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges