싱글턴
씬에 하나뿐인 behaviour를 어디서든 Type.Instance로.
월드에는 보통 하나뿐인 것이 있습니다. 경기, 상점, 문 관리자. 다른 모든 behaviour가 그것에 닿아야 하고, 인스펙터에서 하나씩 참조를 연결하는 방식은 스무 개가 될 때까지는 버팁니다. 아무도 연결을 기억하지 못한 새 프리팹이 생기기 전까지는요.
Singleton<T>를 상속하세요.
using Udonite;
public class GameManager : Singleton<GameManager>
{
public int score;
public void Award()
{
score = score + 1;
}
}
GameObject에 하나 올리고, 이름은 원하는 대로 붙이고, 다른 어떤 behaviour에서든 가져다 쓰세요.
GameManager.Instance.Award();
속성도, 직접 쓸 접근자도, 끌어다 놓을 참조도 없습니다. 오브젝트 이름에 기대는 것도 없습니다. Instance 읽기는 가벼워서 Update 안에서 신경 쓰지 않고 써도 됩니다.
씬에 하나라는 것은 편집 중에 확인됩니다
씬에 둘 있으면 콘솔이 두 오브젝트를 모두 짚고, 메시지를 클릭하면 그중 하나가 선택됩니다.
Udonite: GameManager is a Singleton<GameManager> and there are 2 in the scene:
'Managers/GameManager', 'Spawn/GameManager'. A singleton is one behaviour, and
nothing can choose between these. Delete the extras.
하나도 없으면 그것도 알려 주고, 하나 놓을 때까지 씬의 모든 GameManager.Instance는 아무것에도 닿지 않습니다.
둘 다 Udonite가 컴파일할 때마다, 그리고 씬을 저장할 때마다 확인하므로, 두 번째 복사본을 오브젝트에 끌어다 놓아도 바로 알 수 있습니다.
서로 다른 싱글턴이 여럿인 것은 평범합니다. 각각 따로 찾으므로 하나가 다른 하나를 건네줄 일은 없습니다.
참조가 먼저 준비되고, 값은 나중에 들어옵니다
GameManager.Instance는 첫 프레임부터 쓸 수 있습니다. GameManager가 자기 Start에서 넣는 값은 아직일 수 있습니다.
Unity는 모든 Start를 어떤 Update보다 먼저 돌립니다. 월드는 그러지 않고, Play 모드에서는 그 차이가 보이지 않으므로 업로드 전에 알아 둘 만합니다.
public override void Update()
{
label.text = GameManager.Instance.score.ToString(); // 괜찮음
title.text = GameManager.Instance.title; // 1프레임째엔 비어 있을 수 있음
}
확실한 방법은 둘입니다. 인스펙터에서 값을 넣어 두거나, 그것은 Start보다 먼저 들어 있습니다.
public string title = "Match";
아니면 프레임이 아니라 값 자체를 기다리세요.
public override void Update()
{
if (ready)
return;
if (GameManager.Instance.title == "")
return;
ready = true;
// 여기부터는 안전
}
참조 자체는 기다릴 필요가 없습니다.
static 필드에 인스턴스를 담을 수는 없습니다
public static GameManager Instance; // UDN0002
월드의 behaviour는 저마다 자기 메모리를 가지므로 static 필드는 behaviour 사이에서 공유되지 않습니다. 두 behaviour가 각자 자기 복사본을 갖고, 어느 쪽도 상대가 쓴 값을 보지 못합니다. 월드가 조용히 어긋나느니 Udonite는 거부합니다.
하나뿐인 것을 두는 방법은 Singleton<T>입니다. 변하지 않는 값이라면 const와 static readonly는 여전히 쓸 수 있습니다.