当对象被销毁时,audio.play()无法正常工作

时间:2015-12-04 16:24:17

标签: c# audio unity3d

我试图在GameObject被摧毁时播放声音。然而声音不会播放。我已经尝试过这种方式并将音频片段分配给变量,但似乎都不起作用。如果我将声音设置为在唤醒时播放它会在GameObject产生时播放,所以我知道声音片段有效 - 但它在被破坏时不会播放。

using UnityEngine;
using System.Collections;

public class DestroyByContact : MonoBehaviour {

    public GameObject explosion;
    public GameObject explosion02;
    public GameObject explosionShot;
    public int scoreValue;
    public GameController gameController;
    public int health;
    public AudioClip explosionSound01;

    void start () {
    }

    void Update () {
        if (health <= 0) {
            this.gameObject.GetComponent<AudioSource> ().Play ();
            Instantiate(explosion, transform.position, transform.rotation);
            Instantiate(explosion02, transform.position, transform.rotation);
            GameObject gc = GameObject.Find ("GameController");
            GameController gcs = gc.GetComponent<GameController> ();
            gcs.AddScore (scoreValue);
            Destroy(gameObject);
        }

        if (this.gameObject.tag == "Asteroid") {
            if (this.gameObject.transform.position.x  < -16) {
                Destroy (gameObject);
                Destroy (transform.parent.gameObject);
            }
        }
    }

    void OnTriggerEnter2D(Collider2D other){
        if (other.tag == "Boundary") {
            return;
        }
        if (other.tag == "Asteroid") {
            return;
        }
        if (other.tag == "Player") {
            Instantiate(explosion, transform.position, transform.rotation);
            Instantiate(explosion02, transform.position, transform.rotation);
            Destroy (gameObject);
        }
        if (other.tag == "Bullet") {
            Instantiate(explosionShot, transform.position, transform.rotation);
            other.gameObject.GetComponent<AudioSource> ().Play ();
            health -= 10;
            GameObject gc = GameObject.Find ("GameController");
            GameController gcs = gc.GetComponent<GameController> ();
            gcs.AddScore (10);
            Destroy (other.gameObject);
        }
    }
}

4 个答案:

答案 0 :(得分:2)

将其简化为基本线,我们只剩下两个:

this.gameObject.GetComponent<AudioSource>().Play();
Destroy(gameObject);

销毁GameObject也会破坏附加到它的任何组件。你已告诉AudioSource玩,然后立即将其摧毁。一旦它被摧毁,它就不再存在,因此无法播放任何声音。

为了避免这种情况,你可以创建一个单独的GameObject来包含一个播放声音的AudioSource,然后在声音完成后将其销毁。

Unity实际上有一个辅助函数AudioSource.PlayOneShot,就是这样做的:

[RequireComponent(typeof(AudioSource))]
public class ExampleClass : MonoBehaviour {
    public AudioClip impact;
    AudioSource audio;

    void Start() {
        audio = GetComponent<AudioSource>();
    }

    void OnCollisionEnter() {
        audio.PlayOneShot(impact, 0.7F);
    }
}

如果您需要更多控制权,可以创建和管理自己的GameObject,可能是instantiating a prefab

public class ExampleTwoClass : MonoBehaviour {
    public AudioSource audioPrefab;

    void OnCollisionEnter() {
        GameObject clone = Instantiate(audioPrefab, transform.position, transform.rotation) as GameObject;
        AudioSource cloneAudio = clone.GetComponent<AudioSource>();
        cloneAudio.play();

        //destroy clone once audio finishes
        Destroy(clone, cloneAudio.clip.length + 0.1f);
    }    
}

答案 1 :(得分:1)

嗯,你正试图在上播放声音的游戏对象正在被破坏,因此音频源将随之被破坏。

您必须为要附加的音频源创建一个空的游戏对象,放置在被破坏的对象的位置,并在声音效果结束后销毁该游戏对象。或者另一个类似的解决方案,取决于您的确切需求(Destroy有一些开销,因此使用池化系统会改变答案)。

答案 2 :(得分:1)

您可以轻松地将脚本更改为工作,您只需要使用Destroy(GameObject,float)方法而不是Destroy(Gameobject)。 这是一个方便的解决方案。

if (health <= 0) {
            this.gameObject.GetComponent<AudioSource> ().Play ();
            Instantiate(explosion, transform.position, transform.rotation);
            Instantiate(explosion02, transform.position, transform.rotation);
            GameObject gc = GameObject.Find ("GameController");
            GameController gcs = gc.GetComponent<GameController> ();
            gcs.AddScore (scoreValue);
            Destroy(gameObject,1f);// here use time parameter.
        }

分配取决于你的音乐时间,如果你的利用声音1秒然后分配时间Destroy(gameObject,1.25f)。

答案 3 :(得分:0)

您可以使用此静态方法:

AudioSource.PlayClipAtPoint(soundClip, Camera.main.transform.position); 
Destroy(gameObject);

要从检查器设置声音片段,请将成员添加到类:

[SerializeField]
private AudioClip soundClip;