Unity Netcode - 클라 요청 -> 서버 스폰 구조 정리 (랜덤 캐릭터 생성)

반응형


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);
    }
}

🔄 요약 흐름

  1. 클라이언트가 버튼을 누름 → ServerRpc 호출
  2. 서버에서 히어로 오브젝트 생성 및 Spawn
  3. 서버에서 ScriptableObject 기반 능력치 추출 → HeroData 구조체 생성
  4. ClientRpc 호출 → 모든 클라이언트가 해당 오브젝트를 초기화

💡 참고: 왜 HeroData 구조체를 쓰는가?

  • ScriptableObject는 네트워크로 직접 전송할 수 없음
  • 따라서 INetworkSerializable을 구현한 순수 데이터 구조체로 변환 필요
  • HeroData 구조체는 서버에서 ClientRpc로 전송 가능

 

반응형

'유니티 > 서버' 카테고리의 다른 글

Netcode 공부 메모  (0) 2025.05.27