- Home /
How to send a message across different scenes
I have a script in Unity which lets me load scenes randomly once the user presses on the "Next Button" in scene 0, which in turn loads a random scene (be it scene 1 or scene 2). Now, each scene has its own next button which (theoretically) sends a message to the SceneManager script that is attached to the mainCamera object in scene 0 to loads the next random scene.
But the reality is that, while it is loading random level from scene 0 the first time, when I get to either scene 1 or 2 and hit the next button it doesn't load, it just stops after I hit the button.
Now, here is the script I have attached to the mainacmera object in scene 0:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
[ExecuteInEditMode]
public class myDefaultScene: MonoBehaviour
{
public static bool userClickedNextButton;
protected const int MAX = 2;
private List<int> scenes = new List<int>();
void Start()
{
scenes = new List<int>(Enumerable.Range(1,MAX)); // This creates a list with values from 1 to 2
cs_completionWindow = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<TestCompletionWindow>();
Debug.Log(scenes.Count);
}
void Update()
{
if (userClickedNextButton)
{
if (scenes.Count == 0)
{
Application.Quit();
}
// Get a random index from the list of remaining level
int randomIndex = Random.Range(0, scenes.Count);
int level = scenes[randomIndex];
scenes.RemoveAt(randomIndex); // Removes the level from the list
Application.LoadLevel(level);
userClickedNextButton = false;
}
}
}
Here is the command I have in my other scenes to send the message to the scene0:
public void myMethod()
{
switch(...)
//...
//CODE goes here
//...
case Windows.nextReferentTask:
myDefaultScene.userClickedNextButton = true;
break;
}
Answer by Tomer-Barkan · Dec 18, 2013 at 09:05 PM
Maybe you want to attach the SceneManager object to all scenes, not just scene0. Keep in mind, that when you load a scene, the previous scene is unloaded from memory, so all the objects and scripts in the old scene are no longer running. You can't actually send a message to an object in another scene, but what you can do, is load another scene and pass some information to it. But remember that the other scene will only use this information after it is loaded.
The trick to do that, is define an object that remains between scenes, and is not destroyed when you switch scenes. You can do that by calling the DontDestroyOnLoad. All you have to do is run the command in the object's start method:
void Start() {
DontDestroyOnLoad(gameObject);
}
Now this object will be kept between scenes, and you can use this object to pass messages between scenes.
For your case, it seems like one of two methods will work best: Either keep your SceneManager between scenes (with the method described above), or have a different SceneManager in every scene.
@tbkn in my inspector I created a new object called it myPersistentObject and attached the script I want to use in my other scenes. I also removed it from the $$anonymous$$ianCamera object. In the Awake() method I wrote: DontDestroyOnLoad(); but it gave me an error as DontDestroyOnLoad() requires at least one argument, so I placed DontDestroyOnLoad(this); and that seemed to have quieted the editor. But when I run it it tells me that Object is not set to an instance of an object. Any idea as to why that is happening?
try DontDestroyOnLoad(gameObject)
, and if it still fails (I think it will because the error seems unrelated) check which line gives you the null pointer error, and share it.
I'll update my code, I forgot you have to pass a parameter to DontDestroyOnLoad.
@tbkn the error lies when I try to access the script from another class.
I have the class that handles the loading of the random levels:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
[ExecuteInEdit$$anonymous$$ode]
public class Referent$$anonymous$$anager : $$anonymous$$onoBehaviour
{
/// <summary>
/// Singleton to hold the boolean value
/// </summary>
private static Referent$$anonymous$$anager instance = null;
public static Referent$$anonymous$$anager SharedInstance
{
get
{
if (instance == null)
{
instance = GameObject.FindGameObjectWithTag("$$anonymous$$ainCamera").GetComponent<Referent$$anonymous$$anager>();
}
return instance;
}
}
[HideInInspector]
public bool userClickedNextButton;
protected const int $$anonymous$$AX = 2;
private List<int> scenes = new List<int>();
void Start()
{
scenes = new List<int>(Enumerable.Range(1,$$anonymous$$AX)); // This creates a list with values from 1 to 2
DontDestroyOnLoad(gameObject);
}
void Update()
{
if (userClickedNextButton)
{
if (scenes.Count == 0)
{
Application.Quit();
}
// Get a random index from the list of remaining level
int randomIndex = Random.Range(0, scenes.Count);
int level = scenes[randomIndex];
scenes.RemoveAt(randomIndex); // Removes the level from the list
Application.LoadLevel(level);
Debug.Log(scenes.Count);
userClickedNextButton = false;
}
}
}
Then I am trying to send a message to this class from another class this way:
case Windows.closeWindow:
Referent$$anonymous$$anager.SharedInstance.userClickedNextButton = true;
break;
Its this line where I am getting the null reference exeption error.
You're making the main camera object to remain between scenes, so assu$$anonymous$$g your other scenes also have a main camera, this is a weird situation. So there are two things you should do:
First, ins$$anonymous$$d of attaching the script to the main camera, create an empty game object and attach to it.
Second, since this is a singleton and you will only have one, you can set the static reference on Awake() ins$$anonymous$$d of searching for the gameobject with tag:
/// <summary>
/// Singleton to hold the boolean value
/// </summary>
public static Referent$$anonymous$$anager SharedInstance { get; private set; }
[HideInInspector]
public bool userClickedNextButton;
protected const int $$anonymous$$AX = 2;
private List<int> scenes = new List<int>();
void Awake() {
SharedInstance = this;
}
// rest of code
@tbkn I went ahead and did what you said; so far so good. Do I make other empty game objects in the other scenes and attach the same script to them as well?
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Distribute terrain in zones 3 Answers
Multiple Cars not working 1 Answer
How do i learn C# or UnityScript as a teen? 6 Answers
C3 Creating GameObject in script why give me an error ? 1 Answer