Creation of a rhythmic game

Hi, I’ve been trying for a long time to create a rhythmic game such as Line dancing or Geometry Dash. My only problem with which lately I have been having difficulties is the synchronization of the music with respect to the movement of the character.

This is the case, I have my 3D character that moves a level created to measure for the music, the problem is not the level but because of the variation of the FPS my character does not move at a constant speed.

Since then I began to investigate in depth how to create this perfect synchronization between the music and the player, most of the supports of this type of synchronization problems are about “How to create a game like Guitar Hero”, handling events through the beats of music, or how to start events with animations through music but none of this (mostly) served me for my problem.

Then I realized that this “perfect” synchronization was almost impossible because there were many (or perhaps too many) factors that prevented this such as the sound hardware, the response time of input on the device and in the game, the device in which is running, human error with a simple delay and many other things

So, I tried to handle the audio to follow the player, it did not work for me. I tried to change the time of the game with a calculation between the time and the FPS, it did not work either. But stop doing so many laps, I began to understand the true functioning of Time.deltaTime and Time.smoothDeltaTime, then I applied it in the code and at the beginning it worked but then with time I realized that although I applied Time.smoothDeltaTime, even so, there were some variations that unbalanced all the speed of the game, and my character sometimes skips parts of the level more than they should, and then other times it returns to normal.

Sorry if all this was very extensive, I wanted in this publication to show that I have tried many other alternatives and until now I do not find any completely stable like those that are seen in this previously named games, if you have any doubt of these attempts I made with I will clarify your question and hope you can find a solution to this problem

Thank you

PS: sorry for my English, I am using the translator :slight_smile:

Usually you can make a object move at the same speed no matter what the FPS is by multiplying your movement by Time.deltaTime (the change in time since last frame) so that more time means more movement.

Since you want to sync your movement based on audio time, you should multiply your movement by the change in audio time.

float timeLastFrame;
float audioDeltaTime;
AudioSource source;

void LateUpdate()
{
    audioDeltaTime = source.time - timeLastFrame;
    timeLastFrame = source.time;
}

This code snippet gets you “audioDeltaTime” each frame, which is the time that has passed in the AudioSource. If you multiply your movement by audioDeltaTime instead of Time.deltaTime, your movement will be in sync with your music.

EDIT: Fixed a silly mistake in the code snippet above

Thank you! I’m going to try it now, I’ve seen something similar in another post but I did not understand very well why it was used in this case

Glad I could help, though I noticed my code snippet was incorrect =P I’ve edited my post so the code is correct now.

The mistake was that I was using “Time.time” instead of “source.time”.

Gambit-MSplitz Ok, I multiplied the speed of the character by the value of the AudioSource.time, maybe I solved the problem of desynchronization but I can not verify it because there is a lot of fluctuation in the time of the audio source and the character has a very unstable movement. I do not know if there is any way to soften this value as in the Time.deltaTime is smoothed with Time.smoothDeltaTime?

@jsra15 You don’t want to multiply your speed by “AudioSource.time”, but by how much “AudioSource.time” has changed since the last frame. In my example from my first post, you’ll want to multiply your speed by the “audioDeltaTime” I show you how to calculate.

Exactly, sorry for not having explained myself well, I applied the calculation you showed me in the post as it is. But I have this problem of instability of the speed of my character due to the high fluctuations that it produces. At this point is where I need to soften the output value without affecting its synchronization with the music

Strange… I’ve never seen fluctuations big enough to be noticeable. I’ll tell you how to smooth the audioDeltaTime, but that means you won’t be using the exact same time difference your audio uses, so things could get out of sync with the music.

Anyway, to turn your audioDeltaTime into a smoothAudioDeltaTime, you want to save audioDeltaTime over many frames, then use the average.

using System.Collections.Generic;

float timeLastFrame;
List<float> audioDeltaTimes = new List<float>();
float smoothAudioDeltaTime;
AudioSource source;

// Adjust this number until things feel right
int framesToSmooth = 8;

void LateUpdate()
{
    // Add the deltaTime this frame to a list
    float deltaThisFrame = source.time - timeLastFrame;
    audioDeltaTimes.Add(deltaThisFrame);
    timeLastFrame = source.time;

    // If the list is too large, remove the oldest value
    if (audioDeltaTimes.Count > framesToSmooth)
    {
        audioDeltaTimes.RemoveAt(0);
    }

    // Get the average of all values in the list
    float average = 0;
    foreach (float delta in audioDeltaTimes)
    {
        average += delta;
    }
    smoothAudioDeltaTime = average / audioDeltaTimes.Count;
}
1 Like

Great! it works almost totally perfect, of course there are moments that come out a bit of synchronicity with the tempo of the music but I think there are ways to solve it, but it is the closest thing I have obtained to an exact synchronization. I appreciate it a lot. Thank you so much!

Could you solve the problems?