Music Player in Unity 5

I’m using Unity 5, and I’ve changed the code in order to let it work, since OnLevelWasLoaded is deprecated on this version.

My problem is this: the code works, the clips are loaded and played correctly in every game scene as expected, but, after the first entire loop of scenes (Start, Game, Win), I get this error in the console at every other scene change (yes, the music player actually still changes clips and plays them with no issues whatsoever).

NullReferenceException: Object reference not set to an instance of an object
MusicPlayer.OnSceneLoaded (Scene scene, LoadSceneMode loadscenemode) (at Assets/Entities/General/MusicPlayer.cs:27)
UnityEngine.SceneManagement.SceneManager.Internal_SceneLoaded (Scene scene, LoadSceneMode mode) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/SceneManagerBindings.gen.cs:198)

In particular, I noticed that I get this error every time (after the first loop ofc) the code tries to access the music object (i.e. music.Stop(), music.clip, etc.) and that, moreover, I don’t really the music.Stop() method, the new clip starts to play stopping itself the old one.

My code for the Music Player script is as follows:

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class MusicPlayer : MonoBehaviour {

    static MusicPlayer instance = null;

    public AudioClip startClip;
    public AudioClip gameClip;
    public AudioClip endClip;

    private AudioSource music;

    void Awake () {        
        if (instance != null && instance != this) {
            Destroy (gameObject);
        } else {
            instance = this;
            GameObject.DontDestroyOnLoad (gameObject);
            music = GetComponent<AudioSource>();
        }
        SceneManager.sceneLoaded += OnSceneLoaded;

    }

    void OnSceneLoaded (Scene scene, LoadSceneMode loadscenemode){
        //music.Stop ();
        if (scene.buildIndex == 0) {
            music.clip = startClip;
        }
        if (scene.buildIndex == 1) {
            music.clip = gameClip;
        }
        if (scene.buildIndex == 2) {
            music.clip = endClip;
        }
        music.loop=true;
        music.Play();
    }
}

Any help in order to shed some light on that console error will be very appreciated! :smiley:

1 Like

This usually means that the inspector needs a reference to the object of the music player and it cant find it.
I think that its destroying the game object regardless of if its this instance or not so when it gets to the else there is no musicplayer object at all.
Hopefully someone will correct me or explain better than i have maybe @Rob as he knows unity and c# a LOT better than me :slight_smile:

2 Likes

I suspect the null reference exception error is being created by a method call to the delete music player object, rather than to the already instantiated (singleton) instance.

The reason the music still plays correctly is because it is being played by the instantiated music player (the one that didn’t get deleted)

Just to check, when you say every other scene change do you mean that literally, e.g. on the 1st change, but not the 2nd, then again on the 3rd, or was that just figurative, and it’s actually happening on every scene change?

If I had to guess I would suggest you have the MusicPlayer on each scene?

2 Likes

Yes, @Rob, I had the same suspicion since the exception was called the first time the code tries to access the music object.

And I found the mistake and was able to correct it: the delegate must be assigned inside the else code of the Awake function, that’s it.

This way, the code doesn’t try to access the music object inside the 2nd instance of the Music Player, which is immediately destroyed on creation, thus not finding the former while calling the delegate method (and stopping the execution of the whole method as soon as it first tries to access to the music object).

So, the correct code of the Awake method in Unity 5 is this:

void Awake () {

        if (instance != null && instance != this) {

            Destroy (gameObject);

        } else {

            instance = this;

            GameObject.DontDestroyOnLoad (gameObject);

            music = GetComponent<AudioSource>();

            SceneManager.sceneLoaded += OnSceneLoaded;

        }

    }

Thanks to both of you for the help!

Edit: I’ll tag @ben too if he wants to add this info regarding the sceneLoaded delegate in the episode.

2 Likes

Hi @Galandil, you’re more than welcome, and well done on finding your solution :slight_smile:

1 Like

Hi there, the think about talking about starting to update to Unity 5 is that once we start the whole course needs re-writing.

At the moment the official line is use the recommended version of Unity for that stage in the course, and if you want to venture with a more recent version there’s plenty of fantastic community support thanks to you guys.

1 Like

I am also doing this in Unity 5 and I am getting the same error, was anyone able to fix this yet ?

EDIT:

In case someone else comes here, this is the soluction:

MusicPlayer script:

private AudioSource music;

to this:

private static AudioSource music;

2 Likes

I had similar behavior in Unity 4.6…that is the game starts and start screen music plays, go to game screen and game screen music plays, go to end screen and endscreen music plays, play again and it says the OnLevelWasLoaded int was null. changing the private AudioSource music to static resolved it.

1 Like

4 posts were split to a new topic: NullReferenceExceptions, Singletons and Delegates

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

Privacy & Terms