Search Unity

Audio problem solved, but I've no idea why!!

Discussion in 'Scripting' started by olidadda, Dec 9, 2019.

  1. olidadda

    olidadda

    Joined:
    Jul 27, 2019
    Posts:
    37
    I’ve figured out that PlayOneShot doesn’t work for collision sounds via OnCollisionEnter function if you have OTHER audioclips going through Update in a separate Audio function activated by user input via if statements. In this scenario, only input sounds will play.

    Instead if I move the call to the Audio function away from update and into the input functions (which refer to Update anyway) it works… WHYYYY???

    that makes no sense to me o_O


    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.SceneManagement;
    3.  
    4. public class Rocket : MonoBehaviour
    5. {
    6.  
    7.     //Member variables
    8.     Rigidbody rigidBody;
    9.  
    10.     [SerializeField] AudioClip Engine;
    11.     [SerializeField] AudioClip Rotate;
    12.     [SerializeField] AudioClip Die;
    13.     [SerializeField] AudioClip winLevel;
    14.     AudioSource audioSource;
    15.    
    16.    
    17.     [SerializeField] float rcsThrust = 220f;
    18.     [SerializeField] float mainThrust = 50f;
    19.     [SerializeField] float upThrust = 50f;
    20.  
    21.     bool wonLevel = false;
    22.     bool died = false;
    23.  
    24.  
    25.     enum State {alive, dying, transcending};
    26.     State state = State.alive;
    27.  
    28.     //[SerializeField] float rotateForce = 20f;
    29.  
    30.     // Start is called before the first frame update
    31.     void Start()
    32.     {
    33.         rigidBody = GetComponent<Rigidbody>();
    34.         audioSource = GetComponent<AudioSource>();
    35.                
    36.     }
    37.  
    38.     // Update is called once per frame
    39.     void Update()
    40.     { if (state == State.alive)
    41.         {
    42.             ThrustShip();
    43.             RotateShip();
    44.            
    45.         }
    46.  
    47.         //Audio();    //IF I CALL AUDIO FUNCTION FROM HERE,
    48.                             // THE "DIE" AND "WINLEVEL" SOUNDS WON'T PLAY
    49.  
    50.     }
    51.  
    52.     private void ThrustShip()
    53.     {
    54.         if (Input.GetKey(KeyCode.Space) )
    55.         {
    56.             rigidBody.AddRelativeForce(Vector3.up * mainThrust);
    57.             rigidBody.AddForce(Vector3.up * upThrust);
    58.             Audio();   //INSTEAD IF I CALL AUDIO FROM HERE EVERYTHING WORKS
    59.         }
    60.                
    61.     }
    62.     private void RotateShip()
    63.     {
    64.         rigidBody.freezeRotation = true;
    65.  
    66.  
    67.         float rotationThisFrame = rcsThrust * Time.deltaTime;
    68.  
    69.         if (Input.GetKey(KeyCode.A))
    70.         {
    71.  
    72.             transform.Rotate(Vector3.forward * rotationThisFrame);
    73.  
    74.         }
    75.         else if (Input.GetKey(KeyCode.D))
    76.         {
    77.             transform.Rotate(-Vector3.forward * rotationThisFrame);
    78.  
    79.         }
    80.  
    81.         rigidBody.freezeRotation = false;
    82.         Audio();  //FROM HERE WORKS TOO
    83.     }
    84.  
    85.  
    86.     void OnCollisionEnter(Collision collision)
    87.     {
    88.  
    89.         if (state != State.alive)
    90.  
    91.         {
    92.             return;
    93.         }
    94.  
    95.  
    96.         switch (collision.gameObject.tag)
    97.         {
    98.             case "Friendly":
    99.                 //do nothing
    100.                 break;
    101.  
    102.             case "Finish":
    103.                 state = State.transcending;
    104.                              
    105.                 audioSource.Stop();
    106.                 audioSource.PlayOneShot(winLevel);
    107.                 Invoke("LoadNextScene", 5f);
    108.                 break;
    109.  
    110.             case "Untagged":
    111.                 state = State.dying;
    112.                                
    113.                 print("playaudio");
    114.                 audioSource.Stop();
    115.                 audioSource.PlayOneShot(Die);  
    116.                 Invoke("LoadStartScene", 5f);
    117.                 break;
    118.  
    119.  
    120.         }
    121.     }
    122.  
    123.     private void LoadStartScene()
    124.     {
    125.         SceneManager.LoadScene(0);
    126.     }
    127.  
    128.     private void LoadNextScene()
    129.     {
    130.         SceneManager.LoadScene(1);
    131.     }
    132.  
    133.  
    134.  
    135.    
    136.    
    137.    
    138.    
    139.    
    140.    
    141.    
    142.     void Audio()
    143.     {
    144.         if (Input.GetKey(KeyCode.Space) && state == State.alive && !audioSource.isPlaying)
    145.         {
    146.            
    147.             audioSource.PlayOneShot(Engine);
    148.         }
    149.  
    150.          if (Input.GetKeyUp(KeyCode.Space) ||  state == State.dying || state == State.transcending)
    151.         {
    152.             audioSource.Stop();
    153.         }
    154.  
    155.  
    156.  
    157.  
    158.  
    159.        /* if (died == true && !audioSource.isPlaying )
    160.         {
    161.  
    162.             print("dead");
    163.             audioSource.Stop();
    164.             audioSource.PlayOneShot(Die);          
    165.             died = false;
    166.            
    167.         }*/
    168.  
    169.         if (Input.GetKeyDown(KeyCode.A) && state == State.alive)
    170.         {
    171.             audioSource.PlayOneShot(Rotate);
    172.         }
    173.  
    174.         if (Input.GetKeyDown(KeyCode.D) && state == State.alive)
    175.         {
    176.             audioSource.PlayOneShot(Rotate);
    177.         }
    178.  
    179.  
    180.        /* if (wonLevel == true && !audioSource.isPlaying)
    181.  
    182.         {
    183.             audioSource.PlayOneShot(winLevel);
    184.             wonLevel = false;
    185.                      
    186.         }*/
    187.  
    188.  
    189.  
    190.     }
    191.  
    192. }
    193.  
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    In your non-working scenario, it's outside the "if (state == State.alive)" if statement. In the working scenarios, it's inside that "if". That's the important difference.
    You could call Audio() at line 44 here and it should work.
     
    olidadda likes this.
  3. olidadda

    olidadda

    Joined:
    Jul 27, 2019
    Posts:
    37
    That actually works, but I don't understand how it affects the audio played from the OnCollisionEnter and NOT the audio that depends directly or indirectly from the update function.
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    It doesn't matter when the audio started. It matters whether that is being run every frame because if it's being run every frame it has a chance to interrupt whatever is playing. Most likely lines 150-152 would cause it to be interrupted.