
아래 내용은 AI 를 통한 정리가 이루어져 있음을 미리 공지 합니다.
Unity에서 멀티플레이어 게임을 개발하다 보면 한 PC에서 여러 클라이언트를 띄워 테스트해야 하는 상황이 반드시 옵니다. 최근 유니티가 제공하는 MPPM(Multiplayer Play Mode)은 매우 편리하지만, 환경 설정을 제대로 하지 않으면 원인 모를 NullReferenceException과 크래시에 시달리게 됩니다. 제가 겪은 주요 이슈와 해결책을 정리합니다.
플레이어 1(Host)이 방을 만들고 대기 중인데, 플레이어 2(Client)가 로그인을 시도하는 순간 플레이어 1의 콘솔에 다음과 같은 에러가 끝없이 찍힙니다.
NullReferenceException: Object reference not set to an instance of an object (Unity.Services.Lobbies.Internal.WrappedLobbyService.TryCatchRequest)
유니티 서비스(UGS)는 기본적으로 "한 기기 = 한 명의 유저"를 가정합니다.
Update 루프에서 Null 참조가 발생한 것입니다.초기화 단계에서 각 플레이어마다 독립된 프로필(저장 경로)을 지정해줘야 합니다.
var options = new InitializationOptions();
#if UNITY_EDITOR
// 실행 시마다 고유한 프로필명을 부여하여 세션 경로 분리
options.SetProfile($"Player_{Guid.NewGuid().ToString().Substring(0, 8)}");
#endif
await UnityServices.InitializeAsync(options);
세션을 분리했는데도 간헐적으로 같은 NullReferenceException이 발생했습니다. 특히 플레이어 참여/탈퇴 시점에 집중되었습니다.
로비 이벤트(LobbyChanged, PlayerJoined, ...)를 구독하고 있었는데, 이벤트가 발생할 때마다 GetLobbyAsync를 수동으로 다시 호출하고 있었습니다.
private bool _isUpdating = false;
private async Task UpdateDataHandler() {
if (_isUpdating) return; // 이미 실행 중이면 무시
_isUpdating = true;
try {
var lobby = await LobbyService.Instance.GetLobbyAsync(currentLobbyId);
// 처리 로직...
} finally {
_isUpdating = false;
}
}
ExecutionEngineException: String conversion error와 함께 유니티가 강제 종료되는 현상이 발생했습니다. 로그에는 Could not initialize persistence라는 메시지가 남았습니다.
Firebase Realtime Database는 오프라인 지원을 위해 로컬에 데이터를 캐싱(Persistence)합니다.
한 기기에서 여러 클라이언트를 돌릴 때는 로컬 캐싱 기능을 꺼야 합니다.
// 초기화 시점에 호출
FirebaseDatabase.DefaultInstance.SetPersistenceEnabled(false);
멀티플레이어 환경에서 "공유 자원(파일, 세션, 메모리)"은 언제나 폭탄이 될 수 있습니다.
이 세 가지만 지켜도 MPPM 환경에서의 의문사 90%는 예방할 수 있습니다. 킹받는 에러였지만 덕분에 내부 동작 원리를 깊게 판 좋은 경험이었습니다! 🛠️