-2
\$\begingroup\$

Why does this not work? I'm trying to get the sound effect before the visual, but I don't hear it until I move away from the location. This is part of a routine that is called from Update on the Player. Thanks in advance for any hints.

    if (carriedObject.name == "HandTorch") {
        float d =findNearest (o.transform);
        if (d < 0.5f) {
            ASource.clip = woosh;
            ASource.Play ();
            float duration = woosh.length;
            StartCoroutine (WaitForSound (duration));
            o.transform.Find("Flame").gameObject.SetActive(true);
            o.transform.Find ("MyTorch").gameObject.SetActive (true);
        }
    }
}

public IEnumerator WaitForSound(float duration)
{
    yield return new WaitForSeconds(duration);
}
\$\endgroup\$
4
  • \$\begingroup\$ Is that from unity? \$\endgroup\$ Commented Nov 16, 2017 at 15:39
  • \$\begingroup\$ yes its from Unity. I should have put that in the title? \$\endgroup\$ Commented Nov 16, 2017 at 15:55
  • \$\begingroup\$ Generally we like to add it as a tag; you can use the edit feature at the bottom of the question to add it :) \$\endgroup\$ Commented Nov 16, 2017 at 16:07
  • \$\begingroup\$ I downvoted because no research has been made. You will find dozens of similar question using your favourite search engine \$\endgroup\$ Commented Nov 16, 2017 at 17:36

1 Answer 1

2
\$\begingroup\$

It is because what you are doing is starting the coroutine, that independently waits, and then you continue calling all the remaining stuff. What you can do is to either execute all the wanting actions inside the coroutine:

    public IEnumerator WaitForSound(float duration)
    {
        yield return new WaitForSeconds(duration);
        o.transform.Find("Flame").gameObject.SetActive(true);
        o.transform.Find ("MyTorch").gameObject.SetActive (true);
    }

You could do a more generic coroutine to wait for something, then do a certain sequence encapsulated in an Action, with a Lambda Expression:

    using System; //You must use this namespace for Actions

    void Start()
    {
        StartCoroutine(WaitForSound(duration,
        ()=>
        {
            Debug.Log("The wait ended, I shall proceed");
        }));
    }

    public IEnumerator WaitForSound(float duration, Action onWaitEnds)
    {
        yield return new WaitForSeconds(duration);
        if(onWaitEnds != null) onWaitEnds();
    }

Or you could play with AudioSource's property isPlaying which is true while it is playing:

    public IEnumerator WaitUntilAudioSourceIsPlaying(AudioSource _source, Action onSourceStopsPlaying)
    {
        while(_source.isPlaying)
        {
            yield return null;
        }

        if(onSourceStopsPlaying != null) onSourceStopsPlaying();
    }

Hope it helps.

\$\endgroup\$
0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.