Machineboy空

싱글톤 패턴(Singleton Pattern) 본문

Game/Unity

싱글톤 패턴(Singleton Pattern)

안녕도라 2024. 10. 30. 11:53

싱글톤은 글로벌 싱글 오브젝트 인스턴스를 관리하는 잘 알려진 패턴이다. GameManager는 단일한 게임 상태를 컨트롤하기 위해 여러 클래스들이 사용하므로 싱글톤을 사용하기에 완벽한 조건이다.


 

『 움직이는 증강 현실 게임 개발』 마이클 랜햄 지음 P.255~

 

모든 오브젝트를 씬(scene)에서 로컬로 관리했다. 따라서 서비스(service)나 관리자(manager)의 수명에 대해 걱정할 필요가 없었다. 하지만 게임이 개발되면서 사용하는 씬의 숫자가 늘어난다. 이제 서비스나 관리자 클래스는 자식 씬들은 물론 코드에서 쉽게 접근할 수 있어야 한다. 

 

옛날 게임에서는 씬들과 스크립트 전체에서 게임 상태를 체크하기 위해 글로벌이나 정적(static)변수를 사용했다. 글로벌 정적 클래스를 사용할 수도 있지만 다음과 같은 문제점들이 있다.

  • 정적 클래스는 지연돼서 불려오고(lazy loaded), 유니티에서는 특히 취약할 수 있다.
  • 정적 클래스는 인터페이스(interface)를 구현할 수 없다.
  • 정적 클래스는 오브젝트에서만 파생될 수 있다. 그들은 MonoBehaviour에서 상속받을 수 없으므로 유니티에서 컴포넌트로 사용된다. 따라서 유니티의 코루틴 또는 Start, Update 등과 같은 다른 기본 메소드를 사용할 수 없다.

일반적인 MonoBehviour 게임 오브젝트를 선언할 때와 업데이트된 GPSLocationServisce스크립트로 싱글톤을 사용하는 경우의 차이점을 살펴보자.

public class GPSLocationServece: Monoehaviour

 

이것은 여러 번 본 바와 같이 유니티 컴포넌트를 선언하는 일반적인 방법이다. 이제 GPSLocationService의 새로운 클래스 선언과 비교해 보자.

public class GPSLocationService: Singleton<GPSLocationService>

 

 

이상하게 보일 수도 있을 것이다. 싱글톤이라 불리는 일반(generic)타입으로부터 상속받는 오브젝트를 선언하면서 타입으로 스스로를 지정한다. Singleton클래스는 인스턴스를 글로벌 정적 변수로 변환해 코드의 아무 곳에서나 접근하게 해주는 래퍼다. 다음은 이전에 GPS 서비스를 접근했던 방법과 지금의 방법이다.

 

//이전에는 GPS 서비스 오브젝트가 에디터에서 설정해야 하는 클래스의 필드로 설정했다.
public GPSLocationService gpsLocationService;
gpsLocationService.OnMapRedraw += gpsLocationService_OnMapRedraw;

//이제 GPS 서비스는 싱글톤으로서 어디에서나 접근할 수 있다.
GPSLocationService.Instance.OnMapRedraw += GpsLocationService_OnMapRedraw;

 

싱글톤을 구현할 때 알아둬야 할 한 가지 중요한 부분이 있다. 씬에서 게임 오브젝트로서 싱글톤 매니저 혹은 서비스가 생성되는지 확실히 해야 한다는 것이다. 이제 구성이 끝났으니 Start, Awake, Update 및 다른 메소드에서 사용할 수 있다. 하지만 신에서 이러한 오브젝트를 추가하지 않고 코드에서 접근하려고 하면 접근할 수는 있겠지만 Awake나 Start 메소드에서 일어나는 중요한 초기화 부분을 놓칠 수 있따.