How to access a game object in another scene?

In my game, If an error occures, I want to move the player to the menu scene and in that scene display an error message. My idea was to have a script with a static bool variable on the menu scene so at the Start() function if the variable is true it will display the message. How do I cange this variable from a script in another scene?
Getting a refrance to the object in the menu scene is not an option.

Thank you!

https://discussions.unity.com/t/839310

But only if both scenes are loaded together. If you want to pass information from one scene to another after replaced the scene, you can store information in static variables or your can have DontDestroyOnLoad objects for this specific purpose. I like the static variables more. I usually build a kind of blackboard system around this so it can be used for all kind of information I need to store for gameplay.

How can you use static vars in this case? Can you give me an example?

Static Variables are great, but can also cause spaghetti code for larger projects, since they tend to make things less modular. Static variables are bound to the class itself, so you can just write MyClass.myStaticVariable = myValue.

Anyways… “if there is an error”? As in an actual exception? I wouldnt spend effort on making sure the player ends up in the main menu if an exception occurs. How do you intend to accomplish that? The player will be annoyed anyways, whether the game crashes or he ends up in the main menu makes little difference imho. Rather make sure there is no exceptions to begin with.

2 Likes

It’s a multiplayer so if the host suddenly disscontcts. Thanks for the help.

1 Like

You can use a scriptable object asset to allow objects in different scenes to communicate with each other.

The scriptable object:

[CreateAssetMenu]
public sealed class Error : ScriptableObject
{
    public event Action<string> Occurred;
 
    public string Message { get; private set; } = "";
 
    public void Report(string message)
    {
        if(string.IsNullOrEmpty(message))
        {
            Message = "";
            return;
        }
     
        Message = message;
        Occurred?.Invoke(message);
    }
 
    public void Clear() => Message = "";

    private void OnEnable() => EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
    private void OnDisable() => EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
    private void OnPlayModeStateChanged(PlayModeStateChange mode) => Message = "";
}

How to use it:

public sealed class ErrorReporter : MonoBehaviour
{
    [SerializeField]
    privates string message;

    [SerializeField]
    private Error error;
 
    public void Report() => error.Report(message);
}
public sealed class OnErrorLoadScene : MonoBehaviour
{
    [SerializeField]
    private Error error;
 
    [SerializeField]
    private string scene;
 
    private void OnEnable() => error.Occurred += OnErrorOccurred;
    private void OnDisable() => error.Occurred -= OnErrorOccurred;
 
    private void OnErrorOccurred(string message) => SceneManager.LoadScene(scene);
}
public sealed class ErrorDisplayer : MonoBehaviour
{
    [SerializeField]
    private Error error;
 
    [SerializeField]
    private TMP_Text displayer;
 
    private void Start()
    {
        if(string.IsNullOrEmpty(error.Message))
        {
            return;
        }
     
        displayer.text = error.Message;
        error.Clear();
    }
}
2 Likes