1
\$\begingroup\$

I'm working on a rhythm based android game similar to Guitar Hero.

I have a kinematic rigidbody moving downwards with tapobjects (colliders) inside which need to be pressed when moved above the button.

The big problem: No matter what I try, I can't get the first movement of the rigidbody to be aligned with the exact start of the music. There is always a delay of around +-100ms and more.

Intialization:

void Start()
{
    velocity = beatTempo / 60f;
    startDelayedBy = 0f;
    setupAudioInputLag = false;
    firstFixedUpdate = false;
    songLag = 0.0692f;   // time in seconds when first beat occurs of the audio
    songLagStep = ( beatTempo / 60f ) * songLag; // calculate the distance of songlag on y axis
    velocityAdd = new UnityEngine.Vector3(0f, -velocity, 0f); 
}

What I tried, Example 1:

private void FixedUpdate()
{
    if (setupAudioInputLag == false)
    {
        beatMusic.PlayDelayed(1f);
        rb.position = new UnityEngine.Vector3(rb.position.x, 0f + songLagStep, rb.position.z);
        setupAudioInputLag = true;
    }
    if (startDelayedBy >= 1f) 
    {
        rb.MovePosition(rb.position + (velocityAdd * Time.fixedDeltaTime));
    }
    if (setupAudioInputLag)
    {
        startDelayedBy += Time.fixedDeltaTime;
    }
}

Example 2:

private void Update()
{
    getAccurateDspStart = AudioSettings.dspTime;
    if (setupAudioInputLag == false)
    {
        beatMusic.PlayScheduled(AudioSettings.dspTime + 1.0f);
        dspTimeStore = AudioSettings.dspTime + 1.0f;
        rb.position = new UnityEngine.Vector3(rb.position.x, 0f + songLagStep, rb.position.z);
        setupAudioInputLag = true;
    }
}

private void FixedUpdate()
{
    if (getAccurateDspStart >= (dspTimeStore) && setupAudioInputLag) 
    {
        rb.MovePosition(rb.position + (velocityAdd * Time.fixedDeltaTime));
    }
}

Example 3:

private void Update()
{
    getAccurateDspStart = Time.time;
    getAccurateDspStartOld = AudioSettings.dspTime;
}

private void FixedUpdate()
{
    accurateDspTime = getAccurateDspStartOld + (Time.time - getAccurateDspStart);
    if (accurateDspTime != 0f)
    {
        if (setupAudioInputLag == false)
        {
            beatMusic.PlayScheduled(accurateDspTime + 1.0f);
            dspTimeStore = accurateDspTime + 1.0f;
            rb.position = new UnityEngine.Vector3(rb.position.x, 0f + songLagStep, rb.position.z);
            setupAudioInputLag = true;
        }
    }
    if (accurateDspTime >= (dspTimeStore) && setupAudioInputLag)  
    {
        rb.MovePosition(rb.position + (velocityAdd * Time.fixedDeltaTime));
    }
}

Example4:

private void FixedUpdate()
{
    if (setupAudioInputLag == false)
    {
        beatMusic.PlayDelayed(1f);
        rb.position = new UnityEngine.Vector3(rb.position.x, 0f + songLagStep, rb.position.z);
        setupAudioInputLag = true;
    }
    if (beatMusic.time != 0) 
    {
        rb.MovePosition(rb.position + (velocityAdd * Time.fixedDeltaTime));
    }
}

And much more I tried over several days without even getting close. I need accuracy about 10-20ms.

Using PlaySheduled(dspTime) in start and starting movement instantly in FixedUpdate was the closest, but least reliable for some smartphones.

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

The simplest thing you can do with 0 ms delay in the result is: Create a manager that will start the music, and then run the required Start methods for all objects. For example:

[SerializeField]
List<ObjectsStarts> starts; 
public void Run()
{
    audio.Play();

    for(int i = 0; i < starts.Count(); i++)
    {
        starts.CustomStart();
    }
}
\$\endgroup\$
3
  • 1
    \$\begingroup\$ audio.Play(): unluckily does not start instantly but usually with processing delay. According docs its recommended to use audio.PlaySheduled(); \$\endgroup\$
    – delato468
    Jan 14 at 8:17
  • \$\begingroup\$ can you then await play? \$\endgroup\$
    – Bogdan
    Jan 14 at 14:01
  • \$\begingroup\$ It is not async, maybe you can try to use _audioSource.PlayOneShot() instead of Play. \$\endgroup\$
    – Bogdan
    Jan 14 at 14:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .