- Home /
How to prevent Unity4.6 Toggle button loosing its state when jumping between scenes?
Hi!
I have a Singleton MusicManager what offers sounds and music to a game, menus, buttons etc. I tested today Unity3d 4.6 new Toggle-button and somehow it is working. If I turn sounds off in my option menu and go to play a game and come back to option menu, the image is back in default state (music on). I am using my MenuManager.cs and it is calling singleton Musicmanager, How can I prevent this? Is there way to tell Unity that don't destroy and instantiate options-scene again when jumping between scenes or could I somehow programmatically change the state/image of the toggle-button to be right?
EDIT: The weirdest thing is that according to the Unity Log, when I come second time to Option screen, it goes automatically MusicManagerSingleton and MenuManager's ToggleMusic() methods even if I haven't touch the whole button? My usecase is that when I go first time to options and mute the music, everything is working fine, BUT when I come back there without touching the button,music starts and mute/sounds Toggle button is in state true.
EDIT2
Unity calls automatically ToggleMusic()-method as well and that was the reason. I added this line and everything started to work: if (toggle.isOn != MusicManagerSingleton.Instance.musicOn())
public class MenuManager : MonoBehaviour {
public bool musicOn;
public AudioClip musicClip;
public UnityEngine.UI.Toggle toggle;
public void Start ()
{
toggle = GameObject.Find("MusicToggle").GetComponent<UnityEngine.UI.Toggle>();
toggle.isOn = MusicManagerSingleton.Instance.musicOn ();
Debug.Log ("0. START() MenuManager musicOn in ToggleMusic()--->" +toggle.isOn);
}
public void ToggleMusic() {
MusicManagerSingleton.Instance.toggleMusic ();
//toggle.isOn = MusicManagerSingleton.Instance.musicOn ();
Debug.Log ("1. AFTER TOGGLING MenuManager musicOn in ToggleMusic()--->" +toggle.isOn);
Debug.Log ("2. AFTER TOGGLING MenuManager musicOn in ToggleMusic()--->" +MusicManagerSingleton.Instance.musicOn ());
}
}
EDIT2 NOW THIS IS WORKING
***************MenuManagerSingleton.toggleMusic()*************************
public void ToggleMusic() {
if (toggle.isOn != MusicManagerSingleton.Instance.musicOn()) {
MusicManagerSingleton.Instance.toggleMusic ();
}
}
Thanks! Tumpula
[1]: /storage/temp/37218-screen+shot+2014-12-18+at+11.37.43.png
Answer by HYPERSAVV · Dec 18, 2014 at 01:42 AM
You could use the PlayerPrefs to store state between scenes. When you alter the value in the options, set the value in PlayerPrefs. When you come back to the option menu, get the last recorded values from PlayerPrefs.
Hi and thanks for answering! I have the state already in my $$anonymous$$usic$$anonymous$$anager-Singleton, but the problem is that how to tell it to new 4.6 UI Toggle Button so that image is always in correct state as well? No when user clicks the mute button, it calls $$anonymous$$enu$$anonymous$$anager's Toggle$$anonymous$$usic()-method and it calls the $$anonymous$$usic$$anonymous$$anager: public void Toggle$$anonymous$$usic() { $$anonymous$$usic$$anonymous$$anagerSingleton.Instance.toggle$$anonymous$$usic ();
Think of it this way...your options menu is merely going to represent the current state of $$anonymous$$usic$$anonymous$$anager. So when you "start" the options menu you should just query the necessary values/states and update the UI to reflect that. Your flow should be something like this.
Go to options scene
Update UI elements to reflect state of $$anonymous$$usic$$anonymous$$anager
User does stuff
User signals interest in leaving scene
Update $$anonymous$$usic$$anonymous$$anager to reflect state of UI (if this is not done when interactions are made)
Exit to next scene
This way you are not considered with maintaining a single menu. It's just a view on top of a layer of data. NOTE: Step 2 assumes that you can retrieve the state from $$anonymous$$usic$$anonymous$$anager, so these will need to have public getters. Not sure how familiar you are with C#/OOP, but this can be down like so:
public bool mute { get; private set; }
The value can still be queried from other objects, but $$anonymous$$usic$$anonymous$$anager will still be in control of altering it.
Hi!
I think that I have all of this. The state is saved on $$anonymous$$usic$$anonymous$$anager and $$anonymous$$enu$$anonymous$$anager asks it from the $$anonymous$$usic$$anonymous$$anager. I updated the question a little bit so could you please check it.
Thanks you! Tumpula
It seems like you have everything in order here...I'm assu$$anonymous$$g you have something like this for Start:
// Within $$anonymous$$enu$$anonymous$$anager...
void Start()
{
Toggle toggle = GameObject.Find("TheToggle").GetComponent<Toggle>();
toggle.isOn = get$$anonymous$$usicOn();
}
In your code I don't see where $$anonymous$$enu$$anonymous$$anager updates the Toggle at start (you are only doing if after the user makes a gesture), so if you did not omit anything in your sample you are still missing that key part.
Answer by SkaredCreations · Dec 18, 2014 at 01:40 AM
You can declare a static variable in your MenuManager to store your toggle state before loading the new level and in your MenuManager.Start you will set the toggle state yourToggle.isOn = MenuManager.yourVariable (static variables persist even if you change level).
I have the static variable: public static bool musicOn; but when choosing the On Value Changed in Inspector, Unity doesn't show that variable at all. It only shows the Toggle$$anonymous$$usic()-method, not the static parameter at all under the $$anonymous$$enu$$anonymous$$anger. Thanks for answering!
I was not talkimg about changing or setting a method for On Value Changed, please re-read my answer: I'm saying to set "isOn" property of your toggle to "musicOn" directly inside the method Start of $$anonymous$$enu$$anonymous$$anaget (that I suppose is a $$anonymous$$onobehavior)
Good idea!
public void Start ()
{
musicOn = $$anonymous$$usic$$anonymous$$anagerSingleton.Instance.musicOn();
Debug.Log ("musicOn in START=========>" +musicOn);
}
I added a start method and in log it says: musicOn in START=========>False UnityEngine.Debug:Log(Object) $$anonymous$$enu$$anonymous$$anager:Start() (at Assets/Scripts/$$anonymous$$ain$$anonymous$$enu/$$anonymous$$enu$$anonymous$$anager.cs:12)
but in the game screen:

Answer by Kiwasi · Dec 18, 2014 at 01:57 AM
There are multiple ways to approach this. Choose the one that fits. In the order I would suggest they are:
Have the button check the sound manager state in OnEnable
Use DontDestroyOnLoad to maintain the same button
Tie an event to the change in your sound manager. Update the button every time the event fires
Could you help me a little bit, I have no idea how to do that :) I am new with unity. $$anonymous$$y ToggleButton name is $$anonymous$$usicToggle in inspector. Thanks!
Your answer
Follow this Question
Related Questions
PlayerPrefs for Mute/Unmute button 1 Answer
GameObject as toggle button with touch 1 Answer
Toggle Button State On/Off 2 Answers
GUI.Button Toggling Error 1 Answer