0

I'm creating a rhythm game in C#/Unity, and have come across a problem where on most PC's the game runs completely fine but on others the note time (which is stored as the elapsed time from the song start) gradually drifts from the audio time which ends up desyncing the gameplay from the audio. I've tried all the different time keeping values Unity has to offer (Time.time, Time.realTimeSinceStartup, Time.deltaTime, etc) and they all end up causing desyncs.

This leads me to believe that I need to smooth the song time towards the audio time, but I have no idea what's the best way to do that.

I'm not exactly sure how expensive getting the audio time is, so I assume that running it once a second and then smoothing the time values together over the next second and then repeating the process may be a decent way of doing it without causing bad amounts of overhead. Would this be a good way of doing it?

Ryan Foster
  • 51
  • 1
  • 2
  • I'm not a game programmer so this might be a dumb question. But wouldnt it be better to just count frames and do the math from there? You know the BPM of a song, and you could figure out the framerate right? Or at least force the app to run at a certain framerate? – maccettura Oct 17 '17 at 18:51
  • The main problem comes from people running at higher framerates, so the precision errors start adding up and cause the drifting because all I'm doing is keeping track of the elapsed time by taking Time.deltaTime (which is the time between frames) and adding it to a double. This doesn't have anything to do with the BPM of a song, it has to do with keeping the song time updating smoothly while keeping it in sync with the audio time. – Ryan Foster Oct 17 '17 at 19:04
  • This sounds more like syncing than smoothing to me. If the Audio Time should control, then one idea is just to periodically sync up the Note Time to the Audio Time. If you were to smooth (as in blend, like an average) the two times, then you'd get a new value that is neither Note Time nor Audio Time, but a hybrid. – Kevin Fichter Oct 17 '17 at 19:06
  • The problem is that I've tried that. I assumed that the drift would be small enough that periodically snapping the song time to the audio time would work but some players seem to be getting stuttering (was syncing it every second, in between it was updating based on Time.deltaTime). I just pushed out an update where I'm just using the audio time as the song time, and while that's probably more expensive it seems to fix the desync and stuttering issues that were happening. But obviously I'd like to make it as efficient as possible, so I'm looking for a better way to sync/smooth the two values. – Ryan Foster Oct 17 '17 at 19:13
  • 1
    Understood. As I understand it, all you really want is a type of metronome to keep track of time. I don't think any timekeeping api will get you there perfectly. But, going back to @maccettura's comment, you can get a measure of time from the framerate without ever calling deltaTime: Determine or fix the FPS for the app during launch, then just count frames. If the framerate is 50 FPS, and 23 frames have elapsed, then 23/50 seconds have elapsed. – Kevin Fichter Oct 17 '17 at 19:22
  • [Something to check out](https://stackoverflow.com/a/4150095/2655263) re dispatchertimer or just framerate stuff. – Kevin Fichter Oct 17 '17 at 19:33

0 Answers0