Facade
What is it?
Facade is a structural design pattern that puts a simple access point in front of a complex subsystem. Instead of making the rest of the code deal with many different classes one by one, it provides a cleaner and more controlled interface.
For example, in Unity, think of an audio system with classes like MusicPlayer, SfxPlayer, and AudioFader. With a Facade, the game only talks to something like AudioFacade, using simple methods such as PlayMusic(), PlaySfx(), or SetMasterVolume().
Facade does not remove the subsystem. It only hides its complexity from the outside. This keeps the code easier to read, easier to maintain, and safer to change later.
When is it used?
Facade is useful when several classes need to work together to complete one larger task. Audio systems, UI systems, save/load systems, networking, achievements, and third-party SDK integrations are common examples.
It is especially helpful when the same group of operations is repeated in different parts of the project. For example, a single ChangeMusic() method can handle lowering the current track, starting a new track, and fading the volume back in.
It is also useful in larger projects where you want to reduce dependencies. Other systems do not need to know how the subsystem works internally. They only depend on the Facade.
Animation
Code
using System.Collections;
using UnityEngine;
namespace Patterns.Structural.Facade
{
public class AudioFacade : MonoBehaviour
{
public static AudioFacade Instance { get; private set; }
[SerializeField] private AudioSource _musicSource;
[SerializeField] private AudioSource _sfxSource;
private MusicPlayer _music;
private SfxPlayer _sfx;
private AudioFader _fader;
private void Awake()
{
if (Instance != null)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
_music = new MusicPlayer(_musicSource);
_sfx = new SfxPlayer(_sfxSource);
_fader = new AudioFader();
}
public void PlayMusic(AudioClip clip) => _music.Play(clip);
public void PlaySfx(AudioClip clip) => _sfx.PlayOneShot(clip);
public void ChangeMusic(AudioClip newClip, float fadeDuration = 1f)
{
StartCoroutine(ChangeMusicRoutine(newClip, fadeDuration));
}
private IEnumerator ChangeMusicRoutine(AudioClip newClip, float duration)
{
yield return _fader.FadeOut(_musicSource, duration);
_music.Play(newClip);
_musicSource.volume = 1f;
}
public void SetMasterVolume(float v)
{
_music.SetVolume(v);
_sfx.SetVolume(v);
}
}
}Advantages and Disadvantages
• Advantages:
- Simplifies complex subsystems.
- Reduces dependencies on internal classes.
• Disadvantages:
- It can grow into a God Object.
- It can hide too much or add an unnecessary extra layer.
Tips
In Unity, try to keep each Facade focused on one responsibility. Instead of creating one large GameFacade for everything, split it into smaller facades such as AudioFacade, UIFacade, or SaveFacade.
When possible, write the Facade as a plain C# class instead of making it directly dependent on MonoBehaviour. If it needs scene-based objects, pass them from the outside through a constructor or an Initialize() method.
Only expose the methods that the rest of the project actually needs. Keeping the public API small prevents unnecessary dependencies.
Facade is especially useful for third-party SDKs in Unity. Ads, analytics, cloud saves, and in-app purchases become much easier to replace later when they sit behind a facade.