Search Unity

Stop playing music after loading a specific scene.

Discussion in 'Audio & Video' started by Archozalol, Mar 31, 2017.

  1. Archozalol

    Archozalol

    Joined:
    Nov 19, 2016
    Posts:
    11
    Right now I managed to make it work so that music keeps playing when I'm changing between scenes, but I have no idea how to make sure that it doesn't load the music again when entering the same scene.

    Right now I put the BackgroundMusic audio file with the script on MainMenu scene, and everything is working good, but when I go back to MainMenu scene via "Back to Main Menu" button, it starts the music again.

    Can anyone tell me what am I supposed to do? Is there a single command line that I have to put in the button void to make sure it doesn't start the music again?

    Thank you.
     
  2. jerotas

    jerotas

    Joined:
    Sep 4, 2011
    Posts:
    5,572
    Let's see your code for starting the music. Sounds like you have the Audio Source in a "don't destroy" game object right?
     
  3. Archozalol

    Archozalol

    Joined:
    Nov 19, 2016
    Posts:
    11
    Sorry for the late reply, i've been pretty busy!
    So, for starting the music, there's not really any code, I just made a empty game object, and gave it a sound component, and put in a music so it would play once the game has started and the window is open.

    The Script is very simple, it's just this

    using UnityEngine;
    using System.Collections;

    public class AudioManager : MonoBehaviour {

    public AudioSource BGM;

    void Start () {
    DontDestroyOnLoad (gameObject);

    }
    }

    And then I placed this script inside the sound object so it would understand not to be destroyed once I change the scenes.

    Is this the correct info I gave you?
     
  4. jerotas

    jerotas

    Joined:
    Sep 4, 2011
    Posts:
    5,572
    Ok, I think you need to do this:

    1) Add code to "FindGameObject" of your Audio Manager class in Awake of your Audio Manager script and destroy the new one if there's already one (so you don't have 2 of these ever running at the same time). Only "don't destroy" after it's been established that this is the only one left.
    2) Add code to check the currently playing AudioClip in the Audio Source, if any (position > 0). If it is > 0, do nothing (exit method). If nothing playing (position = 0), play the clip. Turn off "start on awake" on the Audio Source. Make the code only do it.
     
  5. Archozalol

    Archozalol

    Joined:
    Nov 19, 2016
    Posts:
    11
    I'm still learning Unity, so honestly I've no idea what you mean with both of those points.
    Apologies for inconvenience. I am trying to understand how to do that, but no luck. Only getting random errors that unity doesn't understand my code.
     
  6. jerotas

    jerotas

    Joined:
    Sep 4, 2011
    Posts:
    5,572
    #1 is this, should happen in Awake method, which is the first thing that fires for a MonoBehavior script. Assuming your script class is "PlaySong", it would be like this.
    Code (csharp):
    1.  
    2. void Awake() {
    3.    if (FindObjectsByType(typeof(PlaySong)).Length > 1) {
    4.       Destroy(gameObject);
    5.       return; // don't allow code to continue executing since we're destroy this "extra" copy.
    6.    }
    7.  
    8.    // put code for #2 here
    9. }
    10.  
    #2 would be this:
    Code (csharp):
    1.  
    2. var _audio = this.GetComponent<AudioSource>();
    3. if (_audio.clip != null && _audio.time == 0) { // check if audio clip assigned and only do this if it hasn't started playing yet (position == 0)
    4.     _audio.Play();
    5. }
    6.  
    This is all C#, I don't do "UnityScript" or Javascript.
     
  7. Archozalol

    Archozalol

    Joined:
    Nov 19, 2016
    Posts:
    11
    Thank you! I also use C#, so this is helping me out a lot!

    Thank you for your help.

    EDIT: So I tried to put these codes in, but it says that it can't find "FindObjectsByType", so I tried changing it to FindObjectOfType, and then there were no errors, but the game still starts a new song if I go back to main menu screen...
     
    Last edited: Apr 6, 2017
  8. jerotas

    jerotas

    Joined:
    Sep 4, 2011
    Posts:
    5,572
    It's FindObjectsOfType, I may have mistyped.

    https://docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html
     
  9. Archozalol

    Archozalol

    Joined:
    Nov 19, 2016
    Posts:
    11
  10. Saryk360

    Saryk360

    Joined:
    Apr 7, 2017
    Posts:
    8
    I'd go for something like this, attached to a Music Manager gameObject :

    Code (CSharp):
    1. public class MusicPlayer {
    2.     static MusicPlayer instance = null;
    3.  
    4.    void Awake () {
    5.       if (instance != null)
    6.          Destroy (gameObject);
    7.       else {
    8.          instance = this;
    9.          GameObject.DontDestroyOnLoad(gameObject);
    10.       }
    11.    }
    12. }
    Note the use of Awake() rather than Start().
    If you execute the code on Start(), you'll get two instances of the player for a split second and you'll hear some kind of glitch in the audio.
     
    Last edited: Apr 7, 2017
  11. jerotas

    jerotas

    Joined:
    Sep 4, 2011
    Posts:
    5,572
    Yeah that's more performant that FIndObject stuff, that takes care of #1 in my OP. Add a return statement after the Destroy call and then insert #2 code at the end of method above.
     
  12. Archozalol

    Archozalol

    Joined:
    Nov 19, 2016
    Posts:
    11
    Thank you both for the reply, I'll try to do that when I'll get home and tell you the results.
     
  13. Marqmule

    Marqmule

    Joined:
    Jul 16, 2017
    Posts:
    3

    I created a public gameobject near the top and named it gameObject but unity says the name "Destroy" does not exist in the current context
     
  14. cFlop

    cFlop

    Joined:
    Apr 20, 2020
    Posts:
    1
    damm this helped me tysm ppl
    Its my first time too