Null AudioClip error after landing and crashing

My code works more or less as expected, but if I land on the finish pad and crash at the same time (right on the edge or fall over), the next level is loaded WITHOUT the saved audioClips in the variables and returns a null AudioClip error. How do I make sure that they stay?

using UnityEngine;

using UnityEngine.SceneManagement;

public class CollisionHandler : MonoBehaviour

{

AudioSource audioSource;

[HideInInspector] public int currentSceneIndex;

[SerializeField] private float delaySec = 1.5f;

//controls crash sound and volume

[SerializeField] private AudioClip crashSound;

[SerializeField] private float crashVol = 0.1f;

//victory sound and volume

[SerializeField] private AudioClip victorySound;

[SerializeField] private float victoryVol = 0.8f;

void Start() {

    audioSource = GetComponent<AudioSource>();

    if (audioSource == null) audioSource = gameObject.AddComponent<AudioSource>();

}

private void OnCollisionEnter(Collision other)

{

    switch (other.gameObject.tag) // checks the collided object's tag

    {

        case "Friendly":

            Debug.Log("Safe!");

            break;

        case "Finish":

            Debug.Log("Finished!");

            StartSuccess();

            break;

        case "Boost":

            Debug.Log("Boost!");

            break;

        case "Boundary":

            Debug.Log("Wall!");

            break;

        default:

            Debug.Log("Hit!");

            startCrash();

            break;

    }

}

private void StartSuccess()

{

    // add SFX and particles

    audioSource.PlayOneShot(victorySound, victoryVol); // plays the sound and volume from the audioSource component

    GetComponent<PlayerMovement>().enabled = false;

    Invoke(nameof(loadLevel), delaySec);

}

private void startCrash() {

    // add SFX and particles

    audioSource.PlayOneShot(crashSound, crashVol);

    GetComponent<PlayerMovement>().enabled = false; //disables player movement script

    Invoke(nameof(ReloadLevel), delaySec); // no longer reliant on string

}

Looking at your code, only one of the collision things can happen in a frame. However, depending on the load delay, it is still possible for a second one to happen while the delay is running. The first thing is to prevent other collisions from triggering once you have crashed or landed. You can do this by simply setting a flag in the “Finish” and default cases. Then, if the flag is set, don’t process any further collisions.

private bool alreadyProcessed = false;

private void OnCollisionEnter(Collision other)
{
    if (alreadyProcessed) return;
    switch (other.gameObject.tag) // checks the collided object's tag
    {
        case "Friendly":
            Debug.Log("Safe!");
            break;
        case "Finish":
            Debug.Log("Finished!");
            StartSuccess();
            alreadyProcessed = true;
            break;
        case "Boost":
            Debug.Log("Boost!");
            break;
        case "Boundary":
            Debug.Log("Wall!");
            break;
        default:
            Debug.Log("Hit!");
            startCrash();
            alreadyProcessed = true;
            break;
    }
}

There doesn’t seem to be anything wrong in the code to cause the issue you described. The only thing I can think of is that the next level doesn’t have the audio clips defined. If this is in a prefab, make sure the clips were assigned in the prefab and not in the level. If they were assigned in the level, they are only for that level. You can go to the prefab overrides (at the top right) and apply them to the prefab. This will then save the clips to the prefab instead of the scene.

Then, just an observations - which you are free to ignore:
You add an AudioSource in the Start method if you cannot find one. You don’t really need to do this. If you put a [RequireComponent(typeof(AudioSource))] above the class, Unity will ensure that there is an AudioSource on the game objects as soon as you add the CollisionHandler, or warn you that it is not there before you play the game. It will look like this

using UnityEngine;
using UnityEngine.SceneManagement;

[RequireComponent(typeof(AudioSource))]
public class CollisionHandler : MonoBehaviour
{
    // Class content here
}

See the documentation here:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms