반응형

Unity Netcode: 클라이언트가 요청하고 서버가 스폰하는 구조 정리
개요
- 클라이언트가 캐릭터 생성 요청을 보냄
- 서버가 캐릭터 프리팹을 생성 및 Spawn
- 이후 능력치 데이터(HeroData)를 ClientRpc를 통해 각 클라이언트에게 전달
- 각 클라이언트는 받은 데이터를 바탕으로 자신의 캐릭터인지 확인하고 초기화 수행
① 클라이언트 or 호스트 구분
if (IsClient && !IsServer)
{
// [1-1] 클라이언트: 서버에게 히어로 스폰 요청
ServerSpawnHeroServerRpc(LocalClientID());
}
else if (IsServer)
{
// [1-2] 호스트: 직접 HeroSpawn() 실행 (자기 자신이 서버이므로 ServerRpc 필요 없음)
HeroSpawn(LocalClientID());
}
② 클라이언트가 보낸 ServerRpc 실행
[ServerRpc(RequireOwnership = false)]
private void ServerSpawnHeroServerRpc(ulong clientId)
{
// [1-3] 서버: 클라이언트 요청을 받아 직접 HeroSpawn() 실행
HeroSpawn(clientId);
}
③ 서버에서 캐릭터 생성 및 데이터 준비
private void HeroSpawn(ulong clientId)
{
// [1-4] 서버: 프리팹 인스턴스화 및 네트워크 스폰
var go = Instantiate(_spawn_Prefab);
NetworkObject networkObject = go.GetComponent<NetworkObject>();
networkObject.Spawn(); // → 이 오브젝트는 자동으로 모든 클라이언트에 동기화됨
// [1-5] 서버: Resources 폴더에서 Hero ScriptableObject 리스트 가져오기
Hero_Scriptable[] m_Character_Datas = Resources.LoadAll<Hero_Scriptable>("Character_Scriptable");
var data = m_Character_Datas[UnityEngine.Random.Range(0, m_Character_Datas.Length)];
// [1-6] 서버: 능력치 데이터를 ClientRpc로 클라이언트들에게 전달
ClientSpawnHeroCLientRpc(networkObject.NetworkObjectId, clientId, data.GetHeroData());
}
④ 모든 클라이언트에서 캐릭터 초기화
[ClientRpc]
private void ClientSpawnHeroCLientRpc(ulong networkId, ulong clientId, HeroData data)
{
// [1-7] 클라이언트(호스트 포함): 서버가 스폰한 오브젝트를 찾고, 능력치 초기화
if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(networkId, out var heroNetworkObject))
{
bool isMine = clientId == LocalClientID();
SetPositionHero(heroNetworkObject, isMine);
heroNetworkObject.GetComponent<Hero>().Initialize(data);
}
}
🔄 요약 흐름
- 클라이언트가 버튼을 누름 → ServerRpc 호출
- 서버에서 히어로 오브젝트 생성 및 Spawn
- 서버에서 ScriptableObject 기반 능력치 추출 → HeroData 구조체 생성
- ClientRpc 호출 → 모든 클라이언트가 해당 오브젝트를 초기화
💡 참고: 왜 HeroData 구조체를 쓰는가?
- ScriptableObject는 네트워크로 직접 전송할 수 없음
- 따라서 INetworkSerializable을 구현한 순수 데이터 구조체로 변환 필요
- HeroData 구조체는 서버에서 ClientRpc로 전송 가능
반응형
'유니티 > 서버' 카테고리의 다른 글
| Netcode 공부 메모 (0) | 2025.05.27 |
|---|
