As your project develops, most likely your number of classes will grow as well. In order to keep our code flexible, we can use a software pattern called a Mediator. So what is a Mediator exactly? When should you use a Mediator and how can we improve our code in Unity using Mediators?

In This Article

What is a Mediator
In simple words, a mediator is a technique that developers can use to simplify the code. Every time two classes work together, they form a dependency on each other. Once a dependency is formed, these classes know about each other’s existence and become tightly coupled.
However, we want code to be as abstract as possible. That means classes should not be tightly coupled and only know about as few classes as possible. Mediators act as a go-between and reduce the amount of dependencies between classes. In turn, this simplifies our code and leads to abstraction.
When To Use a Mediator in Unity
To effectively use a Mediator in Unity, you first need to identify where there is a need for it. Usually, the best place to start using mediators in Unity is where a class relies on other classes. This could be a MonoBehaviour that uses a lot of Components or any type of C# class Next, you need to ask the question whether the class should have all the responsibilities it has. If you find that a class has too much responsibilities you could consider implementing a Mediator.
Common Areas To Use a Mediator Pattern In Unity
Usually, the common areas to use a mediator pattern in Unity are sections of the code that are central to the game. This is because in these areas, many different classes interact from which game features emerge. Examples of common areas include:
- Players
- Enemies
- Player or Enemy Abilities
- UI Systems
- Scoring Systems
- Quest or Mission Systems
- Achievement Systems
- AI Planners
- Cinematics or Cutscenes
- Tutorials

How To Use a Mediator in Unity
In order to show you how you can use a Mediator pattern in Unity, we will share an example. Imagine a scenario where you are building a game in which the player can cast.an explosive spell at a particular location. When this happens, the area surrounding the spell will be scorched, trees will catch fire and pushed aside. On impact, enemies will receive damage and pushed back. In the code below, we have implemented a naive way to this exact spell:
Player.cs
public class Player : MonoBehaviour { [SerializeField] private GameObject m_SpellEffectPrefab; [SerializeField] private AudioSource m_ExplosiveSpellSound; public void CastExplosiveSpell(Vector3 position float damage) { // Get all enemies and trees Enemy[] enemies = FindObjectsOfType<Enemy>(); Tree[] trees = FindObjectsOfType<Tree>(); // Damage and enemy and push it back foreach(Enemy enemy in enemies) { enemy.Damage(damage); Vector3 direction = (position - enemy.transform.position).normalized; enemy.PushBack(direction); } // Push back the tree and set them on fire foreach(Tree tree in trees) { Vector3 direction = (position - enemy.transform.position).normalized; tree.PushBack(direction); tree.SetFireState(true); } // Show spell effect and play its sound Instantiate(m_SpellEffectPrefab); m_ExplosiveSpellSound.Play(); } }
How To Determine if a Class Needs a Mediator
Now, to determine if our class needs a Mediator, we check to see what responsibilities it currently has. Then, we need to check if we can group these responsibilities in a common Mediator class. As you can see above, our Player class has an awful amount of responsibilities, clearly something has to be done.
- Retrieving Enemies
- Retrieving Trees
- Damaging Enemies
- Pushing Back Enemies
- Pushing Back Trees
- Set Trees Ablaze
- Spawn Spell Effect
- Play Spell Sound

Next, we need to determine if we can group all of the responsibilities in a common Mediator class. Since the explosive spell is some sort of a skill, we can create an ExplosiveSpellSkill mediator.
Implementing a Mediator in Unity
To implement a mediator, you often need to delegate functionality from the original class to the mediator. In our case, we will create a new class and call it ExplosiveSpellSkill. In this class, we put every related to casting the spell that was originally in the Player. After our refactoring efforts, we end up with the following result:
Player.csExplosiveSpellSkill.cs
public class Player : MonoBehaviour { [SerializeField] private GameObject m_SpellEffectPrefab; [SerializeField] private AudioSource m_ExplosiveSpellSound; public void CastExplosiveSpell(Vector3 position float damage) { ExplosiveSpellSkill spell = new ExplosiveSpellSkill(); spell.Cast(position, damage); spell.PerformFeedback(m_SpellEffectPrefab, m_ExplosiveSpellSound); } }
public class ExplosiveSpellSkill { public void Cast(Vector3 position, float damage) { Enemy[] enemies = FindObjectsOfType<Enemy>(); Tree[] trees = FindObjectsOfType<Tree>(); foreach(Enemy enemy in enemies) { enemy.Damange(damage); Vector3 direction = (position - enemy.transform.position).normalized; enemy.PushBack(direction); } foreach(Tree tree in trees) { Vector3 direction = (position - enemy.transform.position).normalized; tree.PushBack(direction); tree.SetFireState(true); } } public void PerformFeedback(GameObject spellEffect, AudioSource sound) { Instantiate(spellEffect); sound.Play(); } }
After refactoring, our ExplosiveSpellSkill Mediator class acts as an go-between for the Player, Enemy and Tree classes. As a result, our Player class has lost its dependencies for the Enemy and Tree classes.
Best Practices On Using Mediators in Unity
To improve our code in Unity using Mediators, we recommend to use the following guidelines:
- When creating a mediator class, give it a name that makes sense.
- Consider using a Mediator when a class has more than 5 dependencies.
- Be mindful of the lifetime of MonoBehaviours or Components encapsulated by the Mediator. They may need to updated over time.

Summary
What you learned in this article:
- Every time two classes work together, they form a dependency on each other.
- Mediators act as a go-between and reduce the amount of dependencies between classes
- The best place to start using mediators in Unity is where a class relies a lot on other classes
- If you find that a class has too much responsibilities you could consider implementing a Mediator.
- Always check if we can group responsibilities in a common Mediator class.
- To implement a mediator, you often need to delegate functionality from the original class to the mediator

Conclusion
In the end, we hope you now have a better understanding of how you can improve your code in Unity using Mediators. While it might be difficult to use them at first, they will start to make sense in no time. Next, we have shared an example of how to implement a Mediator in Unity and listed several best practices.
Further Reading
Other articles you may find interesting:
