0
votes

About a month into making my first game, I have realized that I am very confused when it comes to attaching gameobjects as classes to another game object's script. That's a mouthful so here's my issue.

My Game.cs attached to Game (gameobject) has

public Player player;

My Player.cs is attached to a Player (gameobject) prefab

Why can I drag a Player gameobject, that has a player script, into the Game gameobject's "player" field? How does that make sense? It should be

public GameObject player;

Then I would drag my prefab gameobject "Player".

The reason why this confuses me is, If i Instantiate "player", am I instantiating a gameobject? It seems not, because I cannot do this:

GameObject newPlayer = Instantiate(player, new Vector3(1,1,1), Quaternion.identity) as GameObject;
newPlayer.transform.SetParent(GameObject.Find("Level"));

If I do I will get the error the newPlayer is null.

2
what unity actually is doing is trying to be nice. Dragging a game object into that public Player player; property Unity is analyzing the GameObject for components that would fit into the variable and getting the player one for you. You are not actually putting a GameObject (Square Peg) into a Player variable (Round Hole). I beleive if you tried to put a game object there that didn't have a component of the Player Class Unity would silently fail.Joe

2 Answers

2
votes

A script is actually a Component object like any other object (most of the time).

It is technically not too easy to drag a Component object from an inspector onto another slot in another inspector. Probably thats why they made this "shorthand", when you can drag the actual GameObject instead from the hierarchy.

If the dragged GameObject has a matching component to a slot, it counts as you have dragged the Component itself.


You cannot instantiate a script Component using Object.Instantiate, you'll always instantiate a GameObject this way, see the docs. If you need the script, simply get the component from the brand new instance.


It can be confusing indeed, I personally prefer naming convention something like:

public GameObject playerObject;
public Player player;
1
votes

Unity. by default, will cast any gameobject into the possible component, for example, if you have a Transform in your script and pass a gameobject (as a lot of tutorials do), it will automatically cast to the transform of given gameobject.

The main problem with that is simply that if you try to attach an object without Player script, it will probably crash in one way or another if you don't check the value.

Anyway, while you are working with your own scene and are sure the player gameobject has the necessary script, it won't be a problem in any way


Oh, about the last part, attaching components is common for already instantiated objects, to instantiate from a component you should get the parent game object of that script, and it would not make sense as you could easily attach the prefab directly

I don't remember now exactly how, sorry