- Home /
Music works but not when accessed by another script in JavaScript
So I'm working on a small puzzle game and I have a game object with a script that handles loading different levels and changing the music based on if the player is on the title screen or one of the various levels. In that same script, I currently have GUI buttons in the OnGUI() function that changes the levels and music flawlessly by changing some variables and running the Start() function again. I want to change from GUI buttons to other game object buttons, and that works for changing the level but I get an error "Can not play a disabled audio source" and the music tracks do not change.
Here is the code for my Music() function, basically it stops and plays music based on variables
function Music()
{
if(titleScreen == true) //checks to see if the title screen music is already playing
{
if(levelCounter == 0)//checks to see if level counter set to the title screen
{
if(playMusic == 0)
{
titleSong.Play();//plays the titlescreen song
}
}
else if(levelCounter > 0 )//checks to see if the level 1 or higher
{
if(playMusic == 0)
{
titleSong.Stop();//stops the title song
firstSong.Play();//plays the first level set song
}
titleScreen = false; //sets title screen to false
levelSet1 = true; //sets the first level set to true
}
}
else if(levelSet1 == true) //checks to see if the first level set music is already playing
{
//this is used to update the game's music based on the level selected
if(levelCounter == 0)//checks to see if the game is on the title screen
{
if(playMusic == 0)
{
firstSong.Stop();//stops the first level set song
titleSong.Play();//plays the title song
}
levelSet1 = false; //sets the first level set to false
titleScreen = true; //sets title screen to true
}
}
}
In that same script, I have this code located in the Start() function and the audio sources are attached to this object.
var gameMusic = GetComponents(AudioSource); //puts the audio sources in an array
titleSong = gameMusic[0]; //title screen music is the first song attached
firstSong = gameMusic[1]; //first level set music is the second song attached
Music(); //executes the music function to play the right music
As mentioned before, that works perfectly, but I get the error when I have the code from another script running the start function from that script. I have the first script created as a variable and then have it run that Start() function in OnMouseDown().
var gridArrayScript : scr_gridArray;
function OnMouseDown()
{
gridArrayScript.levelCounter = 2; //sets the level to 2 before running the level creation function
gridArrayScript.Start(); //runs the start function in the grid array script to reset the level
}
So is there something else I need to do in order to start/stop audio from another object? I didn't expect to run into an issue because it's the functions in the original script that are executing the commands, the second script is only telling it to run Start()
If it matters, my GUI button has pretty much identical code:
if(GUI.Button(new Rect(20,70,80,20), "Level 2"))
{
levelCounter = 2; //Sets the level to 2
Start(); //runs the Start() function again in order to create the level
}
This seems like a very confusing way to write this. Try something a bit more like this :
//State Enums collections.
enum eGame_States { Title_Screen, Level_1, Level_2}
public var sThe_Game_State_Is : eGame_States;
function subChange_$$anonymous$$usic() {
//oTitle is your reference to the Title Audio Source
//oLevel_1 is your reference to the Level_1 Audio Source
//oLevel_2 is your reference to the Level_2 Audio Source
//You could use switching with one source but I find
//it more trouble than using appropriatly named
//Empty Objects with sources on them.
//Stop all music.
oTitle.audio.Stop()
oLevel_1.audio.Stop();
oLevel_2.audio.Stop();
//Start Playing the correct music.
switch (sThe_Game_State_Is) {
case eGame_States.Title_Screen:
oTitle.audio.Play()
break;
case eGame_States.Level_1:
oLevel_1.audio.Play();
break;
case eGame_States.Level_2:
oLevel_2.audio.Play();
break;
}
}
Call this function like this :
//Once you have set your new game state.
sThe_Game_State_Is = eGame_States.Title_Screen;
//Call subChange_$$anonymous$$usic to set appropriate music for the new game state.
subChange_$$anonymous$$usic();
Hope this helps.
Oh, i guess I should have mentioned a couple things. the "if(play$$anonymous$$usic == 0)" check is to make sure that sound is turned on since i have another game object that turns music off if the player clicks on it ( a mute button). I originally used a boolean, but PlayerPrefs doesn't save those.
The other reason I had it set up that way is that I didn't want the song to restart in between each level. I would rather have the song continue playing as the player advances from level to level. Since some of the short tutorial levels only take 15-30 seconds, I figure hearing it constantly start over and over that quickly would be obnoxious. Is there a way to implement that functionality? Levels 1-10 will use one song, 11-20 will use another, etc.
For the $$anonymous$$ute button I would have a separate function that goes through all your audio sources and tells them to stop, much like the revised subChange_$$anonymous$$usic() example below, which should do what you want. If the player un-mutes the game then just run the subChange_$$anonymous$$usic() function again(no state change needed for un-mute). Here you go :
function subChange_$$anonymous$$usic() {
//Start Playing the correct music.
switch (sThe_Game_State_Is) {
case eGame_States.Title_Screen:
oTitle.audio.Play()
oLevel_1.audio.Stop();
oLevel_10.audio.Stop();
oLevel_20.audio.Stop();
break;
case eGame_States.Level_1:
oTitle.audio.Stop()
oLevel_1.audio.Play();
oLevel_10.audio.Stop();
oLevel_20.audio.Stop();
break;
case eGame_States.Level_10:
oTitle.audio.Stop()
oLevel_1.audio.Stop();
oLevel_10.audio.Play();
oLevel_20.audio.Stop();
break;
case eGame_States.Level_20:
oTitle.audio.Stop()
oLevel_1.audio.Stop();
oLevel_10.audio.Stop();
oLevel_20.audio.Play();
break;
}
}
Sorry typo, that should be isPlaying not Playing. I'm going to sleep, 2A$$anonymous$$ here, good luck!
Answer by MrSoad · Oct 16, 2014 at 03:28 AM
Hi, again. Got insomnia party because my new PC is arriving tomorrow(like Christmas) and party because I knew as soon as I lay down that the code I gave you could have been a lot better, so here is my new answer.
The Main Music functions :
//State Enums collections.
enum eMusic_States { Title_Screen, Music_1, Music_2, Music_3}
public var sThe_Music_State_Is : eMusic_States;
//Mutes var.
private var bMusic_Is_Muted : boolean = false;
function subPlay_Music() {
//Stop All music.
subStop_Music();
//Start Playing the correct music.
switch (sThe_Music_State_Is) {
case eMusic_States.Title_Screen:
oTitle_Music_Source.audio.Play()
break;
case eMusic_States.Music_1:
oMusic_Source_1.audio.Play();
break;
case eMusic_States.Music_2:
oMusic_Source_2.audio.Play();
break;
case eMusic_States.Music_3:
oMusic_Source_3.audio.Play();
break;
}
}
function subStop_Music() {
//Stop All music.
oTitle_Music_Source.audio.Stop()
oMusic_Source_1.audio.Stop();
oMusic_Source_2.audio.Stop();
oMusic_Source_3.audio.Stop();
}
Called like this when you change your level :
function subLevel_Has_Changed_Music_State_Change() {
//When level changes... (With 0 for Title Screen)
if (iLevel_Number == 0) {
sThe_Music_State_Is = eMusic_States.Title_Screen;
if (bMusic_Is_Muted == false) {
subPlay_Music();
}
} else if (iLevel_Number == 1) {
sThe_Music_State_Is = eMusic_States.Music_1;
if (bMusic_Is_Muted == false) {
subPlay_Music();
}
} else if (iLevel_Number == 10) {
sThe_Music_State_Is = eMusic_States.Music_2;
if (bMusic_Is_Muted == false) {
subPlay_Music();
}
} else (iLevel_Number == 20) {
sThe_Music_State_Is = eMusic_States.Music_3;
if (bMusic_Is_Muted == false) {
subPlay_Music();
}
}
}
With this for mute :
function subMute_Music() {
bMusic_Is_Muted = true;
subStop_Music();
}
And this for Un-Mute :
function subUnMute_Music() {
bMusic_Is_Muted = false;
subPlay_Music();
}
This should do the job for you far better, sorry about the long winded rubbish above. My thinking cap had gone to sleep :D
Awesome, thanks again, I'll be working on more of this tomorrow. It's one of the final steps I need for the framework of my project haha
I've done one final edit this morning, it would not have worked quite right the way I wrote it at 4A$$anonymous$$. I think, but due to lack of sleep am not 100%, that it is truly right now. If anyone else out there wants to have a quick read through to double check this I would appreciate it, thanks in advance to anyone who does :D