Unity seems difficult for me to wrap my head around, especially when referencing classes in scenes?

I am used to having object banks for scenes, and putting them together using parameters. In unity the same is true, except this:

[GameObject] ----CONTAINS—> <OBJECT_CLASS> ----CONTROLS -----> (Object_SubClass_Reference| GameObject_Reference_T:eyes:ther_Object | Reference_To_GameObject | Variables_In_THIS_ObjectClass | A_Reference_To_A_SpecificComponentCalled_In_Another_GameObject_Which_Must_Be_Stored_Again| etc)

I must not be looking at this the right way BUT I am viewing the scene objects and classes as basically an island or container. I hate viewing this, this way. I cannot seem to get my mind around managing a bunch of islands containing parts I need. I’m used to seeing a class or object as a reference to its parts or subclasses. Maybe its just an imaginary mental block when it comes to accessing and declaring whole objects.

Do other game engines use things like GetComponent for everything? I thought you could declare references within subclasses a whole bunch of ways.

I’m not sure I like this reference stuff.

I’m used to like, taking a genetic class, and directly accessing a variable that I have given it and working with it.

But now the classes are gameobjects which hold scripts(the class), and arent gameobjects themselves. This is very confusing to me.

The classes you inherit from monobehaviour are components, not gameobjects. It might add to your confusion but you can have normal c# classes that behave “normally” as well, hence the distinction.

Gameobjects are “folders”, they contain “files” (i.e. components). If you want to access specific “data” (attributes/functions) in the “files” you need to specify which “file” in the “folder” you’re taking about (i.e. GetComponent() might be stretching the analogy here :slight_smile: :eyes: )

ummmmmmm now im more confused but yeah youre right. Anyway all of this is making need a break now. thanks for the understanding. I tthink maybe unity is beyond me.

Sometimes it is better to have the game in just 1 scene, and use some level editor to make maps (if it’s that kind of game). But if you want to share data between scenes, you can use static variables. It’s just if you were to have class based on MonoBehavior, a reference variable of that type might become null when 1 scene unloads. But that’s understandable too, anything in the scene will not carry over.

If you use to organize your application as an hierarchy of classes, the way entities are built in Unity can seem a bit unatural and can conflict with your mental representation of an application.

Unity is designed around a component based architecture. That is, the objects are build by composition rather than derivation. Derivation and composition can solve the same problem. Composition becomes more flexible when your objects share the same characteristics and there is no apparent hierarchy organizing them.

But wait a second, doesnt this mean that the GameObject in unity is like an instantiated namespace? You have to GetComponents out of it to even access whole classes inside parts of it.

Or no?

bleh, anyway thanks everyone who responded with your thoughts. I think I’ll take a long break probably and contemplate the design structure of Unity, surely my mental block is imagined. I’m sure its easierr than I think to work in the heirchy of unity’s game engine structure.

Rather look at it as a kind of container.
A gameobject itself doesn’t really do anything at all, it only provides methods to handle that “thing” in your world, for example, destroying it, enabling/disabling, find a component that is attached to it etc etc.
In the end, the components define what the GO is going to represent in your world.

So, once again, in order to build your entities in the world, you add components to an GO which define what it’s gonna be. In order to get a reference to them, you have to use GetComponent.

Well, you have to get the reference somehow.
In usual C# programming, you’d either use a way to inject the dependancy by passing an already existing object, use a factory-like class or you’d make the object instantiate all the objects it needs to reference. You can do this in Unity as well, but these classes should neither inherit from MonoBehaviour nor ScriptableObject.

Unity’s components have to be initialized / set up at some point in order to be properly linked to the GameObject it belongs to and other internal stuff.
That all is hidden for good reasons, and that’s also why you call “AddComponent” when you want to add a behaviour during runtime, it simply has to be set up internally.
You cannot (actually you can, but it’s not useful at all) simply use " … = new MyCustomMonoBehaviour()", try it: You’ll get a warning, and, for instance, the gameobject property will return null, because the engine didn’t have the chance to do necessary initialization steps.

1 Like

The GameObject does store the Transform that defines the position and rotation of the GO and its components in 2D or 3D world space, and the GO establishes the position of the “thing” in the scene render hierarchy – for example, a doorknob which can rotate on its own, but is also a child of the door and so is rotated with the door when the door moves on hinges.

As I said, the GameObject itself doesn’t really do anything (except a few things, internally probably more). The components define what it is. Transform is also a component, which is, unlike other components, indispensable for a GameObject’s existence.

No GameObject <=> no Transform.

So yes, it stores the Transform component just like any other component, but the GO class itself does not provide anything else than some basics and can be seen as container that manages all the components.

1 Like

wow I think I get it, so it IS a type of container which references its own specific lists of classes contained inside?

So getcomponent is like calling on a specific memory address of a class contained inside of a specific GameObject?

Well hey I got a question then, whats the best way to like, FIND tons of gameobjects (clones) in a sea of endless clones? Will I, or should I just append things to lists:

List<GameObject> megaList =  new List<GameObject>();

and add things to that list (not 100% on the syntax for adding things when instantiated.

But, then add a variable in each GameObject inside of a class called ID or FixedValue or something?

Hmmmmm… Should I even have different lists for different types of gameobjects? OR , should I create lists for unique classes, and hold in each class a reference to its GameObject which I can then search each list to find a specific object meeting a if conditional statement to choose them, for instance, UI elements. Hrmm… I need to think about this more.

Thanks again…

At least think of it as if it was a container, you can also see it as the overall wrapper to bundle everything for one entity in your world. Inside, it needs an actual container-like data structure to keep track of all components that belong to it. Maybe others can tell you more about it in detail, I cannot. Except that most of that actually happens on the C++ side.

GetComponent will try to get a component that has been added before. You will always be able to find the GOs transform, as this will automatically be added when a GameObject is created. Any other call to GetComponent can fail to return an instance of the given component type. Every component that is attached to a gameobject will usually be shown in the inspector.

When you drop one of your scripts onto a gameobject so that it is shown in the inspector, it’s kinda like the same as calling “AddComponent”. That component will then be instantiated, properly linked/ registered and whatsoever the engine needs to do with it. At a later point, if you haven’t saved the referenced already, that GO can return it by using “GetComponent”.

It’s really like asking “hey, could you please get a component of type T out of your component-bag”. If there is one, you’ll get it, if there isn’t one, you’ll get ’ null '.

This can be done, the question is: does it make sense for your use-case?

You can either make use of the name of a gameobject (or the tag, but i wouldn’t do that in this case) or you add a component, a script that inherits from MonoBehaviour and carries all the meta-information that you need.
For the latter part of your question: that really depends on what you want to achieve. There is no solution that is 100% correct.

Good point. I stand corrected. :slight_smile:

Ok, so Unity actually works with gameObjects who have these attributes such as InputField,Text, Spriterenderer, or ClassScripts appended to them on creation/after creation, so stop viewing the componenets themselves as individual classes outside of the gameObject. But instead view each gameObject as the class I am managing and then using GetComponent to actually locate the child attribute that the gameObject can reference under it or you can get from the gameObject?

So my question is, how do you effeciently manage a ton of children and their attributes? Create one master gameObject as a “global” and then on create of every gameobject append each specific type of attribute to a list to see the amount of so and so renderers, and check in each list (of the component) the owner they have stored inside of them (which is automatic… this.gameobject)?

Hmm…

The components are individual classes, they’re not just some attributes, but they always need to be attached to a gameobject in order to exist.
You can reference a component from wherever you want to do so, but in order to come alive properly, they have to belong to a gameobject. That’s why you need AddComponent (or drag and drop while in editor).
The gameobject will store them internally, like already mentioned in previous posts. It actually doesn’t really matter to the game developer how it is done, the engine does it for you behind the scenes.

All you need to know is: you can use GetComponent and AddComponent (and similar methods) to get and add components

Just play around:

Create an empty gameobject and have a look at the inspector. There’s nothing besides the name, tag, layer attributes and the Transform component. The component itself exposes some of it’s attributes as well.

And maybe this is the part which confuses you: In order to define what it’s gonna be, you add components that your gameobject needs to represent a specific kind of gameobject. For example, a light component, or a renderer and meshfilter, or a collider, or all of them.

That’s just how Unity works, it’s component-based. Code-wise you can say it’s composition. You will never be able to define a more specified GameObject class by inheritance (unless you mess with the compiled DLL files).
It’s a sealed class, which means, no class can derive from it.

So a componentXZY can be a part of a gameobject, in other words, the gameobject can have a componentXYZ and that component will usually only exist as long as the gameobject exists. You have access to the component’s gameobject by using

componentXYZ.gameObject

Once again, regarding the latter question: It is really dependant on your usecase. You can do it in many different ways. That’s up to you. You can collect all components of a type in a collection, or you gather all the children in a list and access their components this way. You can also just search for a specific child and a specific component which is attached to that child in order to avoid huge lists.
I’m afraid you have to try different approaches to find the one that fits your needs.

1 Like

It appears I will, hmmmm. What is a GameObject that is a child to another game object considered as to the first game Object is is under? And what about its components?

is it simply a change in name for the object? “ParentName/ChildName” if there are tons of children under one parent just sort them from a list of children and find a variable in each one and test against that object?

//this objects important references
GameObject thisGameObject;
thisClassComponent thisClass;
int thisObjectID; //will reference a length inside of the ParentClassManager , which is a component class of the ParentObject gameobject
int thisClassID; //will reference a length or amount of objects inside of the ParentClassManager , which is a component class of the ParentObject gameobject

//reference parent object
GameObject ParentObject;
//reference the classs that handles all data inside the parent for all children
ParentObjectClassScript ParentClassManager;

//Reference a list of all gameobjects inside of it
List<GameObject> ParentObjectChildList;
//Reference a list of all gameobjects child classes of this kind in it
List<thisClassType> ParentThisClassTypeList;






void SelfInit()
{

	//get references to self
	thisGameObject = this.gameObject;
	thisClass = thisGameObject.GetComponent<thisClassComponent>();

	ParentObject = GameObject.Find("UniqueNameOfParentObjectInScene");
	ParentClassManager = ParentObject.GetComponent<ParentObjectClassScript>();
	
	//get lists
	ParentObjectChildList = ParentClassManager.listInsideForChildObjects;
	
	ParentThisClassTypeList = ParentClassManager.listInsideForChildObjectClassOfThisType;
	
	//add gameobjects then this class to specified lists
	ParentClassManager.listInsideForChildObjects.Add(thisGameObject);
	ParentclassManager.listInsideForChildObjectClassOfThisType.Add(thisClass);
	
	//run a method inside of the ParentClassManager which updates the ints holding a reference to the length of each individual list, or you could just return length manually as the new int values?
	ParentClassManager.UpdateIntCountFromListsLength();
	
	
	thisObjectID = ParentClassManager.CountOfObjectsListInt;
	thisClassID = ParentClassManager.CountOfClassOfThisTypeListInt;


}

is this one of the better ways to attempt to append values to everything you make, child or not? in a heirarchy of objects? I’m trying to figure out in my head how I’ would ekep track of hundreds of isntantiated UI element objects, input fields, sprites, gameobject transform, parents and children of those parents. And I cant see other ways of just trying to figure out ways to access objects in the scene since I must work off the references of gameobjects and a collection of their components someplace where I can ID either one.

Look at the documentation on the Transform Component that is part of every GameObject.

Most all of the above information your are initializing is already tracked by this component based on the structure of the hierarchy of your scene. Parent, child count, accessing children by index, accessing other components relative to this component, it’s all there already. Whether you actually need to access that information on each script component is really going to be up to where and how you handle the control or management of these components

1 Like

Thanks, I guess I dont understand the Transform component. I’ll definately look into it.