Unity로 게임을 개발하다 보면 코드가 점점 복잡해집니다.
이럴 때 디자인 패턴을 활용하면 코드 구조를 훨씬 깔끔하게 유지할 수 있습니다.
이번 글에서는 Unity에서 자주 사용하는 4가지 패턴을 정리해보았습니다.
"이 씬에서 대장은 나 하나뿐이야!"
특정 클래스의 인스턴스가 하나만 존재하도록 보장하고
어디서든 접근할 수 있도록 하는 패턴입니다.
게임 전체에서 하나만 존재해야 하는 시스템에 사용합니다.
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
void Awake()
{
if (Instance == null)
Instance = this;
else
Destroy(gameObject);
}
}
어디서든 다음과 같이 접근할 수 있습니다.
GameManager.Instance.StartGame();
싱글톤을 너무 많이 사용하면
"나 상태 변했어! 관심 있는 애들은 알아서 반응해!"
어떤 객체의 상태가 변하면
그 객체를 구독하고 있는 다른 객체들에게 자동으로 알림을 보내는 패턴입니다.
예를 들어 플레이어가 데미지를 입었을 때
같은 이벤트가 동시에 발생해야 할 때 사용합니다.
플레이어 코드가
같은 시스템을 직접 알 필요가 없습니다.
단순히
"나 데미지 입었어"
라는 이벤트만 보내면 됩니다.
Unity에서는 보통
ActiondelegateUnityEvent를 사용합니다.
예시
public static Action OnPlayerDamaged;
void TakeDamage()
{
OnPlayerDamaged?.Invoke();
}
"지금은 공격 중이니까 이동은 못 해!"
객체의 현재 상태에 따라 행동을 변경하는 패턴입니다.
복잡한 if-else 구조를 해결하는 데 매우 유용합니다.
State 인터페이스
│
├ IdleState
├ RunState
├ AttackState
└ DeadState
public interface IState
{
void Enter();
void Execute();
void Exit();
}
public class IdleState : IState
{
public void Enter() {}
public void Execute() {}
public void Exit() {}
}
새로운 상태가 추가될 때
"버리지 말고 재활용하자!"
객체를 Destroy하고 Instantiate하는 대신
미리 만들어 둔 객체를 재사용하는 방식입니다.
Unity에서
InstantiateDestroy는 매우 비용이 큰 연산입니다.
이 과정에서
이 일어나면서 프레임 드랍이 발생할 수 있습니다.
Object Pooling을 사용하면 이 문제를 크게 줄일 수 있습니다.
총알 20개 생성 → 비활성화
비활성화된 총알을 가져와 활성화합니다.
bullet.SetActive(true);
파괴하지 않고 다시 비활성화합니다.
bullet.SetActive(false);
이렇게 다시 Pool로 반환되어 재사용됩니다.
| 패턴 | 사용 목적 |
|---|---|
| Singleton | 전역 관리 시스템 |
| Observer | 이벤트 기반 시스템 |
| State | 상태 기반 행동 제어 |
| Object Pooling | 객체 재사용으로 성능 최적화 |
이러한 패턴들을 적절히 활용하면