Unity — Game Architectures — Part 3

Samuel Asher Rivello
9 min readApr 11, 2021

--

Unity is a powerful suite of tools (Project IDE, Code IDE, run-time) for game development.

I have explored many architectural approaches to game projects. Architecture is a hot topic in Unity — especially related to scaling up to larger Unity game projects.

I am a Unity Game & Tools Developer with over 20 years of game development experience. I am available for hire (Remote, Contract).

SamuelAsherRivello.com

My architectural background includes many frameworks. Highlights include heavy usage of Robotlegs (I even contributed to the project and drew the official diagram), PureMVC (I was the technical editor for the O’Reilly book on it), and PushButton (I published related articles for Adobe). I also presented and taught about the three at conferences and weekend workshops. Of these, only PushButton is a game-specific architecture, but all can be applied to games.

What are the qualities of good gaming architecture? Most architects applaud solutions that are flexible, readable, D.R.Y., testable, orthogonal, and “refactorable” (at an acceptable cost). I will discuss the philosophy of design in a future post, but for now, I simply list the major pros and cons of each approach.

Update: After completing all the research below, I created a new custom architecture for Unity 2019/2020.

Checkout Unity Game Architectures — Part 1 for more info!

Unity Bowling

A simple bowling game is recreated from scratch for each of the architectural approaches found below.

I review some common approaches and a few novel ones. For each, there are images, details, and an example with full source code.

Table of Contents

  1. No Manager
  2. EmptyGO
  3. SimpleGameManager
  4. uMom
  5. Custom MVCS
  6. StrangeIoC

1. No Manager

This is your most basic approach. First-time Unity developers often start with this technique. Here you put the bowling ball code on the bowling ball, the bowling pin code on the bowling pin, and the ‘game win vs game loss’ code on something random, like the bowling ball too.

Because Unity’s ‘component-based’ approach is so intrinsically awesome (reusable code ‘components’ sit on 1 or more GameObject ‘entities’) you can indeed get very far using this approach. If you are coming from a hierarchical approach to gaming, learning the component approach can be a challenge and your first projects may be of this ‘No Manager’ approach here in #1 or soon evolve to the ‘EmptyGO’ approach we see below in #2.

Diagram

Hierarchy

Type: Component-based

Pros:

  • There are MANY free, useful tutorials created using this “No Manager” approach. So it’s easier to learn the basics of Unity this way.
  • Flexibility for prototyping
  • Intuitive for beginners, e.g. “Bowling-pin code goes on the bowling-pin”

Cons:

  • It is the very definition of spaghetti code
  • Very low scalability for teams (of 3 or more)
  • Very low scalability for projects of intermediate or high complexity.

2. Empty GO

This is a slight evolution beyond #1 above. Still, you put the bowling ball code on the bowling ball, and the bowling pin code on the bowling pin, BUT you try now to put all the rest of the code which has no visual representation in the world onto an invisible or ’empty’ GameObject (GO). Hence the name ‘EmptyGO’.

This technique still has a lot of drawbacks, but at least we begin to see game logic more centralized (on that EmptyGO). This aids readability for newbies working on your project, or for you after you return to an older project after a long time. You don’t need to hunt around everywhere to find your core code — most sits there on the EmptyGO.

Diagram

Hierarchy

Type: Component-based

Pros:

  • More readable (than #1 above)
  • Good mix of flexibility for prototyping (yet not AS much spaghetti code as #1 above)
  • Intuitive for beginners, e.g. “Bowling-pin code goes on the bowling-pin”

Cons:

  • Less testable
  • Less refactorable (since less code is likely to be properly abstracted, decoupled, and reusable when compared to 3,4,5,6 below)
  • Communication and referencing between GameObjects is likely too brittle (e.g. using GameObject.Find() or inspector target references)

3. Simple Game Manager

Probably the most mature technique which is in WIDE usage within the free tutorials and sample projects you find in the community is something like my SimpleGameManager technique. Imagine the ‘EmptyGO’ from #2 above, but now it’s a persistent (between scenes) Singleton.

Code still exists directly in the GameObjects in the world, but whenever possible it calls centralized code [e.g. SimpleGameManager.Instance.playSound("GunShot"); ] It's a good approach and an appropriate (simple) solution for many small projects.

Diagram

Hierarchy

Type: Component-based w/ Manager

Pros:

  • Ultra-fast setup (but with minimal functionality). It’s more of a racetrack — where YOU must supply the racecars.
  • Persists between scenes, and if it’s not created it will create itself as soon as it is referenced (because it’s a Singleton).
  • Ideal for prototypes (but thus not scalable)

Cons:

  • It’s not plug-and-play per se. The current workflow is to import the package and EDIT the core class, rather than use/extend.
  • Not D.R.Y.
  • Less testable. Much of your code STILL sits around on various GameObjects (like in 1 & 2 above).

Sample Game

4. uMOM

My (unreleased) uMOM Asset Store project arose from a problem inherent in Unity. There is no default Main.main() type ‘hook’ to centralize the entry into your run-time and no default way for UI and code to persist from scene to scene. This was the genesis of the Unity Manager of Managers (uMOM), pronounced as /you-mom/. You can read more at the uMOM Dev Diary and see the status of the project (it has some issues). Here is a short summary of the purpose and benefits;

The uMOM package allows developers to add one or many reusable, custom manager classes to the project. Each ‘start’ automatically, have a predictable life-cycle (reset, add, update, remove), optionally receive ‘update()’ calls, optionally run during edit mode, and optionally persist between scenes. Managers operate as singletons and can easily address each other to collaborate.

Types of uMOM Managers: Really anything is possible, but here is the short list of use cases I will address first. Use some of mine or none of mine — then create your own. Most of any existing manager class you have can easily be converted for compatibility here.

  • uEventManager -Streamline messaging between classes. Replace the need for Unity’s clunky ‘SendMessage’ and instead dispatch strongly typed objects. (The uEventManager will also be available separately).
  • Store references to audio clips (drag-n-drop) and control audio playback via C# from one place.
  • GUIManager — Layout UI which optionally persists between scenes. Centralize the controls to handle clicks, etc…
  • PoolManager — Optimize your run-time performance by persisting GameObject or prefab instances in RAM and displaying them as needed.
  • LevelManager — Queue up levels and perform transitions (e.g. fade-in-out) between them.
  • GameManager — While other managers are not project-specific, this one likely is. Here you manage the core game mechanics, how the user wins and loses, store the score, etc…
  • SaveManager: Takes care of saving and loading user preferences and achievements.
  • MenuManager: Controls all menus, managing their animations, their contents, and their behaviors. Perhaps it heavily uses the GUIManager for layout.
  • Much, much, more…

Diagram

Hierarchy

Type: Component-based w/ Manager

Note: The images and source code for this architecture are not yet available.

Pros:

  • Reuse code between projects. That is probably its greatest strength. Ultra-fast to set up with much out-of-the-box functionality. Nice GUI!
  • Have global access (also a con) to managers which are decoupled by discipline (GUIManager, LevelManager, AudioManager, etc…) each with a common interface and life-cycle.
  • Scalable to large teams such as 4–10 developers (but may require more planning upfront and dedicated team members creating the managers vs. those using the managers)

Cons:

  • The benefits of MVCS separation are not implicit ( but are possible ).
  • More scalable to complex games than 1,2,3 above, but far less than 6 below.
  • Still in alpha with bugs that prevent production readiness.

5. uMVCS

For non-game projects, such as data-driven applications, there is a clear favorite in architectures; the Model-View-Controller-Service (MVCS or MVC). For the uninitiated, it’s where you separate your code into 4 areas; the data, the user interface, the core functionality, and any calls to/from backend servers. It seems like OVERKILL at first, but once one is well-practiced he/she can drop in a template (e.g. Unity Package) and in 5 minutes be ready to rock.

The “uMVCS” is an ultra-light framework I created myself. It’s one of many, many setups for MVCS. I created recently, from scratch in just a few hours for ACADEMIC PURPOSES ONLY. It is not complete and scalable like other implementations, but if you have never touched MVCS before, it’s a great way to learn.

Type: MVCS

Read More : Unity Game Architectures — Part 1

Download Full Project: uMVCS (Github)

Pros:

  • Great for learning
  • Uses a custom event-dispatcher implementation of the observer pattern for decoupled communication from any scope to any scope.
  • Heavy use of Singletons (also a con) allows access to the ‘architecture’ from any coding scope.

Cons:

  • Purposefully incomplete, it exists just to help newbies learn about code separation with MVCS.
  • No command-pattern.
  • I created it in 90 minutes. Ha.

6. Strange IoC

Here we add to the organizational benefits of MVCS the ease-of-development feature called inversion of control (IoC). To learn more. Here is the official Strange diagram of the MVCS overview and the StrangeIoC website.

Diagram

Hierarchy

Type: MVCS w/ IoC

Pros:

  • Public, Community-driven, and well-documented. (e.g. You can hire/contract a new developer who arrives with this skill on day 1)
  • More decoupled, testable, & D.R.Y.
  • Scales up well for large teams, large projects

Cons:

  • Slower to setup (but faster to add last-minute changes)
  • The steeper learning curve, especially for junior developers
  • Demands discipline/know-how from your team to put logic in its proper place (but removes the ‘where should we put that code?’ decision process)

Sample Game

Downloads

Complete source code and examples are outdated and no longer available. Sorry!

More By Samuel Asher Rivello

Available For Unity Hire: Remote, Contract

20 years of game development experience. SamuelAsherRivello.com

Comments?

Let me know! Twitter.com/srivello

--

--

Samuel Asher Rivello

Game Developer & Instructor - Unity Certified. 20+ years of game dev XP. Available: Remote, Contract. http://www.SamuelAsherRivello.com