What exactly is the type of an object?

Hi,
I’m just wondering about the part in block.cs where you declare an object “level” of type Level.
But what exactly is the type of an object? Like, if Level is the name of the class Level then are there any relationships between the class Level itself and the object type Level? And if you write “level = FindObjectOfType<Level ();” then would the “level” be the class “Level” or the gameobject “level” or an instance of the class “Level”? (probably not because I don’t see any constructor)
Thanks in advance

2 Likes

Hi,

But what exactly is the type of an object?

I’m assuming you mean this in a generic sense. Let’s put that into a bit of context, let’s say we want an object in our game that represents a person, we can define a class which can store data and also provide behaviour. Mini example of what that might look like;

public class Person
{
    private string _name;
    private int _age;
    private float _height;
}

In the above, we define a type called Person and have added some member variables(fields) which can store some data, in this case, the data that is relevant to the person we are trying to create, so we have a name, an age, and a height. This class isn’t going to do anything at all at this stage, the fields are all private, so nothing other than this class can access them, and it doesn’t have any behaviour (functions/methods).

public class Person
{
    private string _name;
    private int _age;
    private float _height;

    public void Walk()
    {
        // ...
    }

    public void Run()
    {
        // ...
    }

    public void Jump()
    {
        // ...
    }
}

In the above, we have expanded our Person class to now have some behaviour, the person can now Walk, Run, and Jump, fairly standard person traits. We could expose our fields through properties, often referred to as getters and setters, which would enable other objects to interact with it. We would probably also want to consider a constructor, e.g. a method which creates a new instance of our class, which we refer to as an object. In Unity, this is handled slightly different, and you inherit (usually) from MonoBehaviour.

public class Person
{
    private string _name;
    private int _age;
    private float _height;


    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public int Age
    {
        get { return _age; }
        set { _age = value; }
    }

    public float Height
    {
        get { return _height; }
        set { _height = value; }
    }


    public void Walk()
    {
        // ...
    }

    public void Run()
    {
        // ...
    }

    public void Jump()
    {
        // ...
    }
}

In the above, you now have fields, to store the data, properties, which allow interaction with the data, and methods which enable behaviour. The above is an example of a type - in this case called Person.

Like, if Level is the name of the class Level then are there any relationships between the class Level itself and the object type Level?

There can be, if I understand your question correctly. Think of a class as a template, or cookie cutter. You define the shape of what you want to create instances of, those instances being referred to as objects. With the above Person class we could use that to create a horde of people all with different names, ages and heights, and they would be able to walk, run, and jump etc.

You can also have static classes with static methods, you’ll see these often where a class just performs a task as opposed to needing to be an actual instance. The Random class in Unity has a static method named Range, its job is to simply return a value between two other values which you specify. You don’t have a create an instance of the Random class in order to use it, you just call its static method Range.

And if you write level = FindObjectOfType<Level>(); then would the “level” be the class “Level” or the gameobject “level” or an instance of the class “Level”? (probably not because I don’t see any constructor)

If you use the above code, the Unity engine will search through all objects in the scene and return for you the first it finds which is of the type you have specified. So, the type you define in this example is Level, but in order for it to return anything it would be an instance of that type in the scene, e.g. a GameObject with that script attached.

Hope the above helps and there’s some further reading for you below :slight_smile:


thanks for the very helpful answer but I’m having some statements needing to be confirmed
+) When you create a class “Level” and attach the script to the gameobject “level”, it becomes a gameobject of type “Level”. The type “Level” has the same usage like other types: int, bool, doubles,…
+) When you write “level = FindObjectOfType<Level();” then it would return the gameobject level which has the type “Level” which is the one has the script attached to it.

and this is totally random but I’m wondering If create a class “Level” and attach to the gameobject “level” then would the gameobject becomes an instance of class “Level”?

Thanks in advance

thanks for the very helpful answer but I’m having some statements needing to be confirmed

You’re very welcome. :slight_smile:

+) When you create a class “Level” and attach the script to the gameobject “level”, it becomes a gameobject of type “Level”. The type “Level” has the same usage like other types: int, bool, doubles,…

Is this from a lecture? I’ll assume so…

I wouldn’t, personally, say that was 100% true… for example, if you have a GameObject (call it whatever you want), and then attached a script component which is a classed named “Level” but also a script with a class named “Music”, clearly that GameObject cannot be two types…

So, you add multiple script components to a GameObject which can be of different types, and you can use FindObjectOfType<> to retrieve an object. The question that remains here would be, are you returning the component which matches the specific type, or, are you returning the GameObject which has a component of that specific type?

I must say, this hasn’t really ever mattered to me in the past, however, if I had to make a guess at the moment I would suggest that you are returning the component of the specified type. In the same way that the transform component can be accessed without needing to use GetComponent I would image that when you use FindObjectOfType<> and then cast to the specific type, if you use GameObject, despite specifying Level as the type to find, Unity enables you to gain a reference to the parental GameObject of the component that was matched by its type. Handy if you then want to grab references to other objects but normally I find myself only casting to the type that I was specifying anyway, e.g.

LevelManager levelManager = (LevelManager)FindObjectOfType<LevelManager>();

+) When you write level = FindObjectOfType<Level>(); then it would return the gameobject level which has the type “Level” which is the one has the script attached to it.

It would actually return an object of type Object which you would then cast to the type GameObject if this was the desired behaviour.


See also;

Unity - Scripting API : Object.FindObjectOfType

I’m a bit confused. Can I use “Level level = new Level();”? In this way I can still access the “CountBreakableBlocks()” method.

If you have a variable in which you have created the reference by dragging the Level GameObject into the Inspector, or, if you have used FindObjectOfType or GetComponent (if Level is a script component on the same object), then you don’t need to instantiate it with new.

so what EXACTLY does the FindObjectOfType<>(); return? Since you didn’t instantiate any object of class Level then how can you return an object of type Level? Please explain it clearly because I’m very new to unity.

Hi,

So, FindObjectOfType comes in two flavours, the first, which is in the Unity documentation (linked below), is used like this;

FindObjectOfType(typeof(Rigidbody));

In the above example, I am using Rigidbody, but potentially any type can be specified. The typeof() gets the type of the object specified and then uses this to search through the entire scene, checking against every GameObject until it finds a match. It will return the first active object that it finds.

The type which it returns is Object, so you typically use this with a cast, for example;

GameObject level = (Level)FindObjectOfType(gettype(Level));

The cast is done with the “(Level)” part of the syntax in front of the FindObjectOfType method. You can also use “as” after the method to cast, as an example;

GameObject level = FindObjectOfType(gettype(Level)) as Level;

So what is the difference? The first approach will throw an exception if the cast fails, whereas the second approach will return null, which you could then check for.

The second use of FindObjectOfType uses generics, interestingly this doesn’t seem to appear in the documentation, however, you use it like this;

Level level = FindObjectOfType<Level>();

In the above, you are specifying the type as Level, the returned type of this method call will be Level if an object is found, or, null if it is not.

With regards to instantiation, FindObjectOfType is searching through the scene for active objects, as such, they will already be instantiated.

The use of any of the Find methods is slow, as it has to traverse the entire scene. Ideally, you would limit the use of these methods calls, certainly not placing them within an Update method. You tend to see them being used perhaps in Awake or Start methods, where a reference is made to the object in the scene and then it lives on as a member variable of the class in question, accessible by any of the methods in that class.

For example;

using UnityEngine;

public class Example : MonoBehaviour
{
    Level level;  // member variable to store the reference to our "level"

    private void Start()
    {
        level = FindObjectOfType<Level>();  // method called once within Start to get the reference
    }

    private void NewGame()
    {
        level.NewGame();
    }

    private void Restart()
    {
        level.Restart();
    }

    private void Quit() 
    {
        level.Quit();
    }
}

In the above example, you could consider this class reacting to the player input after their last life is lost. Three buttons are displayed, restart for restarting the current level, new game to start all over again, and quit, to quit the game.

The level member variable is available to all of this methods but the reference is only made once in the Start method, as opposed to being called in each method.

Note, the example with the Rigidbody is a bit noddy, I can’t recall ever searching through a scene to find the first GameObject that has a Rigidbody, normally you’ll be looking for something specific and then using GetComponent perhaps to get a reference to the specific component on that GameObject to interact with.

I hope the above is of some use. :slight_smile:


See also;

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms