Search Unity

Understanding, Measuring, and Reducing Input Lag in Unity?

Discussion in 'Input System' started by kromenak, Oct 16, 2019.

  1. kromenak

    kromenak

    Joined:
    Feb 9, 2011
    Posts:
    270
    Hi, I'm currently evaluating engine options for a "classic" tournament-level fighting game along the lines of Tekken or Street Fighter, etc.

    When considering Unity, one concern that was raised by a few team members was that Unity has a lot of input lag, making it an unacceptable option for a fighting game.

    I'm not sure if those concerns have merit, or if it used to be a problem and isn't any longer, or if it was a problem with the old input system but not so much with this new input system. Regardless, some people I'm working with have got in their heads that using Unity for a fighting game is just crazy because of the input lag problem.

    So, I thought I'd ask here to get the takes of those who likely know a lot more than I do about it!

    I actually tried a "poor man's" input test: I integrated the new input system into a test project where a cube on-screen appears when the button is pressed and disappears when the button is not pressed. I stuck a frame counter up on screen. I used the slow-mo camera on my iPhone (240FPS) to try to capture some data comparing when I press the button on my controller vs. when the cube appears on screen. It all feels too inaccurate to provide much meaningful data, but it seemed like sometimes I was seeing 2-3 frames of delay, other times maybe 4-5. But again, not a very accurate method! I certainly am not using the "hardware light soldered into the controller mechanism" trick ;). 2-3 frames doesn't seem very bad to me, but 4-5 sounds a bit high.

    Our goal obviously is to achieve the smallest amount of input lag possible - so, I'm curious whether that is a known value and what engine settings (quality, graphics, input, etc) should be used to achieve that.

    The alternative to using Unity (or some other commercial engine) would be to build an engine ourselves in C++. But I'm not entirely sure (or convinced) that would necessarily reduce input lag...unless Unity is definitely doing something that adds lag that we could avoid in a DIY situation.

    Also, is there any way to determine how much lag is introduced just by the hardware itself? For example, knowing a system timestamp when an input becomes available for the software to consume vs. when it is actually consumed in my user-level code might be an interesting metric.

    Sorry if any of the above is misinformed or naive - but definitely interested to hear any data or thoughts on this topic!
     
    Rs likes this.
  2. I'm not a professional, I have never measured the latency of the input, so please handle my thoughts with a grain of salt and stuff. But, I see some potential flaws in your measurements:

    - 240 FPS = 4ms per frame, if you see 5 of them, that's 20ms, barely higher than one frame at the standard of 60FPS game (and those ~4ms easily can come from your monitor latency, if this is true, and your "game" is running on 60FPS, then you practically got your input in the next possible frame)
    - did you have your v-sync enabled?
    - what kind of display-latency do you work with?
    - have you set the new Input system to gather info on Update or on FixedUpdate or Manually?

    ---

    - You also can try (I really mean try, it's experimental) to fiddle around the https://docs.unity3d.com/ScriptReference/Experimental.LowLevel.PlayerLoop.html API and try to build a custom player loop.
     
    Rs likes this.
  3. kromenak

    kromenak

    Joined:
    Feb 9, 2011
    Posts:
    270
    Yeah, I agree that 240FPS is not really good enough - just making do with the hardware I had available.

    I initially tried with v-sync disabled because I assumed that it would increase input lag. But I'm also going to try testing a bit with v-sync on.

    I'm using an iMac from late 2015, which I believe runs at 60Hz. I am not sure if that answers the display-latency question, or if that's a different metric.

    I initially tried the new Input System with the default "Dynamic Update," but I'm now trying out using "Manual" with a script whose execution order is set to always run first. I have no idea if that would help - just trying a few things out.

    I came across this website which has some interesting info about input lag, but I'm not sure how much of it is relevant in Unity: https://inputlag.science/engine
     
    Rs likes this.
  4. It's different and it does not help. We need your screen exact metric because iMac displays can be crappy when it comes to latency. The newer (I think 2017?) 5K iMac display has a whopping 12ms latency (!!!). Which means you put the image on the cable, it arrives and the user only see this 12ms later. That's almost an entire frame late (on 60FPS).
    So I'm guessing, the older iMacs don't have particularly better displays (when it comes to latency).
     
    Rs likes this.
  5. kromenak

    kromenak

    Joined:
    Feb 9, 2011
    Posts:
    270
    Yeah, that's a good point. And it does seem likely that my 2015 iMac's display latency is then not negligible!

    There is potential for lag to be introduced at a variety of places in the input pipeline, including the controller itself, the OS, or the display. I guess I'd be most interested to hear about the factors that I can actually control in Unity to reduce lag that comes from the engine code itself.

    I could be wrong, but I'd bet that keeping input lag low (or at least providing control over it in some ways) has been a consideration the developers of the new input system have thought a lot about.
     
    Rs likes this.
  6. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    It's been a consideration and we've done some things but there's still work to do to look at lag more closely and specifically optimize for it. With 1.0 of the system our benchmark goal was to be no worse than the old system at least (we do have some reports that for touch, we're actually looking worse on some platforms). Our ambitions for >1.0 are to go beyond that.

    Specifically for a fighting game on desktop that primarily targets controllers, my recommendations/thoughts would be:
    • Put the system into manual update mode and in your game code, minimize the time from when you call InputSystem.Update to when you render the result (basically the lag on your side). By using manual updates, you unhook the input system from fixed points in the player loop and basically get the ability to move input queue flushing and processing as late in the frame as you can. The big gotcha there is physics. If you need input to feed into physics with no added lag, you're back to FixedUpdates and increasing the distance from input to output.
    • Crank up InputSystem.pollingFrequency. On the Mac, it won't matter as there's no polled gamepad input but on Windows, it'll crank up the sampling frequency of XInput controllers making it more likely that when you do flush out input, you'll have the most up-to-date state. IIRC Xbox controllers have a 4ms report interval so 250Hz is the max you can get out of this.
    To determine the amount of lag between when we see an input and when it gets processed by the input system (i.e. excluding the lag from that point to input making its way through game logic and then back out through rendering), you can check the timestamps on InputEvents and compare them to Time.realTimeSinceStartup.
     
    NikoBay, Jingle-Fett, Rs and 7 others like this.
  7. kromenak

    kromenak

    Joined:
    Feb 9, 2011
    Posts:
    270
    Very cool! Thanks for the insight.