Passing a game object reference into script

Hi,

I hope someone can help me. I’m new to Unity, but a very experienced C# developer, I am struggling getting references to game objects into my script files.

I have declared public variables for the game objects I wish to reference in my script. This makes them appear in the Unity editor. I then drag my game objects from the assets into the public variables that I have created. To make this work, I had to drag the scene objects into my assets which created a prefab which I was then able to drag into the variable window, dragging the game object directly from the scene wouldn’t work. The problem is when I run the Visual Studio debugger over my script, when I enter into the Update method, the game object reference variables are all null. I can’t figure out why the references aren’t being created. I have read that you can’t link references from prefabs but I can reference an object directly from a scene so I’m in a bit of a catch 22.

Am I doing this the right way? I’ve also looked at the GetComponent, LoadComponent methods etc. but they don’t seem to work either and they also don’t allow me to specify a particular object e.g. if I have multiple Tilemaps, the GetComponent only allows me to get an object of type tilemap e.g. GetComponent(), there seems to be no way to specify a particular Tilemap. How can I get a specific object by name e.g. if i have a Tilemap called BaseLayer for example.

I’m sure there is a simple explanation, but I have been searching for hours and have been unable to find an answer to this seemingly very simple query.

If anyone can give me a hand, I’d much appreciate it!

Many thanks,

Damien

I’m not sure if I understand correctly but if you just want to get a component from a specific GameObject, you could do it this way:

CharacterController cc = GameObject.Find("character").GetComponent<CharacterController>();

This would get Character Controller component from a GameObject called “character”?

And in your case it would be:

Tilemap tMap = GameObject.Find("BaseLayer").GetComponent<Tilemap>();

If you need to access many of your objects in scene which are of certain type, you could use
Object.FindObjectsOfType to get an array containing all objects of that type in your scene.

If you need to access a certain object like your game manager or something that’s there most of the time, you could use Singleton pattern so that you could then access it by:

int level = GameManager.Instance.currentLevel;

Oh man you are awesome, that worked! Is this a particularly efficient way to get a game object though? I’m wondering why i can’t get it to work using public variables as references as from what I understand that should be a valid way of achieving the same thing. If anyone can let me know if this is possible and how I would be really grateful.

Thanks Olmi, you’ve given me enough to allow me to get on with my game :).

Thanks,

Damien

Hm. If you have public exposed variables and you have dragged a GameObject (or whatever type you have defined it to be), components should be easily accessible just as well, like this:

// In your class
public Player exposedPlayer;

// In some method
int playerHealth = exposedPlayer.GetComponent<Player>().health;

It’s often said that these GetComponents and Finds should be used with consideration, so just cache references when you can. i.e. do your finds and get your components in Start instead of doing it every time you need to access Player.

Dragging a gameobject into an inspector variable in the same scene works fine, do not drag prefab into these variables unless your intention is to clone the prefab in the scene and then use that cloned object(that now does exist) to get components.

A prefab is a blueprint of an object, when you drag it into the scene, it creates a game object you can now reference. But the prefab itself does not actually exist as an object. Does that make sense?

If you need to access objects from other scenes, or just dynamically, there exist a few ways to do this.

A few are: FindGameObjectByTag, make sure when you use it you do null check! Dont assume it will return a valid reference!

Overlap spheres, using collision to search for nearby objects that have collides and gathering them in an array.

ScriptableObject data types that represent whatever you want. Very useful!
There should be many tutorials on YouTube highlighting some very clever ways to do this!

Events. Generate an event to access or affect other objects.

Thanks for all the tips guys, much appreciated!

TimmyTheTerrible (great name BTW) the problem I have is I can’t drag the game object into the variable, the editor just puts a cross over the cursor showing that I’m not allowed to do it. I’m trying to drag my Tilemap called BaseLayer from the GameScene list into the script variable. Am I perhaps dragging the wrong thing? The only way I can get it to work is to drag the object from the GameScene into the Assets section which creates a prefab which I can then drag from the Assets section into the variable - but I don’t want a prefab copy.

If anyone has any idea what I’m doing wrong it would be really helpful.

You can’t drag and drop a reference from the Hierarchy view (scene Object) into something the Project view (asset). Unity just doesn’t support serializing references to scene Objects in assets (or references between Objects in different scenes).

This is why you have to establish the connection programmatically once a scene Object has been created from the asset, because this is first moment when the two Objects both exist inside the same scene.

I’m taking a brackeys tutorial, and I copied the code exactly, yet it doesn’t work.
I’ve thought it was that he was using a Windows computer when I’m using a Mac.
Could you help?

-NuclearCloak

@NuclearCloak You can create a new thread in the Scripting Forum and post the code you need help with there :slight_smile: