Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

MonoBehaviours, when to use or not

Discussion in 'Scripting' started by eco_bach, Feb 3, 2017.

  1. eco_bach

    eco_bach

    Joined:
    Jul 8, 2013
    Posts:
    1,601
    If your class doesn't modify any game object directly or make use of coroutines , but perhaps uses the Update method, is that enough of a reason to make it a MonoBehaviour?
    Wouldn't it be better to simply make Update public and call it from the Update of another MonoBehaviour or use System.Timers.Timer? And then instantiate this class when needed as a new instance or Singleton?

    Just wondering whether overuse of MonoBehaviours is a lazy coding practice that can make applications harder to maintain, debug and even lessen performance.
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
  3. MV10

    MV10

    Joined:
    Nov 6, 2015
    Posts:
    1,889
    You'll run into threading complexities using System.Timers.Timer -- ones that likely aren't worth dealing with for the type of optimization you're talking about. And speaking of optimization, the blog post linked above is a good starting point for thinking about this -- but plenty of games ship every day without this type of optimization, so the usual guidance about avoiding premature optimization applies.

    That being said, it is often useful to build a generic event-management system, so if you're already doing that, it's pretty trivial to lump Update, FixedUpdate, and LateUpdate into that. (You don't want to put Start in there, only Unity can call Start at the right point in an object's lifecycle.) It's also nice if you need a way to control event sequence or prioritization, to arbitrarily activate/deactivate certain events, and so on.

    For those reasons I tend to use a simple custom event manager even if I don't need it for performance reasons.
     
  4. eco_bach

    eco_bach

    Joined:
    Jul 8, 2013
    Posts:
    1,601
    Thanks. Regarding threading I've had good results using UnityThreads(one of several workarounds to communicate with the main thread). Are you saying in general that threads should be avoided in Unity? I thought they are a good thing performance wise.
     
  5. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Performance-wise it's always hard to tell. It depends on the scale of your project, your coding skills/knowledge/ techniques.

    You can actually create whole modules that have nothing to do with Unity and update them with one MonoBehaviour that manages the execution at different points in time.
    It has its benefits as you can design the whole system to be an - in itself - closed, self-maintaining system that has well-coordinated creation/setup and disposing/destruction behaviour. Takes years or even decades to be able to create such systems and you can always improve - a never ending learning process.
    One of the supreme disciplines (with so many different aspects and approaches) in software engineering. I wish I was much better in this :(

    Now if you look at that with Unity's features in mind, like serializable values which are easily tweakable in the inspector, you just loose a lot of freedom especially if you look at it from a designer's point of view... and that can be a pain as you might want to provide the freedom of wiring and configurating your stuff in the inspector.
    ScriptableObjects can help here a lot. They're underrated and I personally feel dumb that I (for quite some time at least) thought I might not find a usage for them :D.

    You can also do it the other way around and make everything a MonoBehaviour. But this is simply overkill if you have complex scenario, because this can get out off hands pretty quickly, too. It can be less performant than an alternative approach and every Unity object is basically a native C++ object with a corresponding C# "wrapper" / "accessor" or however you want to call it. But that does not really matter in many situations, again it depends on scale/complexity of the project and target platform etc.

    Anyway, other tradeoffs: It already starts with the fact that you have access to any Unity Object directly, even if it's not meant to be accessible... or even worse, it'll be a side-effect that happens due to another operation.
    Think about the Destroy() method. Nothing prevents you or a team member from a direct call to GetComponent<..> and a subsequent Destroy(...), just as an example. Sure, you can always tell someone to not do X with object Y, if A & B | !C.

    So you have to work against that by ensuring everything's setup as you need, which might result in extremely defensive coding styles. It's more or less an overhead that could be avoided, always depends what it takes to check the current state and get it back into a valid state, if necessary.
    Simply put that'd be an open system with lots of freedom for designers (in regards to Unity features), but also lot's of potential weaknesses when it comes to coding.

    That's only one of many things to keep in mind when it's time to decide what has to be a MonoBehaviour or not.

    Long story short: There's no general rule... One the one handthere's the flexibility, you have to decide whether or not you need the inspector features and in which depth of detail, on the other hand there are always drawbacks that you have to think about.
     
    Last edited: Feb 3, 2017