在我的项目中,我想要播放声音,然后将对象的活动状态设置为 false,目前两者同时发生,因此声音不会播放。如果我将活动状态保持为 true,那么我会听到声音播放。
如何确保音频在设置的活动状态切换为 false 之前完成,如有任何帮助或建议,我们将不胜感激。
这是我的代码的选择;
void OnTriggerEnter(Collider other)
{
if (other.tag == "Pick Up")
{
if (!isPlayed) {
source.Play ();
isPlayed = true;
}
}
if (other.gameObject.CompareTag ("Pick Up"))
{
other.gameObject.SetActive (true);
count = count + 1;
SetCountText ();
}
}
按照 Joe 的说法使用协程。每次启用碰撞对象时启动协程。
void OnTriggerEnter(Collider other)
{
if (other.tag == "Pick Up")
{
if (!isPlayed) {
source.Play ();
isPlayed = true;
}
}
if (other.gameObject.CompareTag ("Pick Up"))
{
other.gameObject.SetActive (true);
count = count + 1;
SetCountText ();
StartCoroutine(waitForSound(other)); //Start Coroutine
}
}
IEnumerator waitForSound(Collider other)
{
//Wait Until Sound has finished playing
while (source.isPlaying)
{
yield return null;
}
//Auidio has finished playing, disable GameObject
other.gameObject.SetActive(false);
}
您可以使用其
renderer
隐藏对象,以及关闭所有碰撞器,播放声音,然后销毁/将其设置为非活动状态:
renderer.enabled = false;
gameObject.collider.enabled = false;
audio.PlayOneShot(someAudioClip);
Destroy(gameObject, someAudioClip.length); //wait until the audio has finished playing before destroying the gameobject
// Or set it to inactive
许多帖子指出使用 WaitForSeconds 以及 WaitWhile(AudioSource.isPlaying) 的问题,如果剪辑暂停、游戏失去焦点或音频音调发生改变,则会给出错误的值。
所以我相信我找到了更好的解决方案:
void OnTriggerEnter(Collider other)
{
if (other.tag == "Pick Up")
{
if (!isPlayed)
{
source.Play ();
isPlayed = true;
}
}
if (other.gameObject.CompareTag ("Pick Up"))
{
other.gameObject.SetActive (true);
count = count + 1;
SetCountText ();
StartCoroutine(waitForSound(other)); //Start Coroutine
}
}
private IEnumerator PlayAudioAndDeactivate(Collider other)
{
audioSource.clip = clip;
audioSource.Play();
yield return new WaitUntil(() => audioSource.time >= clip.length);
other.gameObject.SetActive(false); //Whatever it is that you're wanting to do.
}
通过使用 AudioSource.time 和 AudioClip.length,您可以将播放位置与剪辑的长度进行比较,这应该始终是正确的。我已经通过暂停和音调变化成功地测试了这一点。