Monday, September 29, 2025

6 Design Patterns Every Unity Developer Needs to Know

There are many reasons why there are design patterns every Unity developer needs to know. To know, and to fully understand that is. If you are a beginning game developer, you’ve undoubtedly already applied some of these patterns in your own game design project without even knowing it. Which pattern is the best depends on the nature and the game design structure. I use a combination of design patterns in my project; predominantly the observer and the singleton pattern. Below, we're going over all those design patterns, along with their pros and cons. Find out what the most common game design patterns are in Unity 6, with examples, so you can easily copy and paste them in your own project!



Wednesday, September 24, 2025

11 Ways to Optimize Performance in Unity 6 You Probably Didn't Know

 

I know, one of the most challenging and important tasks as a game developer is to optimize performance in Unity 6. The problem is that it’s not always clear what causes the lag or stutter. Perhaps after some deep diving into the issue, you come to find out that a texture was of too high a resolution. Or that there were too many unnecessary vertices on a 3D model. Or maybe your scripts are not optimized.

Even if your game is running flawlessly on your machine when play testing, it may struggle on another for no apparent reason. Below, I’m going to mention some of the most common ways to optimize performance in your game development project in no particular order. Some are easy to implement, others may require a bit more research. Some may not even apply to your current game development project at all, but in any case go over it and make sure your game is as optimized as can be (you may need it for your next project!).



Tuesday, September 23, 2025

Top 10 Ways to Cache References in Unity 6 (and the Best Ones!), with Code Examples!

 

The beauty of the Unity Game Engine (and its downfall for some at the same time) is the amount of freedom it gives you when developing your game. There are multiple ways to structure something that result in the exact same outcome, but one approach is often better than another. Which one is best depends on your game design architecture, but overall it’s safe to say some methods are generally stronger regardless of your structure. Choosing the right way to cache references in Unity can greatly enhance the performance of your game.


Here are 10 ways you can cache references in Unity, along with their pros and cons, in no particular order:



Thursday, September 18, 2025

Munnica Proudly Presents: A guide to solo game development

Building a game from the ground up is no small feat. Before you even get into the nitty-gritty of finding assets and promoting your brand, there’s a long list of things you need to take care of to lay the foundation. Choosing the best engine, creating a GDD, and setting a realistic project timeline are all part of the solo game dev job description. Fortunately, this new guide can help you navigate the sometimes choppy (but rewarding) waters of going it alone in the game industry. 

Lessons Learned On The Solo Dev Journey

While you will find tips and tricks to bring your game to life, this book also shares common pitfalls to avoid based on firsthand experience. You’ll learn not just how to put yourself in a programmer’s shoes, but how to develop a mindset that maximizes your time and productivity. It also addresses how to find the best training resources and tech for your game design projects. 

What’s Inside This Guide

  • What to expect from game development and how to start your first game development project
  • How to manage your game development project and boost your productivity
  • Coding and math explained in game development, a guide to Object Oriented Programming (OOP)
  • How to adopt a programmer’s mindset
  • Which mistakes to avoid when developing your game
  • What to do when you're stuck in game development projects
  • How to write a GDD (Game Design Document)
  • How to choose the right game engine for your project (highlighting ALL reputable engines)
  • Where to find the right assets for your project
  • The benefits and setbacks of game development tutorials
  • Ways AI can help you design and/or develop your game
  • General tips any game developer should know
  • How to successfully promote yourself and your game
  • BONUS: resources to help you learn game development in Unity (free or paid)

Where To Find It

Get your copy of A guide to solo game development: Tips, tools, and techniques to make your first game today to delve into planning, organizing, and marketing your debut game. (Kindle or Paperback)


Tuesday, September 16, 2025

Decoupling Game Systems in Unity with an EventBus

 

One of the biggest problems I used to run into while developing my game in Unity were referencing scripts and objects. Unless it's just a small project that can be handled by a handful of scripts, if your game gets any larger you quickly realize this can become a big issue. Before you know it, you're dealing with a ton of spaghetti code referencing scripts all over the place. That's where game architecture comes into play.

As you continue your game development career, you'll notice that game architecture becomes more and more important. It's something you probably didn't give much thought to when you started out, but now it's super important to understand which game architecture path you want to implement in your game.

Does the UI panel need to know if your player takes damage? Or does your Audio Manager need to know if the state of your game changes? Already you can see there is some referencing involved.

Let me show you the "old way" I used to decouple scripts from one another, and the new way — a technique I'm using now to make it even more expandable.

The old way featured a static class that acted like a middleman between scripts that needed information from each other.

The script was simply called GameEvents.cs. and looked like this with an Audio event as an example:


using System;
using UnityEngine;
  
namespace Munnica.Events
{
    public static class GameEvents
    {
        /// 
        /// If audio needs to be played
        /// 
        public static Action<AudioClip> OnAudioPlay = delegate { };               
    }
}
  

Then in another script, let's say AudioManager.cs, you would then subscribe to, and unsubscribe from, this GameEvent:


namespace Munnica.Managers
{
    public class AudioManager : MonoBehaviour
    {
        private void OnEnable()
        {
            GameEvents.OnAudioPlay += PlayAudio;            
        }

        private void OnDisable()
        {
            GameEvents.OnAudioPlay -= PlayAudio;            
        }

        private void PlayAudio(AudioClip clip)
        {
            // Cached references from AudioManager would then be called
            // e.g. _audioSource.clip = clip; _audioSource.Play();
        }
    }
}
  

Audio, for example, would then be triggered from another script by means of GameEvents.OnAudioPlay, which in turn would play the passed through audioclip

The problem that I realized (after having about 20 GameEvents in the script), was that this technique wasn't very scalable. What if I also wanted to control the volume of the audio, or the pitch? GameEvents that took care of th UI were even worse! Images, text components etc, have a lot more possibilities. This would all have to be restructured and refactored if I wanted to add extra things.

The solution? An EventBus!!

A bus, not to be confused with the vehicle :P, in computing terms is a communication system that transfers data between components. Exactly what we need for our game development project that's in dire need of decoupling!

Understanding how the 'old-event' system works (as described above), is a huge plus since it behaves similarly - but not necessary to implement this new system in your own project.

Let’s walk through how you can set up your own EventBus system step by step.

The EventBus system looks like this:

Step 1: Create a static class EventBus


using System;
using System.Collections.Generic;

namespace Munnica.Events
{
    public static class EventBus
    {
        private static readonly Dictionary _eventTable = new();

        public static void Subscribe(Action callback)
        {
            if (_eventTable.TryGetValue(typeof(T), out var existingDelegate))
            {
                _eventTable[typeof(T)] = (Action)existingDelegate + callback;
            }
            else
            {
                _eventTable[typeof(T)] = callback;
            }
        }

        public static void Unsubscribe(Action callback)
        {
            if (_eventTable.TryGetValue(typeof(T), out var existingDelegate))
            {
                _eventTable[typeof(T)] = (Action)existingDelegate - callback;
            }
        }

        public static void Publish(T eventData)
        {
            if (_eventTable.TryGetValue(typeof(T), out var del))
            {
                ((Action)del)?.Invoke(eventData);
            }
        }

        public static void DebugSubscribers()
        {
            foreach (var kvp in _eventTable)
            {
                var type = kvp.Key;
                var del = kvp.Value;

                UnityEngine.Debug.Log($"Event Type: {type.Name}");

                if (del != null)
                {
                    foreach (var d in del.GetInvocationList())
                    {
                        UnityEngine.Debug.Log($"  -> {d.Method.Name} from {d.Target}");
                    }
                }
            }
        }


    }


}

  

As you can see, there are a few additions compared to the previous GameEvent system.

The static 'Subscribe' method is similar to the += subscribe in GameEvents. This time with the addition that we're now using Generics to implement the TYPE we're going to communicate with. The subscription is then stored in an event table (dictionary). In the same class, we're also implementing 'Unsubscribe', this ensures that we can easily unsubscribe from the EventBus in the method OnDisable in any script!

Step 2: (this is where the magic is going to happen!) Create structs: special data containers tailored to your project.

In my game development project, I use all kinds of structs for EventBus, the following example is how I play audio by means of a struct:


using UnityEngine;


namespace Munnica.Events
{
    public struct PlaySoundEvent
    {
        public AudioClip Clip;
        public Vector3 Position;
        public float Volume;
        public int Channel;
        public bool Stop;


        public PlaySoundEvent(AudioClip clip, Vector3 position, int channel = 1, float volume = 1f, bool stop = false)
        {
            Clip = clip;
            Position = position;
            Channel = channel;
            Volume = volume;
            Stop = stop;

        }
    }
}


  

As you can see, it's totally customizable and expandable now! This struct 'PlaySoundEvent' has a constructor that assigns the parameters that need to be implemented! I can now not only decide which Audioclip to play, also I can assign the position, the channel it needs to play through (I have 3 different AudioSources), the volume level and if the audio needs to stop at any given moment. Let's say later on I want to also include the pitch level, or something else, it can be easily added on without breaking any code!

Now, how do we call this Event? Remember in our static class EventBus we wrote the Publish method? Exactly, that's what we're going to use to 'invoke' this event!

Step 3: Publish the event!

From any script, we can invoke this event by:


EventBus.Publish(new PlaySoundEvent(_scannerLoadingSFX, Vector3.zero, 2, 1f));
  

By means of customized structs, perfectly tailored to any small- midsized project, we've now completely decoupled our game system! AudioManager, for example, doesn't need to know which script is playing an audioclip, it just knows it needs to play the clip that's coming in. The same goes for the script pushing the audioclip, it doesn't need to know which script is responsible for playing the clip. It just needs to 'submit' the clip to a subscriber. I recently completely overhauled my project to implement the EventBus system. I've been working with this new system for quite some time now, and I can't go back anymore!

Final note about subscribers:

One last note, and that's about the EventBus subscribers. At some point, your going to have more than one event. In fact, it's likely you'll be ending up with lots of custom structs that all do something in your project. With the 'old-game event system', you could just look at the list GameEvents and see how many events there were in your game (although you still weren't able to see which scripts were assigned to that event unless you did a work around). Now, with EventBus, there is a special included method 'DebugSubscribers' that will allow you to see which game objects (scripts) are subscribed to which event!

In my GameManager class (which is a persistent singleton), I just have a simple boolean _showEventSubscribers, that (when ticked) prints out all the actives subscribers to the console in Unity by means of this code:


	if (_showEventBusSubscribers) { EventBus.DebugSubscribers(); }
  

I hope that you can apply this technique in your own project. I found it the best way to decouple scripts in Unity game development! If you have any questions, (or perhaps know even a better way!) do not hesitate to reach out.

This article may contain typos or grammarly incorrect sentence structures, I'm a gamedeveloper, not an editor or proofreader :P

Happy coding!