Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Realtime input in Unity

Discussion in 'Scripting' started by Hyphen-ated, Jul 12, 2010.

  1. Hyphen-ated

    Hyphen-ated

    Joined:
    Jul 12, 2010
    Posts:
    6
    I'm working on a fighting game in Unity, which has to be able to take input from keyboards and joysticks. In these kinds of games, the input timing has to be very precise: inputs must be updated on a consistent schedule of 60 frames per second, even if the actual graphics run much slower than that. Unity's built-in input system appears to only update itself once per graphical frame, in Unity's Update() loop. (according to http://unity3d.com/support/documentation/ScriptReference/Input.html)

    This can go much slower than 60 frames per second, so it seems I have to either use a thread to call an external library that gets input, or guarantee that Update() runs at 60 frames per second by limiting the graphical complexity. I'm not willing to limit the graphical complexity.

    Here are my questions:
    1: Is my above analysis correct -- Is there any built-in way to get realtime inputs in Unity even when the graphics lag?

    2: Is it possible to get realtime inputs AT ALL in the Unity web player? According to this post http://forum.unity3d.com/viewtopic.php?p=264040#264040 in the web player I can't bring in external code that calls anything outside of Unity or Mono. I can't find any way to do input from joysticks in Mono; it seems like I have to use something like DirectInput or SDL. Is this correct?

    3: Do I really need Unity Pro to use something like DirectInput or SDL?

    Thank you
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    1. No its wrong.
    For one, you should never capture input faster than the rendering is cause there will be useless information (keep in mind, you calculate changes on frame to frame base, input that is updated twice between frames will just be dropped!).
    For the other, if it runs that bad, people won't want to play it independent of your input code errors.

    Also ensure that you create your code to be fps independent by having fixed "per second change values" multiplied by Time.deltaTime

    2. Plugins don't work in the webplayer and no you can't workaround it through mono etc cause all functionality that attempts to access something from the system will NOT work in the webplayer (environment, process, file io, ...)

    3. Yes, plugins are unity pro only. in this case though kind of useless at least in case of SDL as you have no access to DX and OpenGL calls.
     
  3. Hyphen-ated

    Hyphen-ated

    Joined:
    Jul 12, 2010
    Posts:
    6
    You are correct for most games, but not for fighting games. This is a quite rare requirement, that input and gamelogic be realtime instead of tied in with the graphics.

    I update the gameplay logic separately from the graphics frames, in a different thread. My gameplay updates happen at a constant 60 fps. During a single frame of graphics, I can have several gameplay frames be calculated. Therefore it is not wasted information for me to get input more than once during each graphics frame.

    This is important in fighting games specifically because exact timing (down to the 1/60 of a second level!) is part of these games. Also players memorize the exact timing for combos and other such things, and the game needs to react consistently every single time, even if the graphics were running at, say, 50fps instead of 60fps.

    Thanks for your reply.
     
  4. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    You don't need distinct threads for this (would only help partially because the input handling could not talk to unity functionality as unity isn't thread safe).

    Just use Coroutines with yielding for WaitForSeconds( 0.016) or FixedUpdate with a timestep of 0.016 and do the input handling there, that will be at a fixed rate.

    none the less, your primary target must be to make it fluent especially if it is a fighting game as it is aside of shooters the only genre where low FPS is totally inacceptable
     
  5. Hyphen-ated

    Hyphen-ated

    Joined:
    Jul 12, 2010
    Posts:
    6
    Distinct threads are fine, because I can make the interface between my gamestate and my graphics threadsafe. The gamestate thread stores a full history of every gamestate frame in a list, and it updates the index to the "current frame" once it is completely done with a frame. The graphics (and sound) code can then look at the current frame at any time, and the game history at that frame will be fully correct. This is the only interface between the gamestate and the rest of Unity. The gamestate thread never calls any Unity functions at all.

    Coroutines don't work because the Unity input functions only update themselves at the speed of the Update() function. I need the input to update at 60 fps in real time. FixedUpdate doesn't work for the same reason. It will get called 60 times in a second, but if the graphics were slow then the calls to FixedUpdate get "bunched up". Like if the graphics is running at 30fps, then FixedUpdate will get called in chunks of two at a time, 30 times each second.

    It is correct that the graphics should be fluid. The input must be MORE fluid. It is acceptable for the graphics to display at 50 fps average, and vary somewhat. That would not look bad. It in unacceptable for the gamestate logic and the input to run at 50 fps. It must run at 60, completely smoothly with no variation.
     
  6. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    well in that case you need unity pro and a plugin that handles the output totally outside of unity (and it means that you are restricted to desktop targeting, no webplayer)

    Also, unity is not just graphics (just for the sake of completeness in your distinctions), though I guess you know that :)


    what a more fluent than update input handling though would help is over my head as none of the changes you get on the input would take any effect until the next update anyway. The only exception might be combo but combo input chaining that checks more than at worst 30 times per second for changed input does not sound reasonable at all as thats beyond human speed. Thats what I meant in my first answer.

    So even if you update input at fixed 60 FPS. if the FPS is at 30, you will only get this precise in your change requests, animation play etc.
    Collision / physics on the other hand is totally distinct from the update loop and bound to fixed input, but thats the exception

    but its naturally your decision if you need more precision
     
  7. Hyphen-ated

    Hyphen-ated

    Joined:
    Jul 12, 2010
    Posts:
    6
    This is what I thought, which is unfortunate for me :(

    Yep, there is a lot of Unity that I can't really use for my game, but there is still a good amount left that is very helpful for me.

    Yeah I'm not using Unity collision or physics at ALL. All the game rules about movement, doing attacks, getting hit and taking damage, etc etc, that all happens in my special locked-60-fps gamestate thread. It's okay if the graphics don't quite keep up at perfect speed, but the logic itself needs to happen at perfect speed.

    It's not beyond human speed for expert players, which are part of my target audience :) They can't react that fast, but if they plan it ahead of time they can get the timing to come out that fast. My input system needs to recognize their timing.
     
  8. foxter888

    foxter888

    Joined:
    May 3, 2010
    Posts:
    530
    i'm working on a fighting game to but in order to make it react faster i speed up the animations on my 3d package. you can always add a timer into how long it should take until you are able to hit the next punch and so on. i'm having some problems more different for my figthing game i still haven't got a response.
     
  9. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    If you're using the webplayer, it may be possible to capture keyboard input via javascript and communicate it back to your game. Perhaps that would update between frames, but I wouldn't count on it.
     
  10. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Why exactly are you using Unity if you decided to not use unity at all?
    Just using it for rendering is realistically seen not an option as it is a tightly integrated environment where the rest will be there and do its job, independent on if you like it or not.

    It will cause you a lot of problems obviously cause your own code will fight with what unity will do anyway, leading you to a point where I personally would take it as granted that you have 2 ways: totally reworking your game to be a unity game or drop unity again cause you realize that you never wanted to use Unity.

    Using it just for the sake of being webplayer capable obviously has outruled itself. (the situation should never exist. if you killed the unity performance that badly you did something misserably wrong, cause unity even scales to trash pcs and runs well there and I doubt you intend to target those ;) )
     
  11. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    I have to disagree with you there. Unity can be used (or abused) however you want to achieve whatever you need to. When it comes to writing large scale, complex applications, a very tight architecture, often made as independent from the processing medium is a plus. All the applications we develop at work are designed in a more or less "pure" form that minimize their dependence on the host application (Unity, Silverlight, etc.) I think Hyphen-ated's method of handling his game logic is alright as long as it's managed well. I've written applications the same way (processing background thread, UI thread, etc.) and it really is a good way to go if your application design warrants it.
     
  12. Hyphen-ated

    Hyphen-ated

    Joined:
    Jul 12, 2010
    Posts:
    6
    Good asset management for models and stuff.

    Superb interface for editing things live while the game runs. The designer/balance guy is going to spend a lot of time tweaking things, like hundreds of times in each test session, while running the game to test his changes live. Extending the unity editor to do this looks quite a lot easier than writing my own UI for it from scratch on some other platform.

    Easy PC/Mac compatibility for all the graphics and sound etc
     
  13. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    @FizixMan: I agree that it makes sense to have some stuff independent. But from what posted he has ALL stuff independent, does not use collision, input etc, just the rendering and potentially the sound output ...

    In such a case I think it should be evaluated closely if the enforced changes (its not like they are a can, they are a must as long as he relies on low level / native / unmanaged code) impact your "independent" solutions significantly.


    @Hyphen: from what you mentioned though you are not that much interested in these things, at least you mentioned that you have own unity independent game logic code, collision code etc so you hook out the majority from unity (or at least try to, you will potentially find out that they can strike back very hefty when done on the wrong thing or the wrong way).

    The editor naturally is nice, but keep in mind that it is built around, for and with the engine, its not built as standalone editor and it will not work like one.

    I'm saying all these because you aren't the first one with interesting in using Unity yet bypass large parts, there were projects that went even further to even bypass the editor and as far as I see the majority of these projects if not all have vanished again as the amount of work you will have when you waste your time fighting the flow instead of going with it will be serious.
     
  14. Thelo

    Thelo

    Joined:
    Sep 13, 2009
    Posts:
    98
    Hey, I'm in the same team as Hyphen-ated here. Just wanted to confirm that reliable 60Hz input, even if the graphics jump at 5fps for a while, really is a hard requirement for fighting games. In these games, you never, ever want to be in a position where a sudden drop in framerate makes it literally impossible for the player to do a move in time. I can't stress how important this requirement is, it might literally be the single most important requirement for any computer fighting game.

    As a famous counter-example, the PC version of the game Street Fighter 4 polls its input at the same frequency as its graphical framerate, and it is notoriously bad and practically unplayable as soon as the framerate drops slightly (which is unavoidable on computers).

    Real fighting games need to split the graphical work (low priority, can run at low framerates) and input / simulation work (high priority, inputs MUST run at 60Hz). When first looking at Unity, we saw the split between Update() (goes as fast as possible, but is unreliable) and FixedUpdate() (updates exactly at a specified framerate) and thought great, this is exactly what we want! We could reliably poll the inputs in FixedUpdate(), maybe also step the simulation there, and do the rest of the graphical work in Update(), and everything would work ok.

    However, that plan fell to pieces when we learned how FixedUpdate actually worked, that it did not in fact update at fixed intervals at it claims to do, but rather runs a bunch of times in quick succession, then waited for the next Update(). Also, that the Unity input system only actually updated its inputs once every Update() cycle. This effectively torpedoed our plan.

    Our backup plan is to require platform-specific plugins that do that reliable input-polling work, but this is a very sad alternative, since Unity is built around this idea of write once, run anywhere, and writing platform-specific plugins runs completely counter to that (and prevents us from using the webplayer at all).

    ***

    To Dreamora, I'm not sure why you stick on the point of "bypassing large amounts of Unity", because we precisely want to avoid doing that. All we need is some way to get reliable 60Hz inputs, and we'll gladly do things "the Unity way" as much as possible. If Unity lets us do that natively, then we will.
     
  15. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    a steady input handling is required, agreed on that.
    Steady at 60 hz is discussable though.

    SF4 has problems cause it does not steadily get the data and thus runs into ugly timing issues.

    But SF4 is also a bad example it was and always will be a console thing, the devs showed themself how much they lack the desire, time and/or dedication to even make it worth the material required to burn the disk ...
    You really shouldn't compare yourself against them though cause if you shoot for a similar craptastic or nonfluent gameplay, you will follow their path.
    Fighting games require an as steady rendering as they require a steady input, influency, hickups or general low FPS are not acceptable ...

    So if your update callrate gets below 60 FPS, or even below 30 you have much more pressing problems to focus on than input out of my view as gamer, be it considering to cancel the project or be it to drop adding features to solidify and optimize what you have to the point where you can start to consider adding things again.


    as for the bypassing: that was in relation to the mention that the collision system of unity is bypassed to
     
  16. Thelo

    Thelo

    Joined:
    Sep 13, 2009
    Posts:
    98
    I will now repeat myself.

    Graphics updating at less than 60Hz is totally acceptable. At some point, computers have performance spikes, sure, everyone understands that. That is not the problem we are talking about.

    Inputs absolutely, positively MUST be at 60Hz. THAT is our current problem.
     
  17. llde_chris

    llde_chris

    Joined:
    Aug 13, 2009
    Posts:
    205
    ^ Because muscle-memory for combos needs to be consistent in real-time... and counters need to be processed on exact frames...
     
  18. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    In my opinoin if you want guarantee of 60hz and not using coroutines or delays or fixedupdate then you have to use threads and spend a lot of time checking if it's time to do something. If you do it fast enough it should hopefully run in parallel with the rest of the game and check often enough to have almost exactly 60hz rate.
     
  19. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I'm not sure how you're going to do that when no Unity functions (such as input) are thread-safe, and will crash.

    Given the requirements, I don't see any other way than a custom plugin, myself.

    --Eric
     
  20. Hyphen-ated

    Hyphen-ated

    Joined:
    Jul 12, 2010
    Posts:
    6
    The algorithm we can use to schedule the input thread is better than "keep checking to see if it's the right time yet". Here's how it works: make the input thread priority be as high as possible compared to the main unity thread. At the beginning of a round, record the current time. Every time the input thread polls the inputs, have it calculate what time the next poll should happen. (by multiplying the current frame counter by 1/60 seconds and adding to the start time). Then compare that to the current time, and sleep the thread for that many milliseconds. During that sleep is when all the graphics will get done.

    This is a good system because little errors don't accumulate; when calculating the "target" time for the next input update, it doesn't matter what the current time is. So if a particular frame is ever delayed or something by factors beyond our control, like other processes on the user's machine, the timing will automatically go back on track afterwards.
     
  21. AkilaeTribe

    AkilaeTribe

    Joined:
    Jul 4, 2010
    Posts:
    1,149
    Curiosity but is your graphics so heavy that you are sure you won't never reach 60 FPS ?

    Simply don't forget that each game has minimal hardware requirements.

    (I know I don't help, saying that, but just don't go bananas)
     
  22. Elecman

    Elecman

    Joined:
    May 5, 2011
    Posts:
    1,369
  23. playsidepaul

    playsidepaul

    Joined:
    Sep 23, 2015
    Posts:
    11
    Bumping this, because I'm also trying to figure this out, for multiple titles (not all games).

    Worked on a 3D data visualisation app a few years ago, which ran on Unity 3.5 at the time. When you added a large dataset and the frame-rate dropped significantly, your (mouse + keyboard) control for looking & moving around would become really inaccurate, and almost impossible to turn and look where you want.

    Later on, we added 3D mouse (Space Navigator) support, by polling an external DLL, and noticed you still felt in control when the framerate dropped. That's when we realised your movement + rotation is still being processed smoothly, even tho the graphics isn't rendering at that frame-rate. Similar to what Hyphen-ated said about fighting games.

    In the last couple of years, we ported this to Windows/DirectX (mainly for performance reasons) and had a similar problem with the mouse movement, until I changed it to read raw input from the System device on a separate thread. Suddenly voila, mouse movement feels smooth regardless of frame rate, and you'll be surprised how much more in control you feel.

    Recently we've been having similar problems on mobile games, especially nowadays with the huge difference in processing power between the targets of iPhone 4S (or iPad Mini) up to 6S, and performance on Android devices is also a complete lucky dip. Add in the odd performance spike when some third-party SDK decides to start caching an ad or sending some analytics in the background and you have users giving 1-star reviews because they missed swipe gestures.

    I really hope a solution to this emerges soon. Gonna add some of this info to the feature request too.
     
    Harinezumi likes this.