First-time programmers usually start learning the trade with the classic Hello World program. From there, bigger and bigger assignments are bound to follow. Each new challenge drives home an important lesson:

The bigger the project, the bigger the spaghetti.

Soon, it is easy to see that in large or small teams, one cannot recklessly do as one pleases. Code must be maintained and may last for a long time. Companies you’ve worked for can’t just look up your contact information and ask you every time they want to fix or improve the codebase (and you don’t want them to either).

This is why software design patterns exist; they impose simple rules to dictate the overall structure of a software project. They help one or more programmers separate core pieces of a large project and organize them in a standardized way, eliminating confusion when some unfamiliar part of the codebase is encountered.

These rules, when followed by everyone, allow legacy code to be better maintained and navigated, and new code to be added more swiftly. Less time is spent planning the methodology of development. Since problems don’t come in one flavor, there isn’t a silver bullet design pattern. One must carefully consider the strong and weak points of each pattern, and find the best fit for the challenge at hand.

In this tutorial, I’ll relate my experience with the popular Unity game development platform and the Model-View-Controller (MVC) pattern for game development. In my seven years of development, having wrestled with my fair share of game dev spaghetti, I’ve been achieving great code structure and development speed using this design pattern.

I’ll start by explaining a bit of Unity’s base architecture, the Entity-Component pattern. Then I’ll move on to explain how MVC fits on top of it, and use a little mock project as an example.


In the literature of software, we will find a great number of design patterns. Even though they have a set of rules, developers will usually do a little rule-bending in order to better adapt the pattern to their specific problem.

This “freedom of programming” is proof that we haven’t yet found a single, definitive method for designing software. Thus, this article isn’t meant to be the ultimate solution to your problem, but rather, to show the benefits and possibilities of two well-known patterns: Entity-Component and Model-View-Controller.

The Entity-Component Pattern

Entity-Component (EC) is a design pattern where we first define the hierarchy of elements that make up the application (Entities), and later, we define the features and data each will contain (Components). In more “programmer” terms, an Entity can be an object with an array of 0 or more Components. Let’s depict an Entity like this:

some-entity [component0, component1, ...]

Here’s a simple example of an EC tree.

- app [Application]
   - game [Game]
      - player [KeyboardInput, Renderer]
      - enemies
         - spider [SpiderAI, Renderer]
         - ogre [OgreAI, Renderer]
      - ui [UI]
         - hud [HUD, MouseInput, Renderer]
         - pause-menu [PauseMenu, MouseInput, Renderer]
         - victory-modal [VictoryModal, MouseInput, Renderer]
         - defeat-modal [DefeatModal, MouseInput, Renderer]

EC is a good pattern for alleviating the problems of multiple inheritance, where a complex class structure can introduce problems like the diamond problem where a class D, inheriting two classes, B and C, with the same base class A, can introduce conflicts because how B and C modify A’s features differently.


These kinds of problems can be common in game development where inheritance is often used extensively.

By breaking down the features and data handlers into smaller Components, they can be attached and reused in different Entities without relying on multiple inheritances (which, by the way, isn’t even a feature of C# or Javascript, the main languages used by Unity).

Where Entity-Component Falls Short

Being one level above OOP, EC helps to defragment and better organize your code architecture. However, in large projects, we are still “too free” and we can find ourselves in a “feature ocean”, having a hard time finding the right Entities and Components, or figuring out how they should interact. There are infinite ways to assemble Entities and Components for a given task.


One way to avoid a mess is to impose some additional guidelines on top of Entity-Component. For example, one way I like to think about software is to divide it up into three different categories:

  • Some handle the raw data, allowing it to be created, read, updated, deleted or searched (i.e., the CRUD concept).
  • Others implement the interface for other elements to interact with, detecting events related to their scope and triggering notifications when they occur.
  • Finally, some elements are responsible for receiving these notifications, making business logic decisions, and deciding how the data should be manipulated.

Fortunately, we already have a pattern that behaves in this exact way.

The Model-View-Controller (MVC) Pattern

The Model-View-Controller pattern (MVC) splits the software into three major components: Models (Data CRUD), Views (Interface/Detection) and Controllers (Decision/Action). MVC is flexible enough to be implemented even on top of ECS or OOP.

Game and UI development have the usual workflow of waiting for a user’s input, or other triggering condition, sending notification of those events somewhere appropriate, deciding what to do in response, and updating the data accordingly. These actions clearly show the compatibility of these applications with MVC.

This methodology introduces another abstraction layer that will help with the software planning, and also allow new programmers to navigate even in a bigger codebase. By splitting the thinking process into data, interface, and decisions, developers can reduce the number of source files that must be searched in order to add or fix functionality.

Unity and EC

Let’s first take a closer look at what Unity gives us up front.

Unity is an EC-based development platform, where all Entities are instances of GameObject and the features that make them be “visible,” “moveable,” “interactable,” and so on, are provided by classes extending Component.

The Unity editor’s Hierarchy Panel and Inspector Panel provide a powerful way to assemble your application, attach Components, configure their initial state and bootstrap your game with a lot less source code than it would normally.

SCREENSHOT: HIERARCHY PANEL Hierarchy Panel with four GameObjects on the right

SCREENSHOT: INSPECTOR PANEL Inspector Panel with a GameObject’s components

Still, as we’ve discussed, we can hit the “too many features” problem and find ourselves in a gigantic hierarchy, with features scattered everywhere, making the life of a developer a lot harder.

Thinking in the MVC way, we can, instead, start by dividing things according to their function, structuring our application like the example below:


Adapting MVC to a Game Development Environment

Now, I would like to introduce two small modifications to the generic MVC pattern, which help adapt it to unique situations I’ve come across building Unity projects with MVC:

  1. The MVC class references easily get scattered throughout the code.
    • Within Unity, developers typically must drag and drop instances around to make them accessible, or else reach them through cumbersome find statements like GetComponent( ... ).
    • Lost-reference hell will ensue if Unity crashes or some bug makes all the dragged references disappear.
    • This makes it necessary to have a single root reference object, through which all instances in the Application can be reached and recovered.
  2. Some elements encapsulate general functionality that should be highly reusable, and which does not naturally fall into one of the three main categories of Model, View, or Controller. These I like to call simply Components. They are also “Components” in the Entity-Component sense but merely act as helpers in the MVC framework.
    • For example, a Rotator Component, which only rotates things by a given angular velocity and doesn’t notify, store, or decide anything.

To help alleviate these two issues, I came up with a modified pattern I call AMVCC, or Application-Model-View-Controller-Component.


  • Application - Single entry point to your application and container of all critical instances and application-related data.
  • MVC - You should know this by now. :)
  • Component - Small, well-contained script that can be reused.

These two modifications have satisfied my needs for all projects I’ve used them in.

Example: 10 Bounces

As a simple example, let’s look at a small game called 10 Bounces, where I’ll make use of the core elements of the AMVCC pattern.

The game setup is simple: A Ball with a SphereCollider and a Rigidbody (which will start to fall after “Play”), a Cube as ground and 5 scripts to make up the AMVCC.


Before scripting, I usually start at the hierarchy and create an outline of my class and assets. Always following this new AMVCC style.


As we can see, the view GameObject contains all visual elements and also ones with other View scripts. The model and controller GameObjects, for small projects, usually contain only their respective scripts. For bigger projects, they will contain GameObjects with more specific scripts.

When someone navigating your project wants to access:

  • Data: Go to application > model > ...
  • Logic/Workflow: Go to application > controller > ...
  • Rendering/Interface/Detection: Go to application > view > ...

If all teams follow these simple rules, legacy projects shouldn’t become a problem.

Note that there is no Component container because, as we’ve discussed, they are more flexible and can be attached to different elements at the developer’s leisure.


Note: The scripts shown below are abstract versions of real-world implementations. A detailed implementation wouldn’t benefit the reader much. However, if you would like to explore more, here’s the link to my personal MVC framework for Unity, Unity MVC. You will find core classes that implement the AMVCC structural framework needed for most applications.

Let’s take a look at the structure of the scripts for 10 Bounces.

Before starting, for those not familiar with Unity’s workflow, let’s clarify briefly how scripts and GameObjects work together. In Unity, “Components,” in the Entity-Component sense, are represented by the MonoBehaviour class. For one to exist during runtime, the developer should either drag and drop its source file into a GameObject (which is the “Entity” of the Entity-Component pattern) or use the command AddComponent<YourMonobehaviour>(). After this, the script will be instantiated and ready to use during execution.

To begin, we define the Application class (the “A” in AMVCC), which will be the main class containing references to all instantiated game elements. We’ll also create a helper base class called Element, which gives us access to the instance of the Application and its children’s MVC instances.

With this in mind, let’s define the Application class (the “A” in AMVCC), which will have a unique instance. Inside it, three variables, model, view, and controller, will give us access points for all MVC instances during runtime. These variables should be MonoBehaviours with public references to the desired scripts.

Then, we’ll also create a helper base class called Element, which gives us access to the instance of the Application. This access will allow every MVC class to reach every other.

Note that both classes extend MonoBehaviour. They are “Components” that will be attached to GameObject “Entities”.

// BounceApplication.cs

// Base class for all elements in this application.
public class BounceElement : MonoBehaviour
   // Gives access to the application and all instances.
   public BounceApplication app { get { return GameObject.FindObjectOfType<BounceApplication>(); }}

// 10 Bounces Entry Point.
public class BounceApplication : MonoBehaviour
   // Reference to the root instances of the MVC.
   public BounceModel model;
   public BounceView view;
   public BounceController controller;

   // Init things here
   void Start() { }

From BounceElement we can create the MVC core classes. The BounceModel, BounceView, and BounceController scripts usually act as containers for more specialized instances, but since this is a simple example only the View will have a nested structure. The Model and Controller can be done in one script for each:

// BounceModel.cs

// Contains all data related to the app.
public class BounceModel : BounceElement
   // Data
   public int bounces;  
   public int winCondition;
// BounceView .cs

// Contains all views related to the app.
public class BounceView : BounceElement
   // Reference to the ball
   public BallView ball;
// BallView.cs

// Describes the Ball view and its features.
public class BallView : BounceElement
   // Only this is necessary. Physics is doing the rest of work.
   // Callback called upon collision.
   void OnCollisionEnter() { app.controller.OnBallGroundHit(); }
// BounceController.cs

// Controls the app workflow.
public class BounceController : BounceElement
   // Handles the ball hit event
   public void OnBallGroundHit()
      Debug.Log(“Bounce ”+app.model.bounce);
      if(app.model.bounces >= app.model.winCondition)
         app.view.ball.enabled = false;
         app.view.ball.GetComponent<RigidBody>().isKinematic=true; // stops the ball

   // Handles the win condition
   public void OnGameComplete() { Debug.Log(“Victory!!”); }

With all scripts created, we can proceed to attaching and configuring them.

The hierarchy layout should be like this:

- application [BounceApplication]
    - model [BounceModel]
    - controller [BounceController]
    - view [BounceView]
        - ...
        - ball [BallView]
        - ...

Using the BounceModel as an example, we can see how it looks in Unity’s editor:

SCREENSHOT: BounceModel IN INSPECTOR BounceModel with the bounces and winCondition fields.

With all scripts set and the game running, we should get this output in the Console Panel.



As shown in the example above, when the ball hits the ground its view executes app.controller.OnBallGroundHit() which is a method. It isn’t, by any means, “wrong” to do that for all notifications in the application. However, in my experience, I’ve achieved better results using a simple notification system implemented in the AMVCC Application class.

To implement that, let’s update the layout of the BounceApplication to be:

// BounceApplication.cs

class BounceApplication 
   // Iterates all Controllers and delegates the notification data
   // This method can easily be found because every class is “BounceElement” and has an “app” 
   // instance.
   public void Notify(string p_event_path, Object p_target, params object[] p_data)
      BounceController[] controller_list = GetAllControllers();
      foreach(BounceController c in controller_list)

   // Fetches all scene Controllers.
   public BounceController[] GetAllControllers() { /* ... */ }

Next, we need a new script where all developers will add the notification event’s names, which can be dispatched during execution.

// BounceNotifications.cs

// This class will give static access to the events strings.
class BounceNotification
   static public string BallHitGround = “ball.hit.ground”;
   static public string GameComplete  = “game.complete”;
   /* ...  */
   static public string GameStart     = “game.start”;
   static public string SceneLoad     = “scene.load”;
   /* ... */

It is easy to see that, this way, the code legibility is improved because developers don’t need to search all over the source code for controller.OnSomethingComplexName methods in order understand what kind of actions can happen during execution. By only checking one file, it is possible to understand the overall behavior of the application.

Now, we only need to adapt the BallView and BounceController to handle this new system.

// BallView.cs

// Describes the Ball view and its features.
public class BallView : BounceElement
   // Only this is necessary. Physics is doing the rest of work.
   // Callback called upon collision.
   void OnCollisionEnter() { app.Notify(BounceNotification.BallHitGround,this); }
// BounceController.cs

// Controls the app workflow.
public class BounceController : BounceElement
   // Handles the ball hit event
   public void OnNotification(string p_event_path,Object p_target,params object[] p_data)
         case BounceNotification.BallHitGround:
            Debug.Log(“Bounce ”+app.model.bounce);
            if(app.model.bounces >= app.model.winCondition)
               app.view.ball.enabled = false;
               app.view.ball.GetComponent<RigidBody>().isKinematic=true; // stops the ball
               // Notify itself and other controllers possibly interested in the event
         case BounceNotification.GameComplete:

Bigger projects will have a lot of notifications. So, to avoid getting a big switch-case structure, it is advisable to create different controllers and make them handle different notification scopes.

AMVCC in the Real World

This example has shown a simple use case for the AMVCC pattern. Adjusting your way of thinking in terms of the three elements of MVC, and learning to visualize the entities as an ordered hierarchy, are the skills that ought to be polished.

In bigger projects, developers will be faced with more complex scenarios and doubts about whether something should be a View or a Controller, or if a given class should be more thoroughly separated in smaller ones.

Rules of Thumb (by Eduardo)

There isn’t any “Universal Guide for MVC sorting” anywhere. But there are some simple rules that I typically follow to help me determine whether to define something as a Model, View, or Controller and also when to split a given class into smaller pieces.

Usually, this happens organically while I think about the software architecture or during scripting.

Class Sorting


  • Hold the application’s core data and state, such as player health or gun ammo.
  • Serialize, deserialize, and/or convert between types.
  • Load/save data (locally or on the web).
  • Notify Controllers of the progress of operations.
  • Store the Game State for the Game’s Finite State Machine.
  • Never access Views.


  • Can get data from Models in order to represent up-to-date game state to the user. For example, a View method player.Run() can internally use model.speed to manifest the player abilities.
  • Should never mutate Models.
  • Strictly implements the functionalities of its class. For example:
    • A PlayerView should not implement input detection or modify the Game State.
    • A View should act as a black box that has an interface and notifies of important events.
    • Does not store core data (like speed, health, lives,…).


  • Do not store core data.
  • Can sometimes filter notifications from undesired Views.
  • Update and use the Model’s data.
  • Manages Unity’s scene workflow.

Class Hierarchy

In this case, there aren’t a lot of steps I follow. Usually, I perceive that some class needs to be split when variables start to show too many “prefixes,” or too many variants of the same element start to appear (like Player classes in an MMO or Gun types in an FPS).

For example, a single Model containing the Player data would have a lot of playerDataA, playerDataB,... or a Controller handling Player notifications would have OnPlayerDidA,OnPlayerDidB,.... We want to reduce the script size and get rid of player and OnPlayer prefixes.

Let me demonstrate using a Model class because it is more simple to understand using data only.

During programming, I usually start with a single Model class holding all data for the game.

// Model.cs

class Model
   public float playerHealth;
   public int playerLives;

   public GameObject playerGunPrefabA;
   public int playerGunAmmoA;

   public GameObject playerGunPrefabB;
   public int playerGunAmmoB;

   // Ops Gun[C D E ...] will appear...
   /* ... */

   public float gameSpeed;
   public int gameLevel;

It is easy to see that the more complex the game, the more numerous variables will get. With enough complexity, we could end up with a giant class containing model.playerABCDFoo variables. Nesting elements will simplify the code completion and also give room to switch between variations of data.

// Model.cs

class Model
   public PlayerModel player;  // Container of the Player data.
   public GameModel game;      // Container of the Game data.
// GameModel.cs

class GameModel
   public float speed;         // Game running speed (influencing the difficulty)
   public int level;           // Current game level/stage loaded
// PlayerModel.cs

class PlayerModel
   public float health;        // Player health from 0.0 to 1.0.
   public int lives;           // Player “retry” count after he dies.
   public GunModel[] guns;     // Now a Player can have an array of guns to switch ingame.
// GunModel.cs

class GunModel
   public GunType type;        // Enumeration of Gun types.
   public GameObject prefab;   // Template of the 3D Asset of the weapon.
   public int ammo;            // Current number of bullets
   public int clips;           // Number of reloads possible

With this configuration of classes, developers can intuitively navigate in the source code one concept at a time. Let’s assume a first-person shooter game, where weapons and their configurations can get really numerous. The fact that GunModel is contained in a class allows the creation of a list of Prefabs (preconfigured GameObjects to be quickly duplicated and reused in-game) for each category and stored for later use.

In contrast, if the gun information was all stored together in the single GunModel class, in variables like gun0Ammo, gun1Ammo, gun0Clips, and so on, then the user, when faced with the need to store Gun data, would need to store the entire Model including the unwanted Player data. In this case, it would be obvious that a new GunModel class would be better.

IMAGE: CLASS HIERARCHY Improving the class hierarchy.

As with everything, there are two sides of the coin. Sometimes one can unnecessarily over-compartmentalize and increase the code complexity. Only experience can hone your skills enough to find the best MVC sorting for your project.

New game dev Special Ability unlocked: Unity games with the MVC pattern.


There are tons of software patterns out there. In this post, I tried to show the one that helped me most in past projects. Developers should always absorb new knowledge but always question it, too. I hope this tutorial helps you to learn something new, and at the same time, serves as a stepping stone as you develop your own style.

Also, I really encourage you to research other patterns and find the one that suits you best. One good starting point is this Wikipedia article, with its excellent list of patterns and their characteristics.

If you like the AMVCC pattern and would like to test it out, don’t forget to try out my library, Unity MVC, which contains all the core classes necessary to start an AMVCC application.

About the author

Eduardo Dias da Costa, Brazil
member since March 7, 2015
Eduardo is a developer with over a decade of experience focused on client and front-end applications. He is always open to learn and take up new challenges that can make him handle new languages and/or technologies. He specializes in computer graphics, image processing, game development, tools development (CLI, desktop, etc.), and UI/UX/front-end development. [click to continue...]
Hiring? Meet the Top 10 Freelance Unity or Unity3D Developers for Hire in March 2019


Great article! Organizing big projects in Unity is always a hassle, and that looks like a solid solution.
A very instructive article providing instant insight. Well written, kudos. I want to develop an Anroid game over the next 4 weekends which is to be a reboot of an ancient simulation game I used to play 13 years ago. It has no graphics, onlly a 2D GUI, so unity would be overkill in my opinion. Do you agree ? I am looking for ways to model the game's "game logic" before wildly jumping into the development. Can you recommend a source for typical patterns ?
Leonardo Amora
Thank you for the article DUDU!
John Ryan
I don't think Unity is overkill for anything, really. It is great for 2D games, and its UI works well. It's ready to build to Android, as well as other platforms with no problem.
Does every scene has own AMVCC model right?
Eduardo Dias da Costa
I use the same application but create 1 root controller per scene. login.unity3d == class LoginController game.unity3d == class GameController
Why does not BallView extends BounceView instead of GameElement?
I'm still confused how to use this sort of architecture structure with the new uGUI introduced within version 4.6. Given what the structure asks for, I'll have to make a separate model for both a Player and PlayerUI which require connections with one another. Is this correct?
Really great article, thanks a lot. I am trying the framework and came across this question: is any form of user input (keyboard, mouse, swipes, taps) a view or a controller in AMVCC, and why? What do you think? Thanks!
Charles Han
Do you think it's possible to share an example with multiple scenes? Thanks!
Atif Ali
Great the AMVCC! I am new to Unity but it is very helpful for me.
Kirill Avramenko
Why code in bitBucket is a different from examples here?
Carlos Sala Samper
Great tip!
Łukasz Michniewicz
I think that code here is just simplified version showing how model, view and controller objects interact with each other, while BitBucket code is generic framework to enforce MVC structure in your project.
Eduardo Dias da Costa
You can start with single few Model View Controller classes. They will be bigger than ideal but will allow you to prototype your game really quickly.
Eduardo Alvarado D
A really good information Eduardo, thank you very much. I will apply this pattern on my game, I really like it!. Thanks
Jan Rabe
The kicker is that EC was developed because MVC is insufficient for a lot of use cases in game development context. Mainly because you want to think about _behaviours_ rather than mere _presentation_ for an object in your environment. In my opinion you've misunderstood the idea behind EC completely. :(
Eduardo Dias da Costa
Both patterns have their strengths. I just said that EC can give too much freedom, and too much freedom in a dev team leads to chaos. I usually use MVC in the top levels of the app. When I reach the actual MVC elements (Player, Game, Enemies,...) I usually start applying EC and create smaller pieces for a more custom Behaviour on each. In Unity MVC is a layer of abstraction on top of EC. For instance, -model [SceneModel] --game [GameModel,JsonComponent,WebComponent] ---player [PlayerModel,JsonComponent] -controller [SceneController] --game [GameController] -view [SceneView] --game [GameView] ---player [PlayerView,MultiplayerComponent,InputComponent,...] Some Model classes re-use the 'JsonComponent' to serialize the data. The hi-level GameModel use a WebComponent to handle the webservices. The MultiplayerComponent handle incoming/outgoing data and applies to its target. The InputComponent receives input and applies to the target. The PlayerView can handle its extra components behaviours and relay these events to Controllers.
Eduardo Alvarado D
Of course!! In any software that have a MVC structure, the view is always like the software's face, and here is where the users interact with the program, so certainly they insert data too.
What was your reason for passing strings for notifications instead of using some kind of C# events?
SMorris Morris
Excellent article, I've bookmarked it and downloaded the source; so thanks a LOT!! I'm trying to implement this correctly and wondered if you could tell me how you'd do this... I have a drone flight app which contains a drone, flight path, waypoints and some buttons. I have a camera button, a path button and a waypoint button. The camera button simply swaps the camera view from following the drone (over the shoulder), to the drone's onboard camera (fpv). The path button simply makes the path visible in the view (show/hide toggle). The waypoint button toggles the visibility of waypoints in the view. So would you create a BtnCameraView, BtnPathView and a BtnWaypointView class, each of which would "notify" the controller class that an event happened. And then from there would the controller then call a CameraView method, or a PathView, or a WaypointView? This is hard to explain but essentially would you create a view class for the path button, AND a view class for the path? The button view notifies the controller which the notifies the path view? Exactly how many "things" become a view. You bounce example is good, but there's not enough detail for me to understand how a more involved app w/UI would work. Any suggestions would be super appreciated. Again thanks so much for this article.
I think the idea here is to extend every gameObject from GameElement regardless if they are in the view, controller, or app. If a new gameObject call CarView was created, it will still extend GameElement, and never BounceView.
Mihail Georgescu
My thoughts exactly. I think events would be cleaner and even and even more faster!
Juan Jose Ruiz Munoz
HI Eduardo. I have a question. I'm using your MVC model. Is working very well, awesome, but when I use 2 or more applications in the scene, the notification only arrives to one of the Controllers... Meaning, if I got DialogApplication and HUDApplication for instance, all the notifications (Dialog, and HUD) goes to Dialog Controller, instead to go Dialog with DialogController and HUD with HUD controller. I reviewed carefully the header of each class... so I don't know if I'm doing something wrong... Cheers!
Eduardo Dias da Costa
You shouldn't have 2 applications in the same scene. For "Dialogs" and "HUDs" I use them as Views. app [ProgramApp] (the same for all scenes) -- splash | home | game [Splash|Home|Game - Model/Controller/View] (one root MVC element per scene) --- ui [Root M/V/C classes for UI] ---- dialog [could exist for all scenes] ---- hud [exists only on game scene]
Juan Jose Ruiz Munoz
Ok, Thanks for your attention. And congratulations again!
Eduardo Dias da Costa
Correcting one thing.. You shouldn't have 2 Applications on the whole project. To handle different scenes you just create 1 root Model View Controller for each scene
Xin Ma
at least it's a great practice for the game ui architecture! and sure for many types of game!
Oleg Kondrahanov
Hello, Eduardo. I tried to take your approach to my first game and got a question. There is randomly generated world and enemies. So for example we need to create a new enemy. We have some prefabs for different enemies which include CombatEnemy script component with a number of stats (damage, defense, hit points), Transform component and a SpriteRenderer component with sprite for this enemy. Let's say we have enemy1 and enemy2 prefabs. In "model" part of the hierarchy there is CombatModel with current enemy field as instance of CombatEnemy. I am a bit confused how to create a view for enemy and how it should look like. When Gamecontroller decides to create new enemy I suppose it should Instantiate new GameObject from a prefab and set current enemy in CombatModel to created object's CombatEnemy component. But that actually means that it draws enemy sprite, is it ok? What part should EnemyView take in this? Who should create it? Probably I am misunderstanding something in this idea and prefabs should look somewhat another. Thanks in advance.
Eduardo Dias da Costa
For this scenario I would create the prefab like this: - enemy [CombatEnemyModel, CombatEnemyController,CombatEnemyView] -- sprite [SpriteRenderer] - Model will hold the data stats for that enemy - Controller would handle detection and local decision for the enemy behaviour - View would hold the reference to the Sprite and change features of it.. together with collision detections to notify the Controller Keeping the SpriteRenderer internal also helps you to change artwork but keep the main scripts for the enemy untouched.
Oleg Kondrahanov
Thanks. Separating SpriteRenderer makes sense indeed
Thank you for your great article, Eduardo Dias da Costa!! This is the most practical article for MVC I've ever seen! Realy helps me lot, Thanks !!
I'm currently following Quill18's great youtube tutorials on a basebuilding game that follows this pattern pretty faithfully I think. Worth checking out for beginners interested in this:
John kent
Hi, Mr Eduardo, such a great article, been wanting this for a long time. I just have a quick question, I tried your framework but can't seem to implement interfaces after creating a controller. IE: if I declare public class ExController : Controller<ExApplication>, IInputObserver , Visual Studio no longer recognizes public override void OnNotification. Any ideas why this might happen?
Eduardo Dias da Costa
Chances are that IInputObserver could have a "OnNotification" functions. But hard to say :)
Mark Macneil
This is super old, but I just stumbled on this and it solved my multi-scene problem perfectly. If you want to use multiple scenes don't base your root application class on the <M,V,C> extension template as shown in the sample in the source repo but rather just use the BaseApplication, create your specific MVC classes for each scene and cast out your model (ie. (MyCustomSceneModel(app.model).CustomField)) as needed. I hit the same issue trying to apply this to multiple scenes but those simple adjustments worked perfectly in my case...hope it helps someone else.
Kevin Erdiza
Hello, Mr Eduardo, Thank you for great article! I'm currently trying to implement this in my project and now have a question the specific one: In my project, I have a script that control the position of an object so it can snap into specific location, similar to when we are moving icons on android or iphone homescreen. Currently, I attach the script on one of my 'View' game object because the script is directly modifying the transform and that's where I'm confused. What should this script be in the this MVC model? the more general one: What if my unity project is not relying oh unity physics and more on modifying kinematic rigibodies? Which transform should be controlled? Is it wise to make the transform part of the model and let controller modify it instead modifying the view, and then let the view copy the model's transform? Sorry if any of my question is kinda confusing, I haven't been using Unity for long and I may have not known many Unity best practices and stuff Thank you!
Nice article! I was actually looking for a Model-View-Presenter example on Unity, which I couldn't find. Anyway, I'm glad at least I found someone else who thinks that the Unity architecture proposal doesn't look very scalable. I was also wandering if this object-script design has anything to do with OOP traits. But even if it does, using traits doesn't seem wide-spread, popular or even worth the hassle - yet. Regards!
Or Avrahamy
Using strings, you can write a generic component with a public string field (or a SeiralizedField) for the event to send or receive. I'd use an enum to prevent typos. However, I think a real pub-sub framework should use any class as a message. This way you could have messages that are ScriptableObjects, pure class or MonoBehvaiours.
I wonder how it goes when you use it in a real project. Fine in the example coz you have three classes, how about when you have 100 and your view takes care of tens of states each with tens of UI references? You have one model class to hold them all, does this mean 100 references in that one class? No could do. You mentioned in a comment below "They will be bigger than ideal but will allow you to prototype your game really quickly.", So this would be mostly not for real projects but more likely for quick to test prototype?
Eduardo Dias da Costa
It can be pretty much anything. Enums or Event classes. I chose strings for simplicity and flexibility. One thing I like to do is tag the noticiadions with "[email protected]". Like: - [email protected] - [email protected] Then in a AudioController do: if(notification.Contains("@click")) Play("click"); Depending on scale, of course an enum is 1000x faster.
Eduardo Dias da Costa
Hey! For this micro-functionality I would do a "component" as it has a "particle-like" feature. I would do a "TransformDragSnap.cs" where it detects and updates drag and drop, then you specify the cell-size to snap the element. It would then use LateUpdate to detect if drag is acting and which 2D cell the mouse is to snap the element.
Eduardo Dias da Costa
lol 2 years.. sorry for the delay, this article is this old :) In game projects I usually have a GameCommandController.cs Where I listen to all kinds of KeyCode or Mouse and then translate to the project's own enum GameCommandType. This class allows you to register "Commands" like: - Left Alt + KeyCode.X [down] -> Command.Pause - Right Ctrl + KeyCode.X [up] -> Command.Reset As I have different game modes, you can setup this component with different layout of commands. This prevents me from having infinite "if(Input.GetKeyDown)" everywhere.
Eduardo Dias da Costa
I usually create 1 prefab per screen, where it contains (lets assume the Home Screen): - Canvas -- Optimization technique -- Makes the screen rendering context sole for it - HomeView -- Contains all references to buttons, lists, RectTransforms -- Perform Show/Hide and Add/Remove items from UI - HomeController -- Receives notifications like, Open/Close -- Loads external data and populate the screen using HomeView - CanvasGroup -- Allow for show/hide transitions ScreenManagerController Allows the management of a list of screen prefabs and do the transition In and Out of the current screens on the UI.
While a good article, this is NOT an example of the use of the MVC Pattern in Unity. An MVC Design Pattern is something else entirely. See the GoF book or Design Patterns on Wikipedia
Zabingo Softwares
This code structure is effective for Unity...I am beginner in Unity. Can you please tell me the following problem... 1. I have one GameController script set on Controller GameObject also there are another two Supporting Controller like Camera and Spawn Controller Script. Initially I register those controller on main GameController and access them. public class GameController : GameHelperElement{ public CameraController cameraCtrl; //Register Camera Contoller public SpawningController spawnCtrl; // Register Spawn Controller } There are large amount of notification on Main GameController, need to be reduce them to the separate Controller. I have a SpwanController Script which have more Module which I access from player like following way void OnTriggerEnter2D(Collider2D col) { if (col.tag.Equals("Spawnner")) { app.controller.spawnCtrl.GenerateRandomObject(); app.controller.spawnCtrl.GenerateColorChanger(); Destroy(col.gameObject); return; } } But like to access it on Notification basis. void OnTriggerEnter2D(Collider2D col) { if (col.tag.Equals("Spawnner")) { app.Notify(GameEventNotification.RandomEnemy, this); app.Notify(GameEventNotification.ColorChanger, this); Destroy(col.gameObject); return; } } But Problem is there... public void Notify(string p_path,Object p_target,params Object[] p_data){ GameController[] controlerlist = GetAllGameController (); foreach (GameController c in controlerlist) { c.OnNotification (p_path, p_target, p_data); } } public GameController[] GetAllGameController (){ GameController[] contrlist = new GameController[1]; contrlist [0] = controller.GetComponent<GameController> (); return contrlist; } I don't Understand how can I set the SpawnController on above Notify System.
Jorge O'Neill
Wow, thank you very much for the concise and extremely well written article!! Really helpful as I'm now exactly trying to adapt a unity game I'm developing to MVC. Still having some trouble though... Let's take your Spider example, which has two components - a Spider AI and a Renderer - how would you treat it? Would you have a single GameObject with these 2 components? If so would this GameObject be treated? As Model or as View? Or would you instead separate ir into two different GameObjects, one for the AI (model) and another one for the Renderer (View)? I would be most grateful if you could help me with this as I’m having exactly this struggle on my own game. Thanks!!
Franck Yin
I'm sorry I know this might be a stupid question but the reason why there are no instantiation for the custom MCV classes inherited from the generic classes you've built accross the entire repo project is because the instances of BounceModel, BounceView ,and Bounce Controller are the scripts in the Unity Editor right ?
Baron Teapot
Yeah when public variables are assigned via the Unity editor, they don't need to be initialised in code. I know, this was a small sticking point for me when coming from a purely code-based environment to Unity. "Why aren't they initialising their arrays?" etc.
comments powered by Disqus
Free email updates
Get the latest content first.
No spam. Just great articles & insights.
Free email updates
Get the latest content first.
Thank you for subscribing!
Check your inbox to confirm subscription. You'll start receiving posts after you confirm.
Trending articles
Relevant Technologies
About the author
Eduardo Dias da Costa
HTML5 Developer
Eduardo is a developer with over a decade of experience focused on client and front-end applications. He is always open to learn and take up new challenges that can make him handle new languages and/or technologies. He specializes in computer graphics, image processing, game development, tools development (CLI, desktop, etc.), and UI/UX/front-end development.