- Home /
The question is answered, right answer was accepted
Why do we not yet have a getkeydown that returns a list of all keys down? Or all keys being held?
Input polling is lagging unity engine in a significant way.
I have recently switched to building input functionality using the event system in the ongui because polling the input class in the update function causes significant performance problems.
I've tested the input class using a primitive sphere that has a rigid body attached to it. Then creating a gamemanager that does little more than creating and holding a control class that polls and updates bools for the buttons that I want to be used by the player. For the test I polled all possible keys through the update function and the input class using system.enum to get all possible keys.
This caused noticeable performance delays in the falling sphere.
We need to get some input functions that would return a list of all key downs and keys being held.
If I am thinking about this the wrong way or you think it was the system.enum that caused the frame rate changes I am up for that discussion as well, but it seems right now that polling is dragging.
What's the point in polling all possible keys? The only time when you need such a functionality is inside a key settings menu. Other than that you usually have a fix amount of keys you want to check.
How many keys do you currently poll inside Update? I doubt that polling even 100 keys would be even noticable. $$anonymous$$aybe you did something else wrong? Do you create any garbage each frame like an array? How does your code look like?
I agree with Bunny, please provide code so we can see if you are creating unnecessary garbage.
You might be right about creating unnecessary garbage but I wouldn't know how it did.
I used a polling method that enumerated through all of the buttons, but was just a test:
foreach($$anonymous$$eyCode v$$anonymous$$ey in System.Enum.GetValues(typeof($$anonymous$$eyCode))) { if(Input.Get$$anonymous$$ey(v$$anonymous$$ey)) { // do nothing for test } }
And as stated before the test did nothing except watch a sphere drop while this happened. The result was evident, the ball skipped.
Now that you mention garbage collection, I would agree that the apparent problems did resemble garbage collection issues. not all frames were sluggish.
Have you tried running this test in a standalone build? Have you checked out the profiler to find the true source of the performance problems?
I tried your test code and it runs buttery smooth. I even put it in a for loop and ran it 10000 times on each update, and I still found zero performance problems.
You want a method with a signature like List<$$anonymous$$eyCode> GetAll$$anonymous$$eysPressed()
? I can't really see how that would be helpful - the first thing you'd have to do is iterate through the result set and write a ton of:
if(listOf$$anonymous$$eysPressed.Contains($$anonymous$$eyCode.W)) walkForward();
if(listOf$$anonymous$$eysPressed.Contains($$anonymous$$eyCode.S)) walkBackward();
if(listOf$$anonymous$$eysPressed.Contains($$anonymous$$eyCode.Space)) jump();
etc. etc.
Which is no more convenient or performant than Input.Get$$anonymous$$ey(), surely?
I have begun to use the OnGUI event system for the input and I absolutely love that system. It does exactly what I was looking for.
It allows me to switch on the event.
like so... in the OnGUI of course.
// save current event to e
e = Event.current;
if (e.is$$anonymous$$ey)
{
// update key modifiers from the event e
$$anonymous$$odifierUpdate(e); // unincluded function: out of our context
// keyboard event found
Debug.Log("keyboard event found");
Debug.Log(e.keyCode);
Debug.Log(Time.timeSinceLevelLoad);
switch (e.keyCode)
{
case ($$anonymous$$eyCode.Q):
if(e.type == EventType.keyDown)
{
Q$$anonymous$$ey = true;
Debug.Log("Q is down");
}
else if(e.type == EventType.$$anonymous$$eyUp)
This is masterful for what I need it for and cant believe i missed this before...
So, if this is what is intended by the unity $$anonymous$$m I like it, because doing all of the input in the update function is very single threaded.
So, I would have to take back the need for lists of changed keys while I can use the event system.
I'm struggling to see how that is an improvement.... Checking for input in OnGUI is just as "single-threaded" as it is doing it in Update(). And it's less reliable (do you know how many times per frame your code above is getting called? Hint - it's not once per frame).
As I said, you're having to use a bunch of if/switch of the event type and keyCode, which is less elegant and more fragile than using Input.Get$$anonymous$$eyDown/Input.Get$$anonymous$$eyUp - how are you going to account for runtime key rebinding, for example?
Anyway, none of that really matters so long as it's a solution that works for you!
Answer by DaRaVeNrK · May 26, 2017 at 09:50 AM
@Bunny83 and @ShadyProductions were on target for this problem witnessed here.
I changed the testing code after reading some information about the system.enum function and now believe that this was an invalid test.
The enumerator function was creating a lot of garbage that was having to be collected every couple frames. Still not quite sure why, but that is out of scope for this question/comment.
Thank you all for your support! RDL