- Home /
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 :) thanks.
It appears that instantiated prefabs with a reference to a Game$$anonymous$$anager prefab refer to a new instance.
I tested by making int x = 5 in a script in the Game$$anonymous$$anager object and Logging it in update() in one of my instantiated objects.
Upon instantiating the object logged 5, but when i changed the value to 10 in the Game$$anonymous$$anager object in the hierarchy, the value remained 5. So it doesnt reference that object...
Is it possible to directly create a reference to the object without searching for it? like ins$$anonymous$$d of using Find("Game$$anonymous$$anager"), ASSU$$anonymous$$E there is one and try to assign a reference directly in Start() upon instantiation of the prefab.
I guess finding it with a tag would be faster than by name? so at least thats an improvement if i do have to search for it...
hey if i make all the scripts in the Game$$anonymous$$anager object contain static variables then that would work, since the prefab references and the hierarchy object all would refer to the same variables.
but im a little wary of this, cause id have to set a bunch of variables static and who knows what i might miss. But in theory that would work.
Answer by salex100m · Nov 26, 2013 at 04:14 AM
if your game manager is unique, you can just do a find in your Start(), or better yet in Awake().
http://docs.unity3d.com/Documentation/ScriptReference/GameObject.Find.html
Find and then store the reference in your script. You can make the reference private or public, doesn't matter.
sigh... yea i know i can do that, i was just wondering if there's any way to avoid searching. Would it be computationally faster to search by tag?
By adding the find in the Awake or Start it has nearly ZERO computational cost. If you put a find in a loop, inside of Update(), it will be a little worse, but you probably still wont ever notice.
I don't like tags, but you could use a tag.
but what if theres 100 objects in the hierarchy and another is spawned and now searches for "Game$$anonymous$$anager" through the 50 objects, thats gotta be some cost even if it only does it once.
Right now i use findbytag in Awake()
Why dont you like tags? im really curious, ive always found them really useful and you can have unlimited amounts.
You're not going to notice a performance loss for a simple find if you only do it once. period. unless that find is in some terrible infinite loop or something.
If a tag works for you , you should use it. I started using tags then changed my tagging a bunch of times before just settling on using an custom made identifier in my object classes
yea its definitely only once in Start() or Awake()
custom made identifier? how does that simplify things, wouldnt you still have to manually change your identifier a bunch of times if needed?
Answer by colinday · Mar 17, 2015 at 07:21 AM
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;
gameManager.DoSomething();
}
Your answer
![](https://koobas.hobune.stream/wayback/20220613122811im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Getting a NullReferenceException when trying to assign a script variable 1 Answer
Understanding scene files 0 Answers
How do you work on both Windows and Mac using git? 0 Answers
OnNetworkLoadedLevel in the script reference? 0 Answers
How to pass float from one script to another in Unity 5? C# 2 Answers