-1

I am new to Unity, and starting on creating my first simple projects. For some days already I've been facing a problem and doing a ton of research but I still cant get it to work, here is it:

As far as I know, it is a smart idea to have a "GameManager" object with a "GameManager" script that holds the main functions of the game (please correct me if it isn't best practice). So lets put as an example I have Scene 1 and Scene 2:

Scene1: -GameManager -Label

in GameManager there is a function called ChangeLabelText()

Scene2: -Button -Scene2Script

in Scene2script there is a function called ButtonOnClick()

and here is my problem: how do I get ButtonOnClick() to call GameManager.ChangeLabelText()? I always get a reference error.

I've tried to do it within the same Scene and it works perfectly, but not between different scenes. Any ideas?

Thank you !

alfbug
  • 1
  • 1
  • 2
  • This is because when you transition to Scene2, the instance of the GameManager in scene1 "dies", so it's no longer available. To solve this issue put "DontDestroyOnLoad" in Awake/Start function of the GameManager. – rootpanthera Apr 16 '21 at 11:02

1 Answers1

2

Changing scenes in Unity results in Unity destroying each instance. If you want to keep a specific instance/GameObject across several scenes, you may use the DontDestroyOnLoad method. You can pass the GameObject, this specific GameManager instance is attached to, as the parameter. You'd probably want to use a singleton pattern as well for two reasons:

  • You may not want to have two or more instances of the GameManager class at once. A singleton will prevent that.
  • You have to find a way to reference this instance nonetheless, since the components in your other class are totally new instances and they have no idea where this GameManager component is.

Example for a singleton pattern:

GameManager.cs

public static GameManager Instance; // A static reference to the GameManager instance

void Awake()
{
    if(Instance == null) // If there is no instance already
    {
        DontDestroyOnLoad(gameObject); // Keep the GameObject, this component is attached to, across different scenes
        Instance = this;
    } else if(Instance != this) // If there is already an instance and it's not `this` instance
    {
        Destroy(gameObject); // Destroy the GameObject, this component is attached to
    }
}

Example.cs

private GameManager gameManager;

void Start() // Do it in Start(), so Awake() has already been called on all components
{
    gameManager = GameManager.Instance; // Assign the `gameManager` variable by using the static reference
}

This is of course only the basic principle. You may apply that in various slightly different variations if you need to.

User
  • 135
  • 1
  • 1
  • 12