audiosource.PlayOneShot not working

    void Success()
    {
        audioSource.PlayOneShot(success); // NOT WORKING
        Invoke("NextLevel", 2f);
    }

    void Crash()
    {
        Invoke("ReloadLevel", 1f);
        audioSource.PlayOneShot(collisionSound); // BUT THIS WORKS
        FreezeMovement();
    }

I’ve done the exact same thing for success sound and collision sound but only collision is working. I’ve checked my inspector everything is attached.

here is how i cached

[SerializeField] AudioClip collisionSound;
[SerializeField] AudioClip success;

AudioSource audioSource;

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

Hi Varun,

Welcome to our community! :slight_smile:

Comment out the line with Invoke to see if you are able to hear the sound. If you are, increase the delay value. 2 seconds might be too short.


See also:

Still not working :frowning:
Been trying to fix it for the past hour still can’t figure it out.
I interchanged the audio clip now it success sound works in the Crash() method, and the collision sound stopped working in the Success() method. Seems like there is something wrong with Success() method, no audio clip works in that code block.

Here’s the full script for reference

using UnityEngine;
using UnityEngine.SceneManagement;

public class CollisionHandler : MonoBehaviour
{
[SerializeField] AudioClip collisionSound;
[SerializeField] AudioClip success;

AudioSource audioSource;

void Start()
{
    
    audioSource = GetComponent<AudioSource>();
}
void OnCollisionEnter(Collision collision)
{
  
    switch (collision.gameObject.tag)
    {
        case "StartingPad":
            Debug.Log("launch Pad");
            break;

        case "FinishPad":
            Debug.Log("this is working");
            Success();
            break;
        default:
            Crash();
            break;

    }

    void Success()
    {
        audioSource.PlayOneShot(success);
        
        Invoke("NextLevel", 2f);
    }

    void Crash()
    {
        Invoke("ReloadLevel", 1f);
        
        audioSource.PlayOneShot(collisionSound);
        FreezeMovement();
    }
}

When you freeze movement, are you doing anything to stop your main engine thrusting sound?

Nope I’m just disabling the movement script and setting rigidbody.isKinematic = true so it stops at the place of collision rather than falling down.
The thruster sound automatically stops when I stop holding space.

Are you sure about that? I think it’s a good idea to test Anthony’s theory. Comment out the code thrusting sound code.

Also try to play the collisionSound in the Suceess method. Maybe the problem is just caused by the success sound clip. Both variables have got a clip assigned in the Inspector, haven’t they?

Tried commenting out thrusting sound still did not work.
Tried playing collisionSound in success method. Didn’t work. But success sound worked in crash method instead.
I’ve checked the inspector all the clips are assigned.

void Success()
{

        Invoke("NextLevel", 2f);
        audioSource.PlayOneShot(collisionSound); // THIS IS NOT WORKING
       
    }

    void Crash()
    {
        Invoke("ReloadLevel", 1f);
        
        audioSource.PlayOneShot(success);  // NOW THIS WORKS
        FreezeMovement();
    }


private void FreezeMovement()
{
    GetComponent<Movement>().enabled = false;
    GetComponent<Rigidbody>().isKinematic = true;
  
}

Added FreezeMovement() method to success method after PlayOneShot() line now it works!
But still don’t understand why did it not work without it.

That sounds indeed weird. Could you please share your entire script?


See also:

Here is the CollisionHandler script-

using UnityEngine;
using UnityEngine.SceneManagement;

public class CollisionHandler : MonoBehaviour
{
[SerializeField] AudioClip collisionSound;
[SerializeField] AudioClip success;

AudioSource audioSource;

void Start()
{
    
    audioSource = GetComponent<AudioSource>();
}
void OnCollisionEnter(Collision collision)
{

    switch (collision.gameObject.tag)
    {
        case "StartingPad":
            Debug.Log("launch Pad");
            break;

        case "FinishPad":
            Debug.Log("this is working");
            Success();
            break;
        default:
            Crash();
            break;

    }
}

    void Success()
    {
       
        Invoke("NextLevel", 2f);
        audioSource.PlayOneShot(success);
        FreezeMovement();
    }

    void Crash()
    {
        Invoke("ReloadLevel", 1f);
        
        audioSource.PlayOneShot(collisionSound);
        FreezeMovement();
    }


private void FreezeMovement()
{
    GetComponent<Movement>().enabled = false;
    GetComponent<Rigidbody>().isKinematic = true;
  
}

void ReloadLevel()
{
    SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}

void NextLevel()
{
    int totalLevels = SceneManager.GetActiveScene().buildIndex + 1;
    if (SceneManager.sceneCountInBuildSettings == totalLevels)
    {
        totalLevels = 0;
    }
    SceneManager.LoadScene(totalLevels);
}

}

Here is the movement script-

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement : MonoBehaviour
{
Rigidbody rocket;
[SerializeField] float thrustPower = 10f;
[SerializeField] float rotationSpeed = 5f;
[SerializeField] AudioClip mainEngine;

AudioSource audioSource;
void Start()
{
    rocket = GetComponent<Rigidbody>();
    audioSource = GetComponent<AudioSource>();
}

// Update is called once per frame
void Update()
{
    ProcessThrust();
    ProcessRotate();
}

private void ProcessThrust()
{
    if (Input.GetKey(KeyCode.Space))
    {
        rocket.AddRelativeForce(Vector3.up * thrustPower * Time.deltaTime);
        if (!audioSource.isPlaying)
        {
            audioSource.PlayOneShot(mainEngine);
        }

    }
    else
    {
        audioSource.Stop();
    }
}

private void ProcessRotate()
{
    if (Input.GetKey(KeyCode.A))
    {
        Rotation(rotationSpeed);
    }

    if (Input.GetKey(KeyCode.D))
    {
        Rotation(-rotationSpeed);
    }
}

private void Rotation(float rotationThisFrame)
{

    rocket.freezeRotation = false;
    
    transform.Rotate(Vector3.forward * rotationThisFrame * Time.deltaTime);
   
    rocket.freezeRotation = true;
}

}

Does “this is working” appear in your console when you expect the Success method to be called?

Also I cannot see any Debug.Logs or commented out code. Unfortunately, it is impossible to tell what’s going on during runtime by staring at the code.

My guess is that by disabling the Movement component, audioSource.Stop();` does not get executed anymore. If the Movement component remains enabled, Update() continues getting called each frame. That’s just a guess, though. As aforementioned, it is impossible to tell what’s going on during runtime just by reading the code. Logging messages into the console can help verifying assumptions.

“This is working” does appear on the console. I’ll figure it out. Thanks for the help!

Yes, it seems pretty clear both scripts are calling on the same audio source at different times.

During the physics step, the collision handler is trying to play a sound when a collision occurs.

But the movement script will change the audiosource immediately on update, either changing it to play an engine sound or stop altogether. Either way, there’s no time to play the collision sound.

Your FreezeMovement() method happens during the physics step, before the next Update() cycle can occur, preventing this from happening.

Two other solutions that would likely work:

The collision handler can use AudioSource.PlayClipAtPoint instead. This will play the sound once, creating a temporary audio source for the file to use so it won’t have to use the ship’s audio source. This gives less control (can’t adjust the volume and pitch and stuff) but is great for collision, impact, and death sounds so you can do whatever you want to the main player object and the sound won’t be affected.

The other solution would be to place your movement script on a child object with its own AudioSource so the two scripts don’t have to share the same AudioSource. The child object could be called “Engines” or something. Some of the references in the script may have to be changed.

(Personally, I like to keep an audio source dedicated to one sound effect when I can, but often represent effects with temporarily created objects that often have their own audio source and particle system, and a small script.)