Direct reference to a hierarchy object from prefab?

I have a unique GameManager gameobject in my scene at all times, before and during game start.

I want any instantiated prefabs with a script in the scene to have a direct reference to the GameManager object in their respective scripts.

I got this code in each script so i can assign a reference → var GameManager : GameObject;

But i didnt know Unity doesnt allow to drag an object from hierarchy to the slot in the prefab.

Making the GameManager object a prefab lets me assign the prefab to the slots but then wont it mean every instantiated object creates a new GameManager instance that it references? and where is that reference anyway if its a prefab? This confuses me.
Or will the object actually refer to the GameManager present in the hierarchy?

I know that for each prefab i can just put in the Start() function to find the object with name “GameManager” and assign a reference to it but i want to avoid using searching.

Any suggestions and explanation welcome :slight_smile: thanks.

if your game manager is unique, you can just do a find in your Start(), or better yet in Awake().

Find and then store the reference in your script. You can make the reference private or public, doesn’t matter.

Given your class name, it sounds likely that your GameManager has instance data; if so you’ll definitely want to have your objects reference the instance and not the prefab. You can instance your game manager by putting it in every scene you’re going to load or by putting it into the first scene you load and setting it to never be destroyed.

Given that, you can do this easily reference it using a singleton design pattern with zero cost, zero searching, zero tags, and without needing to store it in more than exactly one field

  1. Set the priority of your GameManager script to be higher than every other script via

    Edit->Project Settings->Script Execution Order

  2. During the GameManager.Start(), which will be executed before all other scripts due to step one, save a reference to the game manager in a public static variable:

    class GameManager : MonoBehaviour
    private static bool s_permanentInstance = false; // set to true if you ever only want one instance among all scenes and drop an instance of GameManager in your first scene you load
    public static GameManager Instance {get; private set;}

     public Start()
         if (s_permanentInstance == true)
             if (Instance != null)
                 Debug.LogError( "GameManager initialized twice, overwriting" );
             DontDestroyOnLoad( this );  // prevents this from being destroyed on scene load
         // store the singleton reference
         Instance = this;


  3. Any script that needs to access the game manager can simply now just use the following (and there isn’t really a need to store a reference to it since it’s always fast to retrieve)

    void SomeFunction()
    GameManager gameManager = GameManager.Instance;