- Home /
How to call a function from a script in another scene
is there a way to call a function on a script in another scene? or effect a script in another scene being active or not? I am trying to create difficulty settings and I would like to have my title screen on its own scene and make it call a function or a script in the next scene to set whichever difficulty the player has chosen, I am simply unsure of how to go about linking the menu script to the script in the main game.
Is there a way to do this? Or should I just make my title screen in my main game? I am currently using javascript
Answer by syamilsynz · Jun 30, 2015 at 11:07 AM
In scene 1.
Create empty GameObject and name it "Script". Attached a script (eg: class name "Scene1.cs") that want to be calls from other scenes. Apply DontDestroyOnLoad on it.
void Awake()
{
DontDestroyOnLoad(this);
}
public void TestCall()
{
// test
}
In scene 2.
private Scene1 scene1;
// Use this for initialization
void Start ()
{
scene1 = GameObject.Find("Script").GetComponent<Scene1>();
scene1.TestCall();
}
Answer by Peter G · Nov 30, 2010 at 11:42 PM
There are several ways to do this.
You could make the difficulty a class variable (
static
keyword) then have each scene check the difficulty variable on this script. This would be the opposite of your idea, but would be just as easy, if not easier.You could use
DontDestroyOnLoad()
on some script in your opening scene so that the difficulty manager is not destroyed when the new scene loads.I am not sure how skilled of a programmer you are, but you could create a singleton of you individual scene managers, and then change the difficulty there.
You could use
PlayerPrefs
to store a value to load in the next scene. This method is not really ideal, and I would only use it if the other 3 fail.
The problem is that instances of your scripts are created and destroyed when a scene loads, not when the game loads, so you either have to create a class field or singleton or use DontDestroyOnLoad
.
So by the solutions you listed, would a viable solution be keeping one object as a scene loader (which also holds globals) and loading scenes with the loadLevelAdditive() method?
@Peter G Why don'T you suggest PlayerPrefs method ? Why should i avoid to use it ?
Answer by moment_um · Oct 08, 2018 at 04:15 AM
There are 2 straight forward answers that I can think of.
Make all members in the class static. Making them static is super easy and convenient, but there are a couple problems that you run into: 1, you can't have more than 1 of a member, because static members belong to the Class and not the instance of a class. 2, Unity does not support editor drag and drop functionality of static members ([serilizefield] or public functionality). There are probably some fancy things you could do to get around that, but it's not straight forward. If you must have this,
Make a Singleton helper. a class that calls the singletons methods. The most standard way to make a Singleton is to make a public static instance of itself like this
public static MenuManager instance; void Awake() { if (instance) { Destroy(gameObject); } else { instance = this; } }
then in another class call the singletons methods using that instancepublic void DoSomething(){ SingltonClass.instance.DoSomething(); }
you can put that class in all your scenes, but you only need to put the singleton in your main menu scene, or whatever scene you wish.
Answer by catch_up · Feb 23, 2020 at 11:33 AM
I've loadded Settings scene from MainMenu scene, and now both of the scene exists
SceneManager.LoadScene("Settings", LoadSceneMode.Additive);
I've a game object in MainMenu scene on which MainMenuController monobehavior is attached. Now, in SettingsController.css, I can call a function inside MainMenuController.cs
function void SomeFunc()
{
MainMenuController mainMenuController = GameObject.Find("MainMenuController").GetComponent<MainMenuController>();
mainMenuController.DoSomething();
}
Answer by CoolCosmos · Aug 13, 2020 at 11:07 AM
Peter says that he doesn't suggest PlayerPrefs method to use. Can anyone tell me why i should avoid to use this method ?
I think, it would be easier to save variables and then call it on anywhere you like... I'm not sure though...
Because playpref will save the data in the device and theses data will persist between game session. On window it will be save on the window registery. I'm pretty sure it's a bad idea for what you want to do. A singleton pattern (~ using static reference) is better.