Search Unity

Audio Playing Audio Clip Once

Discussion in 'Audio & Video' started by F1ghter16, Jul 3, 2019.

  1. F1ghter16

    F1ghter16

    Joined:
    Apr 16, 2019
    Posts:
    13
    I'm working on a game that will play a sound when the player collects a crystal. I've tried using the PlayOneShot line to make it play only once but that doesn't seem to work. The only time I get a sound is when it is in the update function, but that just keeps looping it. I've attached the code to this post for your convenience. Thanks in advance!
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5.  
    6. public class GameManager : MonoBehaviour
    7. {
    8.  
    9.     public GameObject player;
    10.     public GameObject gameOverMenu;
    11.     public GameObject levelCompleteMenu;
    12.     public GameObject crystal;
    13.  
    14.     //The following three objects are for the sound I want to play
    15.     public GameObject collectable;
    16.     public AudioClip coinCollect;
    17.     public AudioSource collectableSound;
    18.  
    19.     // Start is called before the first frame update
    20.     void Start()
    21.     {
    22.      
    23.     }
    24.  
    25.     // Update is called once per frame
    26.     void Update()
    27.     {
    28.         if(player == null)
    29.         {
    30.             //Restart();
    31.             gameOverMenu.SetActive(true);
    32.         }
    33.  
    34.         if(crystal == null)
    35.         {
    36.             levelCompleteMenu.SetActive(true);
    37.         }
    38.     }
    39.  
    40.     void Restart()
    41.     {
    42.         SceneManager.LoadScene("LevelOne");
    43.     }
    44.  
    45.     //This function is for the sound that I am trying to play
    46.     void Collectable()
    47.     {
    48.         if(collectable == null)
    49.         {
    50.         collectableSound.PlayOneShot(coinCollect);
    51.         }
    52.     }
    53. }
    54.  
     
  2. Telkir

    Telkir

    Joined:
    Jul 23, 2013
    Posts:
    2
    Well, your Collectable() method isn't being called by anything in the code you gave, so that's why it won't trigger the sound. As you found out already, putting it in Update() will work, but after the collectable is picked up it will always be null which means the sound gets played each frame. I can suggest a couple of options -

    For the way you have it set up, the fix would be to add a bool levelComplete; flag to your class variables, then adjust your Collectable() method like so:

    Code (CSharp):
    1.     //This function is for the sound that I am trying to play
    2.     void Collectable()
    3.     {
    4.         if(collectable == null && levelComplete == false)
    5.         {
    6.             collectableSound.PlayOneShot(coinCollect);
    7.             levelComplete = true;
    8.         }
    9.     }
    Then if you call Collectable() inside Update(), you should have the sound play only once immediately as the crystal is picked up. You just need to reset levelComplete back to false when you move to a new level.

    Possibly a more efficient way of doing it is to play the sound effect at the same point you handle the collision that collects and destroys the crystal object. Assuming you have a script on your player object that is handling the collision checks against the collectable, you can move the AudioClip and AudioSource in there and play it inside OnTriggerEnter() or OnCollisionEnter() method - whichever you're using.

    Hope this helps!
     
  3. F1ghter16

    F1ghter16

    Joined:
    Apr 16, 2019
    Posts:
    13
    Thanks Telkir for the instructions! It worked like a charm.