Unity is a good game development tool and honestly I like most of its features. However the code framework is awkward to use on big projects where code maintainability is of fundamental importance. As you may have guessed, the following considerations in this article do not apply to simple projects or projects developed by one or two coders. For these specific cases, Unity is good enough. The arguments in this article apply to relatively complex projects developed by a medium-big team.

After years of analysing the intrinsic issues of the Unity framework, I realised that they all share the same root: the way Unity injects dependencies inside entities, or better saying, how Unity makes this natural process very difficult.

A dependency can be defined as an object needed by another object to execute its code. If a class A needs the instance of a class B to execute its code, B is a dependency for A. When B is passed into A, we say that the dependency B is injected into the object A.

The problem

Unity code framework is designed around the Component Entity pattern. A component based entity framework brings many benefits: pushes the users to favour composition over inheritance, keeps the classes small and clean focusing on single responsibilities, promotes modularity. This is in a perfect world.

In Unity, the Entites are called GameObjects and the Components are based on MonoBehaviour implementations. Components add “behaviours” to Entities and theoretically they should be perfectly encapsulated. The Entity Component structure relies on the fact that components define the whole entities logic. In theory:

  1. MonoBehaviours must operate within the GameObjects they are attached to. This is needed to ensure that encapsulation is not broken, as it shouldn’t be needed to. Components, by design, must handle only the Entity they are attached to.
  2. MonoBehaviours are modular and single responsibility classes reusable between GameObjects.
  3. The behaviour of a GameObject should be extended adding MonoBehaviours instead of adding code to an existing MonoBehaviour. One component must add one behaviour only to encourage modularity.
  4. GameObjects should not be created without a view such as a mesh or a collider or anything that is actually an entity in the game.
  5. MonoBehaviours can know other components on the same GameObject using GetComponent, however they cannot know MonoBehaviours from other GameObjects. This is still part of the framework design.

The first three points are obvious, even to who has never heard about Entity Component frameworks. The Components design allows to add logic to an entity without using inheritance. We can say that instead to specialize the behaviour of an Entity vertically (usually specializing classes through polymorphism), Components allow to expand behaviours horizontally. This is not the place to talk about it, but in case you didn’t know, composition over inheritance is a well known pattern which benefits have been proved extensively. The great thing about an Entity Component framework is then that composition comes naturally, without any particular effort. Smaller is the component, easier will be to reuse it, that’s why giving a single responsibility to each component will promote modularity.

The fourth point may seem an arbitrary rule, but Unity entities by default implement the transform class, implying that the object must be placed in the world. What’s the point to have a Transform by default if then it’s not used? Having a complex hierarchy in Unity doesn’t come for free, all the transforms must be computed hierarchically, therefore an extra GameObject is an extra matrix multiplication to execute every frame.

Last point starts to uncover the real issue. MonoBehaviours are meant to add behaviours on the GameObject that they are attached to and consequentially Unity can’t provide a clean way to let GameObects know each other without resorting to awkward solutions. The other problem is that Unity asks to the user to use MonoBehaviours even when the logic to code is not related to an Entity at all. For example: let’s say there is an object called MonsterManager in the game world which must know the monsters that are still alive. When a monster dies, how can this object know it?

Currently there are 2 simple solutions to this problem:

  1. MonsterManager is a Monobehaviour created inside a GameObject that has no view. All the monsters will look for the MonsterManager class using the GameObject.Find or Object.FindObjectOfType function inside the Start or Awake methods and add themselves into the MonsterManager. MonsterManager could potentially listen to a Monster event to know when it will die.
  2. Another alternative is that MonsterManager is a Singleton and it’s used directly inside the Monster Monobehaviour. When a monster dies, a public MonsterManager function is called.

both cases are needed to solve the same problem: Inject dependencies. In the case A, MonsterManager is a dependency for the Monster objects. The Monster objects cannot add themselves in the MonsterManager if they don’t know the MonsterManager object. In the second case, the dependency is solved through the use a global variable. You may have heard that global variables and singletons are very bad to use and you may not have fully understood why yet. For the moment, let’s focus on the practical aspects of these solutions:

What’s wrong with GameObject.Find

Beside being quite a slow function, GameObject.Find is one example of how awkward the Unity Framework is for big projects development. What happens if someone in the team decides to rename the GameObject? Should GameObjects renaming or deletion been forbidden? GameObject.Find can lead to several run-time errors that cannot be caught in compiling time. This scenario could be really hard to manage when dozens of GameObjects are searched through this function. GameObject.Find and similar functions should be definitively abolished by the Unity framework.

What’s wrong with the Object.FindObjectOfType

How should the MonsterManager object be injected inside the Monster class then? There is actually another solution: calling the function Object.FindObjectOfType. However, what is FindObjectOfType? Object.FindObjectOfType could be seen as a wrong implementation of the Service Locator Pattern, with the difference that it is not possible to abstract the implementation of the service from its interface. This is another problem of Unity framework, which I will now briefly hint at, but that would need another entire article, Unity discourages the use of interfaces. The interface is the most powerful concept at the core of every well designed code. Instead to push the coders to use interfaces and therefore abstraction, Unity pushes the coder to uses Monobehaviour, even when the use of Monobehaviour is not necessary.

What’s wrong with the Singleton

Singleton is a controversial argument since the pattern has been invented. I am personally against the use of Singleton; every single Singleton class I have encountered so far, led only to design problems hard to fix through refactoring. However if you ask me why I am against the Singleton, I will not answer you with the usual answers (they break encapsulation, hide dependencies, make impossible to write proper unit tests, bind the code to the implementation of a service instead of its abstraction, make refactoring really awkward, usually create memory leaks), but with the hindsight of the practice: your code will become unmanageable. This because the use of Singletons comes without any design constriction that, while apparently makes the coder life easier, will make it a hell later on, when the code turn in to an incomprehensible blob without a structured flow (spaghetti code). Projects developed by one of two coders wouldn’t experience the problem at first or ever (for example, if the project doesn’t need to be maintained over time), but mid-size projects will pay the consequences of wild design when it’s probably too late for refactoring. Think about it, you can use Singletons everywhere, without limits, without rules. What would keep a coder from making a total mess out of it? Common sense? Let’s not fool ourselves, common sense doesn’t apply when release deadlines approach fast.

If this is not enough to dismiss Singletons think of this: what is a Singleton if not just another way to inject dependencies? When you don’t have any other choice than singletons, the real problem becomes how to manage the states of these classes when encapsulation is broken. Singletons normally rely on public functions, public functions that usually change states inside the Singleton itself. When the singleton is used recklessly in several parts of the code, it becomes very hard to track when and how these states change. Refactoring becomes tremendously risky because changing the order of the call of the public functions of the same singleton could mean finding the singleton itself in an unexpected state. The biggest problem about Singleton is then the fact that they cannot be designed with Inversion of Control in mind. You are always forced to write functions like IsSingletonReady() or DisableThisSpecificBehaviour() or AccessToThisGlobalData(), leaving the control of the internal states to external entities there are hard to track, especially due to the Singleton global variable-like behaviour.

Let’s be clear, the main reason why dependencies are injected is to let objects communicate between each other. Communication is impossible without any form of injection. Therefore while in some rare case, the use of a Singleton could be acceptable, you can’t work with a framework that won’t let you use any other kind of injection. While it’s feasible, it’s totally unreasonable to solve all the kind of communication problems through singletons.

The solution

There are 3 ways to resolve dependencies: using the Service Locator pattern, injecting dependencies manually through constructors/setters, exploiting reflection capabilities through an IoC container and, obviously, using Singletons. Disregarding Singletons, I do not like the Service Locator Pattern because the SLP itself is a singleton (or a static class) and this could lead to some severe limitations compared to the IoC container solution. Since Unity doesn’t have a starting place where dependencies can be created and injected, manual injections become quite hard and basically impossible without a good understanding of the Unity limitations.

Therefore a good solution available (but not the only one as we will see later on in this article series!) is to use IoC containers. Another article is needed to explain what an IoC container is, therefore I will give a first simple definition: An IoC container is a…container that creates and contains the dependencies that must be injected inside the application objects. It is called Inversion Of Control because the design is thought in such a way that the objects are never created by the user, but they are lazily created by the container when they are needed.

There are several IoC containers out there, a lot written in c# as well, but practically no one works in Unity and most of all, they are damn complicated*. For these reasons I decided to create an IoC container for Unity trying to keep it as simple as possible. Actually creating a basic IoC container is pretty straightforward and everybody can do it, my implementation has just a few tweaks that makes it simple to use with Unity projects.

Conclusion (for this article)

The second part of this article (including source code) is available here: http://blog.sebaslab.com/ioc-container-for-unity3d-part-2

I strongly suggest to read all my articles on the topic:

*Since when I first wrote this article, new IoC containers have been developed. The best ones out there are StrangeIoC, ZenInject and Adic. Google them, it’s worth it.


  1. Avatar

    please continue with the next article =). I was searching for that for few days

    1. Avatar

      Hi, thanks for the comment.

  2. Avatar

    Hey Sebastiano,

    I have to admit I never used an IoC container before, and I would really be curious to see a continuation to this article, to learn more and maybe change my current design patterns.

    As of now, my solution to the problem is to usually keep my [Level] class as one of many “main” MonoBehaviours of an empty “Brain” GameObject, and then go through a global Notificator (which is the only singleton in my project) that every class uses to send events. Then I just listen to [MonsterBornEvent] / [MonsterDieEvent] from the [Level] class.

    1. Avatar

      Svelto tends to solve this problem with event dispatchers, avoiding a “java-like” EventBus singleton for all the objects intercommunication. (please Sebastiano, correct me if I am wrong!)

  3. Avatar

    Nice article. I’m using a type of IoC by myself and I think it solves most of the described problems well.
    The Object.Find method also have the disadvantage that it looks through all gameobjects in a scene, so this is terribly slow and should not be used easily (may as well apply to Transform.GetChild).
    The singleton pattern may be controversal, but it is imho a valid way to bypass some of these problems for smaller projects, though it’s not a fitting solution for larger projects.

    So I’m looking forward to your next chapter of the article 🙂

  4. Avatar

    I am quite interested to see an IoC container for Unity3d, as I have been looking around to find one that does work with it. Thanks for your efforts, and sharing them (possibly) with others!

  5. Avatar

    I don’t get it why not just use events?

    Also have you tried Ninject? I’m looking to use it for my future Unity3d projects.

    1. Avatar

      I do use events, but events are not suitable to solve all the communication issues. Moreover two instances must know anyway each other to setup the events communication (unless you use singleton event bus, which I loathe). I actually wrote a little post about events and commands (I use commands widely as well). Another technique I like, but I do not use much, is the mediator communication.


    2. Avatar

      Ninject does not work out of the box in Unity. You can anyway use Uniject https://github.com/banderous/Uniject that is a working version of ninject for Unity. I do not use it because for me containers must be kept simple, this stuff is utterly overcomplicated.

      1. Avatar

        I thought you started out right from Uniject at start, but soon realize what you are stating here: that framework is way more complicate to digest than your.

  6. Avatar

    Yeah, actually I am also wondering why you aren’t using events for communicatiing stuff. Reasons for that?

    1. Avatar

      Hello Dominik, I just answered Peter question that unluckily I did not notice before. Thank you for the comment.

  7. Avatar

    I’ve wanted to try IoC but never had the guts try it.
    Thanks you for this article!

  8. Avatar

    thanks a lot

    1. Avatar

      Hi in receving emails of links to your blog in latin. Maybe it was hacker?

      1. Sebastiano Mandalà

        I installed a plugin that added some fake posts in the blog. It may have been that.

  9. Avatar

    +1 Great stuff you mentioned there! Particularly your points about how GameObjects and MonoBehaviours should be implemented. I’ve had lots of issues before with my GameObjects setup. I wasn’t doing that much wrong ‘seemingly’ but now reading this and thinking back, I see why… Thanks for the article!

  10. Avatar

    Fantastic article that made me start using IoC on Unity in a more organized fashion! (Although I always used IoC on systems development, I had not tried to use it with a dedicated container on Unity until reading this.)

    Upon your proof of concept, I ended up creating a fully IoC container (that grew so much that deserved being released!): https://github.com/intentor/adic/

    Anyway, thanks for the great couple of articles!

    1. sebas77

      Thanks André..I will soon blog another article, which clarify very important aspects related to IoC principles. Meanwhile I have tweeted your work 😀

      1. Avatar

        Thanks for the reply and sharing! =D

        And I’ll be waiting eagerly for your next article! I’m sure it’ll bring some interesting facts… and new ideas about IoC!

  11. Avatar

    I don’t agree that GameObjects should not be created without a view. It’s useful to have GameObjects without a graphical representation for structuring your game object tree, simplifying transforms and providing logic acting on groups of game objects.

    1. Sebastiano Mandalà

      Agreed, but honestly if you create GameObject to manipulate Transforms it’s still a view. My reasoning applies for GameObjects with Monobehaviours that just handle logic outside the GameObject itself, like a manager. Your examples are all valid, except the last one, in case you are talking about a manager of gameobjects.

  12. Avatar

    “It is called Inversion Of Control because the design is thought in such a way that the objects are never created by the user, but they are lazily created by the container when they are needed.”

    This was actually the most interesting and intriguing part when trying to work out some features on the Svelto.ECS example

  13. Avatar

    [..] “Having a complex hierarchy in Unity doesn’t come for free, all the transforms must be computed hierarchically, therefore an extra GameObject is an extra matrix multiplication to execute every frame.” [.. ]

    So many people doesn’t realize this fact and think that many gameobjects come at no cost.
    That’s also why object pooling helped so much in developing a mobile game for iPad in 2012.
    We just needed 20 – 30 recycling bullets for the whole scene even with dozen of turrets. The scene never needed more than that amount of bullets concurrently.
    Even if the feeling on screen was like for thousands of them. (the speed of laser sci-fi bullets helped :P)
    In my modest opinion, the only place for having many transforms in the hierarchy, is a fully-fledged complete and articulated 3D character, where the bones transforms, help keeping external objects attached to the character properly (weapons, badges, belts, clothes..etc..)

    The workaround many coders used in the past to circumvent this was to generate structures and objects within a class, without to instantiate anything in the scene.
    While this might be convenient for some cases, it is useless when you want to generate GameObjects and not just objects, which can contain many other monobehavior components.
    The best workaround Unity could found about this problem during its development was a very fast and efficient way to SetActive(true/false) the GameObjects, saving the game cycle from computing them, and that’s the area where object pool managers available around were playing their role and getting the advantage over an Instantiate and Destroy approach which is well known to cause memory leaks and also bad for the big spikes on slower platforms (mobile) with every prefabs Instantiate().

    Using Svelto ECS and its Factories and Engines concept, solves the issue even better than a simple abstract class which plays the ObjectPoolManager role, instantiating and recycling what is not needed in the scene, because effectively, you are not pre-spawning objects in advance, like you would be doing for a mobile game, to avoid the spikes, but you are controlling everything from abstracted classes, that, through Implementers, generate what you need at runtime.

    Now Unity 5 offers a GPU instantiation shader, I didn’t play with it yet, but it sounds like the feature every other engine had, but Unity.
    I think this would change a lot the “number of object / number of matrix computations” slowness, but only some tests could tell.

    Apology for the long rant, but it’s late, and I could have written some heresy here, forgive any you might find 😉

  14. Avatar

    Nice article 🙂

    1. Sebastiano Mandalà

      thanks Gwaredd, did you read the whole series (7 articles)? We are not using IoC container anymore nowadays, gonna write an article about it soon. Our new projects use only Svelto.ECS now

      1. Avatar

        Lemme guess, ScriptableObjects? 😉

        1. Sebastiano Mandalà

          nope, but you should know by now 🙂

Leave a Reply