제네릭 싱글턴
Coddy Unity 여정의 Unity 게임 아키텍처 섹션에 포함된 레슨. 64개 중 43번째.
3절의 싱글턴은 각 매니저에서 반복되는 다섯 줄, 즉 static Instance, 이를 설정하는 Awake, 중복 확인으로 이루어져 있습니다. 제네릭 기본 클래스에 이 코드를 한 번만 작성합니다. 각 매니저는 이 클래스를 상속하고, 자신의 타입을 지정합니다:
public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
public static T Instance { get; private set; }
protected virtual void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this as T;
}
}
public class ScoreManager : Singleton<ScoreManager>
{
public int score;
public void Add(int points) { score += points; }
}
public class SoundManager : Singleton<SoundManager>
{
public void Play(string clip) { Debug.Log("Playing " + clip); }
}// 어떤 스크립트에서든
ScoreManager.Instance.Add(10);
SoundManager.Instance.Play("coin");제네릭 클래스의 static 멤버는 그 클래스로 생성된 각 타입에 속합니다. Singleton<ScoreManager>와 Singleton<SoundManager>는 각각 Instance를 가진 별개의 타입이므로 매니저들은 하나의 Instance를 공유하지 않습니다. ScoreManager.Instance는 이미 ScoreManager 타입이며, 이것이 바로 T를 사용하는 이유입니다. 기본 클래스 안에서 this는 Singleton<T>로만 알려져 있으므로, this as T를 사용해 이를 실제 매니저 타입으로 전달합니다.
기본 클래스는 abstract입니다. Unity는 오브젝트에 매니저만 추가합니다. 자체 Awake가 필요한 매니저는 일반적인 void Awake()를 작성하면 안 됩니다. 그러면 기본 클래스의 메서드를 숨기게 되고(컴파일러가 경고합니다), Unity는 매니저의 메서드만 호출하여 Instance가 설정되지 않습니다. 이를 오버라이드하고 먼저 기본 메서드를 호출하세요:
protected override void Awake()
{
base.Awake();
score = 0;
}챌린지
중급두 매니저 모두 씬을 불러와도 유지되는 기반을 갖게 하세요.
PersistentSingleton에protected virtual void Awake()를 작성하세요. 첫 번째 인스턴스는Instance가 되어 유지되고(DontDestroyOnLoad), 이후에 생성된 인스턴스는 자기 자신을 제거합니다.Wallet과MusicPlayer가 이를 상속하도록 하고, 이들의Instance와 Wallet의 Awake를 삭제하세요.MusicPlayer에서 Awake를 재정의하세요. 먼저base.Awake()를 호출한 다음, 자신이 Instance라면Now playing: Adventure를 로그로 출력합니다.
‘플레이’를 누르고 숲에 갔다가 돌아오세요. 코인 1개가 있어야 합니다. 그런 다음 ‘확인’을 누르세요.
직접 해보기
using UnityEngine;
public abstract class PersistentSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
public static T Instance { get; private set; }
// Awake: 씬을 로드해도 첫 번째 인스턴스는 유지하고, 이후 생성된 인스턴스는 모두 제거한다
}
Unity 게임 아키텍처의 모든 레슨
직접 연습해 보세요: Unity 플레이그라운드