OOP Conceptualization in Unity

Hi - I’m a newcomer to Unity, and I’m having trouble understanding how Object-Oriented Programming works here. I come with some experience of Java, so I largely understand what OOP is - or so I think.

I always understood that OOP centered around objects that were instantiated from classes and their interactions between one another. But here, that seems not to be the case - GameObjects are modeled by classes themselves, not instances of them. Then what is the purpose of constructors and instantiation from classes, and etc?

I apologize if I sound dumb, but I’m a little confused. Could someone help me?

A common mistake with OOP is to think that inheritance hierarchies are the way to accomplish everything. That is the commonly taught and explained version of OOP because it is simple and gets the salient points across. However, as things become more complicated, you should begin favoring composition over inheritance - which is EXACTLY how Unity works. You add components to a GameObject in order to define it’s behaviours. There is nothing about this that is not OOP. You can still use inheritance within the components, but all a GameObject represents is a container for components.

Constructors have nothing to do with OOP - they are a byproduct of language design. It so happens that certain OOP concepts can be easily implemented with the help of constructors, but they are not needed. For anything that extends MonoBehaviour - Unity takes control of the constructor. You should not call the constructors yourself. However, you can still do any initialization you need through the Awake/Start/OnEnable functions. You do not need access to the constructor.

Unity can use OOP just as much as Java or any other programming language - it is just modeled in a slightly different way. Unity pushes you towards composition, which is generally preferred over inheritance, and is still a well used concept in OOP design. Furthermore, composition works VERY well for games. With games you very often run into “diamond inheritance” situations, such as:

      Enemy
        /   \
   Mage     Fighter
        \    /
     Battle-Mage

This seems to require multiple inheritance, which is prohibited in most OOP designs for a plethora reasons. Composition can model this very easily - give a GameObject an Mage and Fighter components and now it is a Battle-Mage.

Remember that OOP is a concept to help you reason about code - it is not a necessity. Sometimes, OOP makes a mess of code that could be very easily modeled in a different way. If you write some code that does not follow OOP conventions, just make sure you are doing so for a clear reason. Have a clear design - whether it’s OOP, functional, procedural… it does not matter.