싱글 게임을 멀티 게임으로 바꾸는 과정에서, 다른 클라이언트들이 싱글톤 패턴을 적용한 오브젝트에 접근할 수 없는 문제가 생겼습니다.
public void PlayerJoined(PlayerRef player)
{
if (player == Runner.LocalPlayer)
{
if ((GameManagerEx.Instance.CurGameType == GameType.MULTI && Runner.IsSharedModeMasterClient) || GameManagerEx.Instance.CurGameType != GameType.MULTI)
{
Runner.Spawn(mapManagerPrefab);
}
LoadMap(); // 해당 함수내에서 mapManagerPrefab의 싱글톤 컴포넌트 접근
}
//...
}
SharedModeMasterClient 의 경우에는 제대로 동작했지만, 다른 클라이언트들만 에러가 발생하는 것으로 보아 동기화 문제임을 알 수 있었습니다.
private static MapGenerator instance = null;
void Awake()
{
if (null == instance)
{
instance = this;
}
}
public static MapGenerator Instance
{
get
{
if (null == instance) return null;
return instance;
}
}
싱글톤을 적용한 부분입니다.
해당 부분은 SharedModeMasterClient 에서만 실행되는 부분이기 때문에, 다른 클라이언트들의 Instance 는 항상 null 입니다.
// MapGenerator.cs
public override void Spawned()
{
// DO AFTER SPAWN GENERATE
if (null == instance) instance = this;
isSpawned = true;
// Settings ...
}
정확한 문제의 원인은 Awake 에서 초기화를 해준 것이었습니다.
Awake 에서 초기화하던 부분을 Spawned 함수 내로 옮겨줍니다.
또한, isSpawned 변수를 true로 바꾸어 Spawn 이 되었다고 알려줍니다.
// PlayerSpawner.cs
public IEnumerator CreateMap()
{
while (!MapGenerator.Instance.IsSpawned)
yield return null;
// MapGenerator Function Calls ...
}
PlayerJoined 부분에서는 IsSpawned 가 True가 될 때까지 기다렸다가 다음 함수들을 실행시켜주면 에러가 발생하지 않습니다.