1 Frame Lag With All Control Input. Rage.

Hello there,

I’ve been fussing for hours and hours trying to figure out why my game feels “bad” and I’ve come to the conclusion: All of the Unity input is 1 frame behind! I verified this by lowering the framerate to a point where this became obvious. Need more proof? I got the XInputDotNetPure library for gamepad input and it is squarely one frame AHEAD of the Unity input methods. I am infuriated, frustrated, you name it. You’d think this would be fixed.

I am currently looking for a way to get at the raw mouse input at the very least for my game, with no seperation between input and display (same dang frame), as I know there already exists a method for gamepad input. Does anybody know if a practiced solution exists?

It’ll be nice when that sickening delay between looking, firing and seeing it is fixed. It’s a deal breaker.

I didn’t know about that

Anyway, can’t you just delay your gamepad input by one frame? I don’t think any player would notice, unless his/her specs don’t suffice and it’s pretty easy to delay just by one frame

No, the point is, the controls are a frame behind. That’s a problem when you’re making a high precision game. If the camera movements lag behind the mouse, the game feels really bad. It’s the difference between aiming in TF2 and aiming in ARMA 3. You may not notice the difference, but you can feel it. Trust me, your solution is the last thing I wanted to hear. More I want a Unity developer to fix this, or point me to a workaround.

1 Like

Hmm it appears I can create c++ plugins for Unity
http://docs.unity3d.com/Documentation/Manual/Plugins.html
And it also appears c++ can get mouse and keyboard events without any libraries but windows.h
http://stackoverflow.com/questions/7798242/keyboard-mouse-input-in-c
I’ll try this out and report back if anyone’s interested.

Bah it’s no use. Note to all people wanting to make an FPS on Unity. Don’t -_-

Did you tried to save your Project and reinstalling Unity?

You do realize that there is latency inherent in the device itself right? And that a lot of it can occur at the OS level?

Also, statements like “My controls stink because Unity adds one frame of latency to my input” sounds like garbage to me.

1 Like

^

That 0.001 - 0.01 (depending on how good or bad the rest of your code is) sounds like it would really be a problem.

Why don’t you change your script execution order? also you get more latency than 1 ms from input devices and you don’t even realise it. Then you get some latency from the display unit itself. It’s never 0 ms. You should fix your code. I mean one frame? if it’s 60fps that’s not measurable really.

Could you give more information or supply a test so we can assist you? In any case it’s likely you’re probably reading inputs after the scripts that want them. So first off, set your input code to be executed earlier.

So I came back to this forum, read all of this stuff that made me shake my head, so I’ve thrown together a video, hope it gets through.

Heh, I’m sure a lot of you will be shaking your heads after this video for other reasons :stuck_out_tongue: However!
One frame is significant (unless you’re playing above 120 fps, double the refresh rate). The script execution doesn’t affect anything.

Here’s the Unity project for you to try if you want to.

https://www.dropbox.com/sh/g77143gslazczfq/opCIlyvi9P

All I want is a solution, not retorts on how it isn’t a problem or I’m too inexperienced to know how to fix it. I’m a Canadian adult male and have 8 years of experience developing, so there should be no language barrier, no judgments on my knowledge base. Please cut to the chase.

I don’t expect any of you to have the solution either, and I don’t expect a Unity developer will grace us with a half-hearted retort either. So this then stands as a giant warning sign to those developers that are hoping to make a snappy precise experience, that they won’t if they use Unity.

If you want to know if the rest of my code merits the concern for Input lag, here’s my first and latest Dev Log video. Also as an assurance that I don’t usually take myself seriously :stuck_out_tongue:

I reimplore you to understand: This lag is my biggest problem right now. I can get around real-time model loading and global illumination, but this lag issue is a real problem for me, unsolvable and deplorable (besides bumping the framerate above 120 fps, but that doesn’t fly for netbooks and 7 year old computers).

This is not as much a guy asking for help, as this is a guy lamenting on how one little issue could stand between a developer with a great game engine and a great FPS. I’m not going to go make my own engine. I’ve tried that, it’s exhausting for a hobby. But I’m not going to silently accept a horrible wart on an otherwise beautiful piece of software. Developers CAN fix it!

$1500 for this. $1500

So, you did check the script execution order? You realise right, that if your input script executes after your other scripts, inputs will defer a frame? Unity - Manual: Script Execution Order settings

If you can eliminate that as being one of your issues then we’ll take you seriously. At the moment you’re making amusing comments involving 7 year old netbooks, which probably would update your game so slowly, that input really wouldn’t matter with huge steps between visual updates.

Yes, as I said. [quote=“Font8, post:10, topic: 509032, username:Font8”]
The script execution doesn’t affect anything.
[/quote]
.

Like a good scientist, made sure there wasn’t any loose variables. If you want to throw your ideas around, you can try them yourself with the project I put up. You might have missed a post, Hippo.

Did you look at this post? Probably the best solution you’re going to get unless the Input class is changed in a future version of Unity.
You can move your fake cursor by the amount that the real cursor moved last frame to extrapolate where it really is this frame. This isn’t a perfect solution but it will feel 98% better than the cursor always lagging one frame behind.

Yep, dead reckoning for mouse movement sounds good, but it makes things super jittery, thanks anyway!

“All the Unity input is 1 frame behind.” No, that’s not what’s happening. Notice that in your video, sometimes both XInput and Unity do change simultaneously. So clearly not all input is one frame behind.

(BTW you don’t have to run at low framerates to see this - just record&report the value of Time.frameCount when things happen.)

The reason this is happening is because Unity samples the input at the beginning of the frame, prior to Update(), and stores it for the duration of that frame - so all Input.GetButton()/Input.GetAxis() values will return the same results throughout the frame - while your XInput call is reading the input exactly as it is (or at least, as the driver reports it) at the time of the call. When you hit the button on your controller, either you do it in the part of the frame between input sampling and XInputTest.Update() - in which case you get different results between the two input methods - or you do it in the other part of the frame, in which case it’s picked up by input sampling at the beginning of the next frame.

So, the biggest problem with changing the current behaviour is that many scripts/projects rely on the Input.Get*() values being consistent across a frame - so that ButtonUp()/ButtonDown() semantics stay well-defined, to make it easier to reason about code, etc. I don’t think it’s going to change, though I could imagine some kind of Input.GetButtonDirect() type method that skipped the cache and provided the most up-to-date values available. I suggest filing a Feedback request.

All this said, I’m making an FPS too, and - though it took some tuning to the inputs - we have no problems with the ‘feel’ of the controls at 60FPS. Now, we’ve not released yet, so maybe when we do the players will all say it feels horrible - but I doubt it. So it is possible to do this stuff on top of Unity’s present behaviour I think.

1 Like

Nice info, Richard.

But I have to question if it’s actually - even in a sporting environment - going to make any difference to the feel or aiming. A pro player isn’t just about lag (60fps would probably still be ok) but about experience and generally not overshooting the mark. Factors like the display resolution being much higher than 1080p would probably give you more of an edge than a difference of 4ms or whenever the sampling for input takes place.

Regardless, it’s a moot point. We now understand what is happening. I suppose running the game at 120fps with vsync off would probably sample unity inputs a lot faster, so perhaps that’s your workaround.

I don’t think so - ‘seeing’ precision is not as important as movement precision. When I see that there’s an enemy to the right side of the screen, I don’t push right on the stick and then hold it until I can see he’s under the crosshairs - I judge, almost subconsciously, how far I need to turn, and then hold the stick for that amount of time and then let go. The higher the input sampling framerate, the more accurately the game sense exactly when I’ve stopped turning.

Actually, it occurs to me that we’re almost exclusively using mouse for control, where the issue is reduced (because time doesn’t matter so much with the mouse, you can just use distance moved). So maybe that’s why I’m not seeing the problems that Font8 is seeing.

Yes, Unity’s input sampling framerate == its render framerate, so running at a higher framerate in general will make the input feel better. That’s not really a practical suggestion for most games though.

The best bet is probably to do exactly what you’ve started doing, Font8, and use a custom XInput DLL to talk to the game controller directly over raw input. However, sampling it once per frame isn’t really going to solve the problem - if you really want super responsive input, then you need to spin your controller sampling into a separate thread. That’ll allow you to sample input at a much higher framerate than you’re rendering.

At 60 fps the delay would be 16.67 ms, faster than the human brain can process as an individual moment of time. Your brain can process and respond to events every 240ms, meaning your mouse delay is mathmatically impossible for you to notice without diagnostic tools. It may be another issue. Let a friend play and ask what they think.

Try your reaction time on Human Benchmark

I get between 190 and 230 very reliably (around a 210 average) and a) I’m old and b) it’s 3am. By the looks of it, you’d need to be a sportsperson to go lower to around 100ms - say a professional sprinter listening for the start gun.

I’d say that fresh with some coffee I’d probably get it down under 200 consistently. For the most part I believe winning is about awareness, not shooting reaction time. It’s about preparation too. So I don’t think its important.

1 Like