Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by jdg23 · Apr 19, 2021 at 07:43 PM · nullreferenceexceptionlists

Problem with random music script

Hi, I have a problem with my music manager script, I want to play random songs that are in a list but to avoid to play them twice in a row, I add them to another list and remove them from the first one, until that one is empty,

I have an error with the line 71 NullReferenceException: Object reference not set to an instance of an object when I start the game.

Now, that list is effectively empty if the if statement is not taken into account, but the if statement should be taken into account and the list should be filled with the songs added every time a new one is played, so I don't really understand my mistake here, nor how to fix it..

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class MusicManager : MonoBehaviour
 {
     private AudioSource audioSource;
     
     //The public list containing all the songs to be played
     public List<AudioClip> musicTracksList;
     //The private, empty list that will contain the songs that have been played
     List<AudioClip> musicTracksPlayed;
 
     private void Start()
     {
         audioSource = GetComponent<AudioSource>();
         
         
     }
     
     //For the main menu, play the first track in the list / That works fine
     public void PlayMusicMainMenu()
     {
         audioSource.loop = true;
         audioSource.clip = musicTracksList[0];
         audioSource.Play();
     }
 
     //Function engaged by the Game Manager when the game starts / The RandomTrack doesn't work
     public void PlayGameMusic()
     {
 
         audioSource.clip = RandomTrack();
         audioSource.Play();
         float trackLength = audioSource.clip.length;
         StartCoroutine(NextSong(trackLength));
         
 
 
     }
 
 
 
 
 
     /*Find a random track to be played for the PlayGameMusic
      * If there are tracks in the music tracks list, pick a random one, return it as the audio clip to be played,
      * remove it from the music tracks list and add it to the played tracks list.
      * When there are no more tracks in the music track list, put all the tracks from the played tracks list in
      * the music track list and re-do the random picking with the previous steps.
      * Also, clear the played track list so it's empty again.
      * 
      * Unity says there is an error with the line 71 NullReferenceException: Object reference not set to an instance of an object */
 
     AudioClip RandomTrack()
     {
         Debug.Log("La liste principale est elle vide ? " + musicTracksList==null);
 
         if (musicTracksList.Count > 0)
         {
             int RandomTrackID = Random.Range(0, musicTracksList.Count);
             AudioClip TrackToPlay = musicTracksList[RandomTrackID];
             musicTracksList.Remove(TrackToPlay);
             musicTracksPlayed.Add(TrackToPlay);
            
             return TrackToPlay;
         }
         else
         {
             musicTracksList = musicTracksPlayed;
             musicTracksPlayed.Clear();
             int RandomTrackID = Random.Range(0, musicTracksList.Count);
             AudioClip TrackToPlay = musicTracksList[RandomTrackID];
             musicTracksList.Remove(TrackToPlay);
             musicTracksPlayed.Add(TrackToPlay);
             
             return TrackToPlay;
 
         }
 
 
     }
 
     //Coroutine to play the next track when the one playing is over.
 
     IEnumerator NextSong(float trackDuration)
     {
         yield return new WaitForSeconds(trackDuration);
         PlayGameMusic();
     }
 
     
     
 }

Thank you for your inputs.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SpaceManDan · Apr 20, 2021 at 04:20 AM 0
Share

Maybe the list isn't initialized?

Try changing

 public List<AudioClip> musicTracksList;

to

 public List<AudioClip> musicTracksList = new List<AudioClip>();
avatar image jdg23 SpaceManDan · Apr 20, 2021 at 08:22 AM 0
Share

Hi,

Thank you for your answer, so I try to do that for both my list, now I'm getting an out of range error .. ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.

I have narrow it down to that line, line 62 in my original script

 AudioClip TrackToPlay = musicTracksList[RandomTrackID];

What I don't understand, is that the RandomTrackID is a random int obtained in the line before :

 int RandomTrackID = Random.Range(0, musicTracksList.Count);

So it should not be out of range or negative like the errors says,

I've tried several things :

-if I debug.log the value of the RandomTrackID, I always get 0.

  • I copied the random part in my main menu part, this original one :

        public void PlayMusicMainMenu()
             {
                 audioSource.loop = true;
         
                 audioSource.clip = musicTracksList[0];
                 audioSource.Play();
             }
    
    
    
    
    
    

So instead of getting the track at index 0, I get a random one, it's working perfectly as intended.

If, instead of using a list, I'm using an array like I did before, it's working, but the problem is that I need to change the size of it at runtime, hence why I try to use list.

Also and I think this the most important, if in my RandomTrack method, I just remove all the ramdomness part and just say to my method to just return an audioclip at a given index that I know it exist, like this :

  AudioClip RandomTrack()
     {
 
 
 
         
         //int RandomTrackID = Random.Range(0, musicTracksList.Count);
         //Debug.Log(RandomTrackID);
         
         AudioClip TrackToPlay = musicTracksList[2];
         //musicTracksList.Remove(TrackToPlay);
         //musicTracksPlayed.Add(TrackToPlay);
 
         return TrackToPlay;
 
 
 
 
     }

It still throws me the out of range error, so now I'm wondering if it's more a problem with the return function itself ? But why would it work with arrays and not lists.....?

avatar image jdg23 SpaceManDan · Apr 20, 2021 at 08:50 AM 0
Share

Also, if I try to assign a specific index in my PlayGameMusic method just like I did in the PlayMainMenu method, it gives me the error of out of range, which is weird because the PlayMainMenu method is working fine, I tried to remove the coroutine part, it stills gives that error. I'll try later by changing list to ArrayList to see if that can solve the problem.

 //For the main menu, play the first track in the list / That works fine
     public void PlayMusicMainMenu()
     {
         audioSource.loop = true;
 
         audioSource.clip = musicTracksList[0];
         audioSource.Play();
     }
 
     //Function engaged by the Game Manager when the game starts / The RandomTrack doesn't work
     public void PlayGameMusic()
     {
 
         audioSource.clip = musicTracksList[2];
         audioSource.Play();
         float trackLength = audioSource.clip.length;
         StartCoroutine(NextSong(trackLength));
 
 
 
     }

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by jdg23 · Apr 20, 2021 at 03:21 PM

Found a solution to this issue. The first mistake was that the lists were not initialized, thanks @SpaceManDan Then, it would throw an out of range issue. That was due to not adding tracks from musicTracksPlayed to musicTrackList with a foreach loop.

It works fine now.

Here is the final script :

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class MusicManager : MonoBehaviour
 {
     private AudioSource audioSource;
     public List<AudioClip> musicTracksList = new List<AudioClip>();
     List<AudioClip> musicTracksPlayed = new List<AudioClip>();
 
 
     private void Start()
     {
         audioSource = GetComponent<AudioSource>();
     }
     public void PlayMusicMainMenu()
     {
         audioSource.loop = true;
         audioSource.clip = musicTracksList[0];
         audioSource.Play();
     }
 
     public void PlayGameMusic()
     {
 
         audioSource.clip = SetMusicToPlay();
         audioSource.Play();
         Debug.Log(audioSource.clip);
         float trackLength = audioSource.clip.length;
         StartCoroutine(NextSong(trackLength));
 
 
 
     }
 
     AudioClip SetMusicToPlay()
     {
         if (musicTracksList.Count > 0)
         {
             int trackID = Random.Range(0, musicTracksList.Count);
             AudioClip trackToPlay = musicTracksList[trackID];
             musicTracksPlayed.Add(trackToPlay);
             musicTracksList.Remove(trackToPlay);
             Debug.Log("Music Tracks Played has " + musicTracksPlayed.Count + " elements");
             Debug.Log("Music Tracks List has " + musicTracksList.Count + " elements");
             return trackToPlay;
         }
         else
         {
             Debug.Log("Engage the copy from the played track list to the track list");
             CopyToTracksList();
 
             int trackID = Random.Range(0, musicTracksList.Count);
             AudioClip trackToPlay = musicTracksList[trackID];
             musicTracksPlayed.Clear();
             musicTracksPlayed.Add(trackToPlay);
             musicTracksList.Remove(trackToPlay);
 
             Debug.Log("Music Tracks List has " + musicTracksList.Count + " elements");
 
             Debug.Log("Music Tracks Played has " + musicTracksPlayed.Count + " elements");
             return trackToPlay;
 
         }
 
 
     }
 
 
     private void CopyToTracksList()
     {
         foreach(AudioClip trackToAdd in musicTracksPlayed)
         {
             musicTracksList.Add(trackToAdd);
             
         }
     }
 
 
 
 
 
 
 
 
 
 
 
 
     IEnumerator NextSong(float trackDuration)
     {
         yield return new WaitForSeconds(trackDuration);
         PlayGameMusic();
     }
 
 
 }
 
 
Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SpaceManDan · Apr 20, 2021 at 05:33 PM 0
Share

Hey, I havn't had time to read over all the code you posted earlier but I think maybe another issue you may have been having was actually that list.count gives you the total number of items. Not the exact index.

For example:

 public List<int> myList = new List<int>();
 void Start()
 {
     myList.Add(1);
     myList.Add(2);
     myList.Add(3);

     print(myList.Count);
 }

The result will be 3 however the index is like so... index 0 = 1, index 1 = 2, index 2 = 3. For example try printing myList[3] (which would actually be the 4th entry because zero counts as one unit.) You will get the OurOfRange exception. This was an issue the greeks ran into and then invented zero to solve the problem. Wikipedia Zero

So when using List.Count you need to subtract 1 most of the time to get the right index. It all depends on how you query the list as if your query index follows the same architecture you wont have an issue.

so an example to avoid this would look like this,

 if(myList.count - 1 == indexImLookingFor)
 { 
      Dostuff();
 }

That being said, the way you are doing it now is perfect, you load the list and query the correct index.

avatar image jdg23 SpaceManDan · Apr 21, 2021 at 11:10 PM 0
Share

Hi,

Thanks for your answer, I appreciate your help on the initialization, that solved my issue.

For the out of range, it was due to not using a foreach loop to copy the content of the second list to the first, my mistake was that I made them equal so when I cleared the second list, the first one got cleared too as they were equal. The foreach loop and add cleared that issue.

There is no need to put a -1 when using Random.Range with int as with int , the max is exclusive, that's why I did not put it.

My best and thanks again for your help

avatar image SpaceManDan jdg23 · Apr 22, 2021 at 02:03 AM 0
Share

Indeed, glad you already knew about inclusive/exclusive and glad you got your lists worked out.

Good luck out there.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

162 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Having troubles using List 1 Answer

Getting "object reference not set" error when creating a list dictionary. 1 Answer

List returns NullReferenceException, but when it's visible in the Inspector it works perfectly ??? 1 Answer

How to check if gameobject has a tag, from a list. 1 Answer

Value seems to be spontaneously changing 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges