2
votes

In my game I am creating in unity I am trying to play an audio clip every time that a collision happens on one of my game objects. For some reason the audio will play the first time there is a collisiom, but from then on it no longer plaus the sound.

The game object that is collided with has a component for the AudioSource and I have the audio clip selected in that component.

Here is the code where I start the audio:

if (PlayerPrefs.GetInt ("Sound Playing", 1) == 1)
{
    audio = GetComponent <AudioSource>();
    audio.Play ();
}

I have also tried using the PlayOneShot () method but it does the same thing.

EDIT

Here is a small representation what of my game is doing here:

public class Ship : MonoBehaviour 
{
    void OnTriggerEnter2D(Collider2D collider)
    {
        Laser laser = collider.gameObject.GetComponent<Laser> ();
        if (laser) 
        {
            if (!immune)
            {
                //update healthbar
                healthbar.hit();

                //reset health boost
                forcefield.resetHealthBoost();


                health -= laser.getDamage(); //remove health from ship

                //create explosion
                GameObject explosion = Instantiate(explode, gameObject.transform.position, Quaternion.identity) as GameObject;
                explosion.GetComponent<ParticleSystem>().startColor = this.GetComponent<SpriteRenderer>().color;

                if (SoundEffects.soundOn && PlayerPrefs.GetInt("Sound Playing", 1) == 1) 
                {
                    audio = GetComponent<AudioSource>();
                    audio.Play();
                }
            }

            laser.hit();//destroy the laser that hit the ship
        }
    }
}

Here is to show that I have the AudioSource and the AudioClip setup in the inspector (the AudioSource is attached to the ship):

enter image description here

3
Check if the code (the audio.Play() in particular) is being reached atleast two times by adding some debug statements. Maybe also try to call audio.Stop() first before doing audio.Play(), or have some additional logic for when the audio is currently being played. You should also observe the AudioSource component in the Unity Inspector to see if anything strange happens (component gets destroyed, clip is lost,..) - Maximilian Gerhardt
@MaximilianGerhardt I have tried debug statements and it does get in the statement two times. Also I have tried using audio.Stop() if the audiosource is not null and that did nothing. Also nothing seems to be going wrong in the inspector. The clip doesn't get removed from the audio source or anything. - sabo
Unable to reproduce. I have created a minium project with a cube that has a box collider with this script attached: pastebin.com/djVdf769 (it has the same logic as your script). I trigger the collision with an FPSController. The cube has a AudioSource component with a clip attached. The sound triggers indeed over and over again, each time I collide. So as long as something doesn't magically destroy the AudioListener on your camera, or the clip is muted, I have no idea what's wrong. Can you provide your project / a minimal setup sothat it can be reproduced? - Maximilian Gerhardt

3 Answers

1
votes

The issue with my game was that I didn't realize that using gameobject.SetActive(false) later in my code was stopping the second audio clip from being able to play. I set it to false when the ship was destroyed and this is what the problem was all along. It works fine now.

0
votes

It's looks with audio it's all right. May be problem is in collisions or something else. Add code Debug.Log("Play sound."); before code line audio.Play();, and test.

0
votes

Make sure your audio listener is near the explosion too. It could be far away and may not be heard. Also do a check to see if audio.isPlaying, then play audio. Audio may be still playing and you have to stop it properly.

   if (audio.isPlaying) {
    audio.Stop();       
    audio.Play();
   }

If all else fails you can always do PlayOneShot(), which will essentially do as it says. audio.PlayOneShot(); This could be problematic though since if you are putting it OnTriggerEnter() it may run more than once in a short duration. You may hear it stutter because it's queued up however many explosions.

Finally, don't use PlayerPrefs for those specific things. You should reserve it honestly for Game Specific data storage. Why can't you simply use isPlaying? PlayerPrefs will only make the task very convoluted. I learned it the hard way when I used to use PlayerPrefs to transfer data from C# to UnityScript. In the end it's almost best to use Static Variables, or create a Singleton class and commit values to various instances. Plus I learned that I can use methods and variables cross languages when I adjust the compilation order(s). A little bit off topic, but still substantially important.