Featured Articles:

Showing posts with label unity learn. Show all posts
Showing posts with label unity learn. Show all posts

Monday, August 31, 2026

Interfaces vs Abstract Classes in Unity: Which One Is Better?

Here we go again, yet another blog post about a debate that's been quietly ruining developer's sleep since the dawn of object-oriented programming. Sit back and relax, because we're finally settling the "interface or abstract class" argument. 

Why This Comparison Even Matters

As a solo game developer like myself, you don't have a senior architect looking over your shoulder telling you your class hierarchy is a big mess. When it comes to interfaces vs abstract classes in Unity, the choice you make on day one tends to snowball... and it'll either be a clean, swappable system, or turn into a tangled inheritance chain you'll be untangling weeks from now. Fully understanding both of them is important, especially at the beginners stage, since this is not even an intermediate topic.

Both let you enforce structure across your scripts. Neither is "wrong." But picking the wrong one for the wrong job is how you end up with an Enemy abstract class that fifteen unrelated objects are awkwardly pretending to inherit from just to get one shared method.

Friday, August 28, 2026

Task vs UniTask vs Awaitable: Performance and API Comparison for Unity Devs

Welcome to another blog post about async programming in Unity, which async should you use? Let's elaborate. If you've ever Googled this while your coroutine spaghetti stared back at you accusingly, you're in the right place. Let's get you something to ponder on over the weekend!

The thing is, Async/await in Unity used to mean one thing: System.Threading.Tasks.Task. Then UniTask showed up and made everyone's coroutines look ancient. Unity's shipped its own native Awaitable type, and suddenly you've got three ways to do the same thing, each with its own opinions about your garbage collector.

So which one should you actually reach for? Let's break down the Task vs UniTask vs Awaitable performance story, the API differences, and where each one earns its spot in a solo game developers toolkit.

 

Monday, August 24, 2026

UnityAction vs UnityEvent: The Real Difference (And When to Use Each)

Back in the day when I first started programming in Unity (during COVID) this was probably one those hard concepts to wrap my head around. I kept mixing them up, and didn't know which one to use when. When I did a google search I was left even more confused! I thought, hey, now that I actually understand the whole thing; why not write an article about it because it's actually really simple.

So, do you use a UnityAction, or do you opt for a UnityEvent? They sound kind of the same. They show up in similar places, and yet mixing them up in the wrong context can leave you debugging phantom null references for a loooooong time, wondering why your inventory system just... stopped listening.

So, let me try to explain it in my own words and hopefully I can make some sense of it all, including exactly when to use UnityEvent in Unity, and when it's just adding overhead for no reason.



Friday, August 21, 2026

Inheritance vs Composition in Unity: Which One Should You Use?

How many time have you argued with yourself: should this Enemy class inherit from a base Character class, or should it just be a GameObject wearing a trench coat made of components? Welcome to the inheritance vs composition in Unity debate, a fight that predates Unity by decades, but hits differently when you're the only person who has to live with the consequences of your own architecture.

This isn't an academic computer science debate for you. You're a solo dev. There's no team lead to quietly blame when your class hierarchy buckles under its own weight six months from now. So let's skip the theory-heavy stuff and talk about what actually matters when you're picking a side (or perhaps, you choose a combination of both in your project).

Let do it!

Wednesday, August 19, 2026

5 More Unity Coding Techniques Beginner Developers Probably Don't Know (Part 2)

Back for round two? Good. I hope you've read the previous article. 

If Part 1 covered TryGetComponent & friends, this batch is about the stuff that happens around your components like tags, cameras, and the Inspector itself quietly judging your field values.

Same thing as before: five more practical Unity coding techniques for beginners, real code and no fillers.

 Let's begin!

 

 

Monday, August 17, 2026

5 Coding Techniques Beginner Unity Developers Probably Don't Know

So you've got Start() and Update() down cold. You can drag a reference into the Inspector in your sleep. But somewhere between "my game runs" and "my game runs well," there's a pile of small C# tricks that never quite make it into the beginner tutorials because, let's be honest, most tutorials are just trying to get a cube to move.

This is the good stuff you'll eventually come across, just like I did. Five underrated Unity coding techniques for beginners, with real code, zero fluff!

 

Why These Unity Coding Techniques for Beginners Actually Matter

If you're a solo dev, you're the programmer, designer, and marketing team all at once. That means every shortcut that saves you five minutes today saves you an hour six months from now when you've forgotten why you wrote something the way you did.

These are NOT advanced architecture patterns. You won't need a computer science degree or a whiteboard full of arrows. They're small, practical Unity coding techniques for beginners that quietly make your code safer, faster to write, and less likely to break the moment you rename something.

Let's dive in!

Wednesday, August 12, 2026

Manager Classes in Unity: When They're Genius and When They're a Bad Idea

A manager class is likely one of the first things you have written in Unity. GameManager, AudioManager, UIManager, SaveManager, they show up in every tutorial, every asset store project, every "clean architecture" YouTube video with a thumbnail of a guy with a weird looking beard pointing confused at a whiteboard.

And look, managers work, and that's exactly the annoying part to explain - but I'm going to try anyway. Managers work well enough, for long enough, and then you don't even notice the problem until your GameManager is 2,400 lines long and touches literally everything in your project. At that point it's not a manager anymore. It's a god object wearing a manager costume.

Let's talk about when managers are genuinely good architecture, when they quietly rot, and how to tell the difference before your Inspector starts looking like a control room of a spaceship.

Monday, August 10, 2026

SOLID Principles In Unity Explained Without Needing A Computer Science Degree

FIVE letters, TEN intimidating words, and a bunch of academic jargon that make your eyes glaze over before you even get to the point. Somewhere along the way, "SOLID principles" got a reputation for being something only enterprise developers care about in between coffee breaks and standup meetings.

Here's the thing though: you've probably already broken (or followed) most of these principles in your Unity projects without knowing they had names. SOLID isn't some separate discipline you need to learn, it's just a handful of common-sense guidelines for not making your future self miserable.

 

Let's go through all five, Unity-style!

 

Friday, August 7, 2026

Unity Events vs UnityEvent vs C# Events: Which One Should You Actually Use?

If you've ever Googled "how do I make a button call a function in Unity" and ended up more confused than when you started (which happens a lot in my case - yes I'm looking at you CodeMonkey!), you're not the only one.

"Unity Events," "C# events," and "UnityEvent" all sound like the same thing said three different ways. 

Well, they're not. Surprise! 

 

They're three genuinely different tools, each with their own tradeoffs, and picking the wrong one for the job is how you end up with either a spaghetti mess of references or a UnityEvent doing something a plain C# delegate would've handled in one line.

Let's sort out what's actually what.

 

First, Let's Kill the Naming Confusion

Here's the actual breakdown:

C# events        → the native "event" keyword, built into the language
C# delegates     → Action, Func, and custom delegate types
UnityEvent        → UnityEngine.Events.UnityEvent, the Inspector-serializable one
"Unity Events"    → the loose, informal term people use for any of the above

That last one is the troublemaker! When someone says "just use a Unity Event," they might mean the actual UnityEvent class, or they might just mean "wire up an event, using the inspector." 

Context matters people! 

For the rest of this article, I'll be specific and call out which one I mean, so you don't end up in the same boat. Let's just make it clear, once and for all!!

Wednesday, August 5, 2026

10 ScriptableObject Patterns Every Unity Developer Should Know (Part 3) Factory Pattern, AI Behaviors & Global Configuration

Over the last two articles, we've explored seven practical ways to use ScriptableObjects beyond simple data storage.

We've covered everything from Data Assets and Runtime Sets to Item Databases and Spawn Tables. Hopefully by now it's becoming clear that ScriptableObjects aren't just a convenient place to store numbers, colors or sprites, they're powerful architectural tools that can help keep your project organized as it grows.

In this final part, we'll look at three more advanced patterns that are particularly useful in larger projects.

Don't worry if some of these seem a little intimidating at first, you probably won't need all of them on your next game. In fact, you may never need them at all, but knowing about it is a great addition to your programmer's toolbox.

Remember, good architecture isn't about using every design pattern you know. It's about choosing the simplest solution that solves the problem in front of you.

Let's jump in.

 

Tuesday, August 4, 2026

10 ScriptableObject Patterns Every Unity Developer Should Know (Part 2) Variable Assets, Ability Definitions, Item Databases

In the previous article, we explored three of my favorite ScriptableObject patterns:

            • Data Assets

            • Runtime Sets

            • Event Channels

If those patterns help organize your project, the next four we're covering today help organize your gameplay. They're all about making your game easier to balance, extend, and maintain without constantly diving into your code.

As with every design pattern, these aren't solutions looking for problems. They're practical techniques that shine in the right situations, and as always, can become overkill if used everywhere.

Let's jump in!

Monday, August 3, 2026

10 ScriptableObject Patterns Every Unity Developer Should Know (Part 1) Data Assets, Runtime Sets, Event Channels

If you've read my previous article on ScriptableObjects, you'll know they're far more than glorified data containers. Of course they're fantastic for storing weapon stats, enemy configurations, and game settings, but that's only the beginning.

One of the biggest "wait a minute sister" moments in my personal Unity journey was realizing that ScriptableObjects can also help shape the architecture of an entire project. They aren't just assets sitting quietly in your Project window; they can become communication hubs, registries, and reusable building blocks that make your code cleaner and easier to maintain.

In this mini-series, we're going to explore ten practical ScriptableObject patterns that I sometimes use in my own Unity projects. These aren't theoretical examples you'll only find in programming textbooks. They're patterns that solve real-world problems you'll encounter as your projects grows.

Learning all these patterns is important in my opinion. Even if you don't plan to use them now, you at least know which options are available - and perhaps you may find one useful in the future. All extra useful knowledge you can add to your programmer's toolbox.

In this first part, I'll cover:

  • Data Assets

  • Runtime Sets

  • Event Channels

     

Let's dive in.

 

Friday, July 31, 2026

ScriptableObjects In Unity And The Hidden Superpowers Most Overlook


When you first encounter ScriptableObjects, it's usually introduced as a way to store data outside of a scene. You create an asset, fill in some values in the Inspector, and suddenly you've got a cleaner alternative to hardcoded variables.

But that's only scratching the surface. It can do more than just hold data!

ScriptableObjects is one of Unity's most powerful and often misunderstood feature. If used correctly, it can simplify your architecture, reduce dependencies, improve reusability, and make your project significantly easier to maintain as it grows.

Unfortunately, it also has a reputation for being overengineered. Spend enough time on Unity forums, and you'll eventually find someone suggesting ScriptableObjects as the solution to virtually every problem. Need an inventory? ScriptableObjects. Dialogue? ScriptableObjects. AI? ScriptableObjects. Coffee machine broken? ...okay, perhaps not that one.

Like any tool, it's at its best when solving the right problem.

Let's deep-dive into what ScriptableObjects really are, when/how/why you should use them, and when it's definitely not the answer.

Thursday, July 30, 2026

Don't Ditch Coroutines for Async/Await in Unity Until You Read This

If you've only ever worked with coroutines, switching to async/await can feel almost magical. The code is cleaner, easier to read, and behaves much like synchronous code.

However, there's an important difference: Tasks are a .NET feature. Coroutines are a Unity feature.

That distinction affects how they interact with Unity's object lifecycle, scene management, and exception handling.

These differences are responsible for many of the mysterious NullReferenceExceptions and "WTF it worked yesterday!!" bugs that developers encounter when first adopting async.


Tasks don't adhere to Unity object lifetimes

This is arguably the biggest gotcha.

Imagine you write a simple async method to open a door:


public async Task OpenDoor()
{
    await Task.Delay(3000);

    animator.SetTrigger("Open");
}
  

Everything works perfectly until the player changes scenes, or destroys the object...or exits play mode. Three seconds later, the task resumes anyway. Now animator no longer exists.

NullReferenceException

You may wonder:

"The GameObject was destroyed. Why is this code still running?"

Because Tasks have no clue what a GameObject is. They're managed entirely by the .NET runtime.


Wednesday, July 29, 2026

Coroutines vs Async/Await vs Awaitable in Unity: Making Sense To Modern Asynchronous Programming

Coroutines have been pretty much the backbone of asynchronous programming in Unity for a long time. When you need to spawn enemies, fade a UI, load a level, or create cinematic sequences, chances are you wrote countless methods returning IEnumerator.

However, Unity has other options regarding this that may be better for your project.

Modern versions of Unity embrace C#'s async/await programming model and, more recently, introduced Awaitable, a Unity-specific asynchronous API that integrates directly with the engine. These additions don't replace coroutines outright but they complement them and, in many situations, offer cleaner, safer, and more powerful alternative.

Perhaps the challenge for many Unity game developers isn't learning the syntax, it's knowing which tool is better for the task at hand.

Let's take a deep-dive into Coroutines, async/await, and Awaitable, including threading, Task.Run(), CancellationToken, AwaitableCompletionSource, performance considerations, and strategies for migrating existing coroutine-based projects.

Friday, December 19, 2025

Overengineering Code in Unity: When Good Game Architecture Can Become a Problem

Back in September of this year, I wrote an article about decoupling game systems in Unity with an EventBus. This is a crucial part of  game architectural design, and should be implemented in those areas of your project that make sense. Once you understand it, you're probably eager to implement it everywhere! But be aware that this can also lead to some unwanted results in your project.

Thursday, October 9, 2025

Greatly Increase Performance For Free With An Update Publisher In Unity!

Does your game or application in Unity use a lot of update loops that slow down performance? No need to install plug-ins or special packages, greatly increase performance for free with an update publisher in Unity. It makes you wonder why this isn’t a standard feature anyway (but that goes for a lot of things in Unity).

We’re basically going to make a SINGLE type of update loop for your entire project! As you can imagine, this will lead to a massive performance boost for your game, especially if you use a lot of scripts that implement any kind of update loop.

Understanding the issue: 

What's the problem? Let’s address the issue of update loops in the first place (like Update, FixedUpdate, or LateUpdate) in Unity, because it's more complex than you may think. 

When you put code in an update loop to move a game object, like transform.position += new Vector3(0, 0, 1) * Time.deltaTime;, under the hood a lot of different checks are being performed before the update loop is even validated and started. First, Unity checks if the object hasn’t been destroyed yet, then there's checks if the requirements have been met to be active at all. Even when it passes all these checks, Unity still needs to confirm that its own update method is functioning properly. 

So basically, even BEFORE Unity runs the actual update loop, it’s doing all these involved computations, behavior iterations, call validations, preparing to invoke the method, verifying all the arguments and then finally running the little piece of code you wrote (which hardly is a performance issue compared to the aforementioned. Yes, this even happens with empty update methods accidentally left behind in scripts!

This slows down your project tremendously, and gets worse the more update loops you have!  

When you have lots of objects that implement any update loop in Unity, you can see the problem if it needs to perform these under the hood checks constantly.

Come on!

But what can we do about it? This is yet another case where the Observer Design Pattern comes in!

 

The Solution: 

First, we’re going to make an UpdatePublisher that lives in the scene on its own GameObject. It holds the ONLY Update method in the game, and it’ll notify all the other listeners when it’s called.

The observer itself is an interface, we’ll call it IUpdateObserver:


public interface IUpdateObserver
{
    void ObservedUpdate();
}

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!



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:



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!