2025. 3. 29. 10:23ㆍ유니티 unity/디자인패턴
게임을 개발하다 보면 시스템 간의 연결 고리가 점점 많아지고 복잡해지게 됩니다. 처음에는 하나의 기능을 위해 두세 개의 매니저만 호출하면 되었지만, 프로젝트가 점점 커질수록 관련된 시스템이 늘어나고 호출 순서와 흐름까지 신경 써야 하다 보니, 결국 코드는 난잡해지고 유지보수가 어려워집니다.
예를 들어 게임 오버 상황을 생각해봅시다. 플레이어가 사망했을 때 다음과 같은 일들이 동시에 일어나야 할 수 있습니다:
- 플레이어 컨트롤 비활성화
- 사망 애니메이션 재생
- 사망 사운드 출력
- 게임 오버 UI 표시
- 현재 게임 상태 저장
- 스코어 정리 및 전송
- 씬 전환 준비
이걸 모두 플레이어 스크립트 안에서 처리한다면? 모든 매니저에 직접 접근해야 하고, 순서도 챙겨야 하고, 테스트나 리팩토링도 매우 어려워집니다.
이럴 때 유용한 설계 패턴이 바로 퍼사드(Facade) 패턴입니다.
퍼사드 패턴이란?
퍼사드 패턴은 복잡한 서브 시스템들을 단순한 인터페이스로 감싸서 외부에서 쉽게 사용할 수 있도록 만드는 디자인 패턴입니다.
쉽게 말하면, 여러 시스템을 하나로 묶은 ‘대표 창구’를 만드는 거예요. 외부에서는 이 창구만 이용하면 내부적으로 어떤 일이 일어나는지 몰라도 됩니다.
복잡한 내부 로직은 감추고, 필요한 동작만 깔끔하게 꺼내 쓰는 구조입니다.
퍼사드 패턴이 유니티에서 유용한 이유
유니티는 씬 단위, 오브젝트 단위로 스크립트가 나뉘어 동작하고, 다양한 매니저 클래스(UI, 사운드, 게임, 저장 등)들이 함께 움직입니다. 이 구조 안에서 하나의 이벤트를 처리하려고 하면 정말 많은 시스템과 연결하게 되죠.
이때 퍼사드 패턴을 활용하면 다음과 같은 이점을 얻을 수 있습니다:
- 호출 순서와 흐름을 한 곳에서 관리할 수 있음
- 외부에서는 한 줄로 복잡한 처리를 요청할 수 있음
- 내부 구현이 바뀌어도 외부 코드는 그대로 유지 가능
- 유지보수, 테스트, 디버깅이 쉬워짐
실제 예제: GameOver 처리 퍼사드 만들기
관련된 매니저들:
public class UIManager {
public void ShowGameOverUI() => Debug.Log("게임 오버 UI 출력");
}
public class SoundManager {
public void PlayDeathSound() => Debug.Log("사망 사운드 재생");
}
public class SaveManager {
public void SaveGame() => Debug.Log("게임 저장 완료");
}
public class PlayerController {
public void DisableControl() => Debug.Log("플레이어 조작 중지");
}
퍼사드 클래스 작성:
public class GameOverFacade
{
private UIManager uiManager;
private SoundManager soundManager;
private SaveManager saveManager;
private PlayerController player;
public GameOverFacade(UIManager ui, SoundManager sound, SaveManager save, PlayerController player)
{
uiManager = ui;
soundManager = sound;
saveManager = save;
this.player = player;
}
public void HandleGameOver()
{
player.DisableControl();
soundManager.PlayDeathSound();
saveManager.SaveGame();
uiManager.ShowGameOverUI();
Debug.Log("게임 오버 처리 완료!");
}
}
사용 예시:
public class GameManager : MonoBehaviour
{
private GameOverFacade gameOverFacade;
private void Start()
{
var ui = new UIManager();
var sound = new SoundManager();
var save = new SaveManager();
var player = FindObjectOfType<PlayerController>();
gameOverFacade = new GameOverFacade(ui, sound, save, player);
}
public void OnPlayerDied()
{
gameOverFacade.HandleGameOver();
}
}
이제 플레이어가 사망했을 때는 HandleGameOver() 한 줄로 모든 처리가 끝납니다. 내부가 아무리 복잡해져도 외부에서는 몰라도 됩니다.
다양한 퍼사드 패턴 예시
1. 씬 전환 퍼사드
public class SceneTransitionFacade
{
private FadeUI fadeUI;
private SoundManager soundManager;
private SceneLoader sceneLoader;
public SceneTransitionFacade(FadeUI fade, SoundManager sound, SceneLoader loader)
{
fadeUI = fade;
soundManager = sound;
sceneLoader = loader;
}
public void TransitionToScene(string sceneName)
{
fadeUI.FadeOut(() => {
soundManager.StopAllSounds();
sceneLoader.LoadScene(sceneName);
});
}
}
2. 게임 시작 퍼사드
public class GameStartFacade
{
private UIManager ui;
private SoundManager sound;
private PlayerSpawner spawner;
public GameStartFacade(UIManager ui, SoundManager sound, PlayerSpawner spawner)
{
this.ui = ui;
this.sound = sound;
this.spawner = spawner;
}
public void StartGame()
{
ui.HideTitleUI();
sound.PlayBGM("Game");
spawner.SpawnPlayer();
}
}
퍼사드 패턴 + 싱글톤 패턴
퍼사드는 전역 접근이 필요할 때 싱글톤과 함께 자주 사용됩니다:
public class GameFacade : MonoBehaviour
{
public static GameFacade Instance { get; private set; }
public UIManager UI { get; private set; }
public SoundManager Sound { get; private set; }
public SaveManager Save { get; private set; }
private void Awake()
{
Instance = this;
UI = new UIManager();
Sound = new SoundManager();
Save = new SaveManager();
}
}
이렇게 하면 어디서든 GameFacade.Instance.Sound.PlayBGM("Main") 같은 방식으로 접근할 수 있어 편리합니다. 다만 남용하지 않도록 조심해야 합니다.
퍼사드를 도입할 때 좋은 타이밍
- 여러 시스템을 동시에 실행해야 할 때
- 메서드 호출 순서를 확실하게 보장해야 할 때
- 외부에서 내부 구현을 몰라도 되도록 만들고 싶을 때
- 테스트 코드를 작성할 때 (퍼사드 하나만 테스트하면 됨)
퍼사드 패턴은 “시스템이 복잡해졌을 때, 정리된 인터페이스를 외부에 제공하자”는 아주 실용적인 철학에서 출발합니다. 유니티처럼 시스템이 나뉘어 있고, 매니저가 많은 구조에서는 퍼사드의 효과가 더욱 두드러집니다.
작게는 UI 묶음 하나, 크게는 게임 전체 흐름까지 퍼사드로 감싸면, 코드가 훨씬 읽기 쉬워지고, 유지보수도 편해지고, 협업 시 충돌도 줄어듭니다.
프로젝트가 조금 복잡해지기 시작했다면, 지금이 바로 퍼사드 패턴을 도입해볼 타이밍입니다!
'유니티 unity > 디자인패턴' 카테고리의 다른 글
유니티에서 템플릿 메서드(Template Method) 패턴 활용하기 (0) | 2025.03.29 |
---|---|
유니티에서 싱글톤(Singleton) 패턴을 활용하기 (0) | 2025.03.29 |
유니티에서 이벤트 버스(Event Bus) 패턴을 활용한 유연한 시스템 만들기 (0) | 2025.03.29 |
유니티에서 옵저버 패턴(Observer Pattern)을 제대로 활용해보세요 (0) | 2025.03.29 |
유니티에서 상태(State) 패턴을 제대로 활용해보기 (0) | 2025.03.29 |