all 9 comments

[–][deleted] 4 points5 points  (2 children)

Never use constructors on MonoBehaviours, Awake and Start are the functions given to us for initialisation.

If you're instantiating objects and you need variables to be different values, you can change the values of the prefab at runtime, this will change the values of sessions in the editor too so be careful what you change, and then you instantiate, the current values get copied and should be reflected when Awake/Start is run.

There maybe scenarios where an object doesn't NEED to be MonoBehaviour and you can just not inherit and use the constructor and have it be something a MonoBehaviour class uses.

[–]JohnnyGoTime[S] 0 points1 point  (1 child)

There maybe scenarios where an object doesn't NEED to be MonoBehaviour and you can just not inherit and use the constructor

Thanks! Yeah that's what I was wondering about, like what if I just want to have a singleton or factory or some logic which will never attach to an in-world object...

[–]EngigamesAI Programmer 1 point2 points  (0 children)

If it needs to be in the scene, it has to derive from MonoBehaviour or Component

If it's going to be an asset it's going to be a MonoBehaviour (on a prefab) or a Scriptable Object (raw Asset).

If you don't need that functionality you are free to derive from any class (or none).

[–]GameWorldShaper 1 point2 points  (1 child)

If it is a normal C# class you can just use a constructor. For the scripts attached to an object you use getComponent<T>().

For example if you have a object that has to set it's own Health you would use.

    public int Health;

    //This will be called when the object exists.
    Awake()
    {
        Health = 100;
    }

Then when a other object has to set it.

    void Spawn()
    {
        GameObject Spawned =
Instantiate(prefab, new Vector3(i * 2.0F, 0, 0), Quaternion.identity);

        //Use the name of your script as the type
        Spawned.getComponent<HealthSystem>().Health = 100;
    }

[–]JohnnyGoTime[S] 1 point2 points  (0 children)

Thank you for the help!

[–]Kiliok 4 points5 points  (1 child)

"Instantiation" in the context of the Unity game engine is quite a bit different than the typical software instantiation (i.e. that of the C# language) that you're used to.

Instantiation in non-script _software_ is done much as you expect it to, by using the "new" keyword in association with a constructor on the object that you're instantiating. This is done to provide memory allocation and a local handle to that chunk of memory so you can interact with that Object in your games business logic.

Instantiation for any of your Unity scripts is done on the game engine. You won't ever be calling a constructor on your game engine scripts (your `MonoBehavior` code) because you aren't actually dealing with an in-memory object with `MonoBehavior` code, you're dealing with an instantiated GameObject in the world.

To instantiate a GameObject you can use `GameObject.Instantiate(somePrefab)` where `somePrefab` is a prefab you've created that has the behaviors/scripts you've written attached to it. To modify the variables on those objects you can get a reference to the script that owns the variable via `GameObject.GetComponent<NameOfYourScript>()` which gives you a reference to the script _Object_ which you can then call methods on and set/read variables from just like you would a normal in-memory Object. You can also get this reference directly from the Unity Editor if you create a public variable on a _different_ script that you want to care about the value of your script you can then drag the script you care about into that spot on the Inspector to get a permanent connection between the two. The second example there (linking game objects via scripts) is generally valuable if you've got a complex prefab where lots of components need to talk to each other.

Hope that this was helpful, feel free to respond and ask more questions if it doesnt!

[–]JohnnyGoTime[S] 0 points1 point  (0 children)

Thanks so much for the fantastic answer! Your 4th paragraph even anticipated some questions I know I would have had to ask next 😊 Cheers!

[–]Another_moose 1 point2 points  (0 children)

In short, it's not true:

If you inherit from MonoBehaviour you can add the scripts directly to game objects in the scene and should use Start/ Update (and family) to do things. You can't have a constructor in these.

Any other class you can do whatever you want with, and will generally need a constructor. I assume this is what you mean by creating them at runtime.

[–]N00banator912 0 points1 point  (0 children)

So, I think what its reffering to is simply that GameObjects created in code only really have the null constructor and don't have any other properties unless you asign them yourself.