[DAY71] RPC Practice : Server RPC & Actor Spawning

베리투스·2025년 11월 26일

TIL: Today I Learned

목록 보기
61/93
post-thumbnail

싱글플레이 환경에서는 SpawnActor 함수 호출만으로 액터 생성이 가능했으나, 멀티플레이 환경에서는 클라이언트가 생성한 액터가 타인에게 보이지 않는 동기화 문제가 발생한다. 이를 해결하기 위해 Server RPC를 활용하여 서버에 생성을 요청하는 구조를 구현하고, 생성된 액터의 소유권(Ownership)을 명확히 설정하는 과정을 정리했다.


📌 오늘의 목표

  • Server RPC의 정의 및 내부 구현 함수(_Implementation, _Validate) 작성법 습득
  • 클라이언트 측 SpawnActor 호출 시 발생하는 문제점과 서버 권한(Authority)의 중요성 이해
  • 네트워크 액터의 Replicates 설정 및 SetOwner를 통한 소유권 설정 필요성 파악

📚이론 및 원리

1. 클라이언트 스폰의 한계와 Server RPC

LandMine(지뢰) 액터를 구현하고 입력 키(F)에 SpawnActor 로직을 연결했으나, 클라이언트 A가 설치한 지뢰가 서버나 클라이언트 B의 화면에는 렌더링되지 않는 현상이 발생했다.

  • 원인: 클라이언트에서 호출된 SpawnActor는 해당 로컬 클라이언트의 메모리(World)에만 액터를 생성한다. 서버는 이 액터의 존재를 인지하지 못하므로, 다른 클라이언트에게 이를 전파(Replicate)할 수 없다.
  • 해결책: 액터의 생성과 같은 게임플레이에 중요한 변경 사항은 반드시 서버 권한(Authority) 하에 이루어져야 한다. 따라서 클라이언트는 Server RPC를 통해 서버에 "지뢰 생성을 요청"하고, 실제 생성은 서버가 수행하도록 로직을 변경해야 한다.

2. Server RPC 구현 절차

Server RPC는 일반적인 C++ 함수와 달리, 언리얼 네트워크 프레임워크에 의해 선언과 구현이 분리된다.

  1. 헤더 선언: UFUNCTION(Server, Reliable, WithValidation) 매크로를 사용하여 선언한다.
    • Reliable: 패킷 손실 시 재전송을 보장하여, 지뢰 생성과 같은 중요한 로직이 반드시 실행되도록 한다.
    • WithValidation: 서버 보안을 위해 유효성 검사 함수를 추가한다.
  2. 소스 구현: 함수명 뒤에 접미사를 붙여 두 개의 함수를 구현해야 한다.
    • _Implementation: 서버에서 실제로 실행될 로직 (지뢰 스폰).
    • _Validate: 요청의 유효성을 검증하는 보안 로직.
// [Header]
UFUNCTION(Server, Reliable, WithValidation)
void ServerRPCSpawnLandMine();

// [CPP]
void ADXPlayerCharacter::ServerRPCSpawnLandMine_Implementation()
{
    // 이 코드는 서버에서만 실행된다.
    if (IsValid(LandMineClass))
    {
        FVector Loc = GetActorLocation() + (GetActorForwardVector() * 300.f);
        
        // 서버 월드에 액터를 생성한다.
        ADXLandMine* Mine = GetWorld()->SpawnActor<ADXLandMine>(LandMineClass, Loc, FRotator::ZeroRotator);
        
        // 생성된 액터의 소유권을 설정한다.
        if (Mine)
        {
            Mine->SetOwner(this);
        }
    }
}

bool ADXPlayerCharacter::ServerRPCSpawnLandMine_Validate()
{
    return true; // 유효성 검사 통과
}

3. 소유권(Ownership) 설정의 중요성

Server RPC를 통해 지뢰를 생성하고 액터의 bReplicates = true 속성을 활성화하면 모든 클라이언트에서 지뢰를 볼 수 있다. 하지만, 로그 확인 시 생성된 지뢰가 누구의 소유인지 구분되지 않는 문제가 발생할 수 있다.

  • 필요성: 추후 "내가 설치한 지뢰"와 "적이 설치한 지뢰"를 구분하거나, 특정 클라이언트에게만 UI를 띄우는 등의 로직을 처리하기 위해서는 누가 이 액터를 생성했는지(Owner)에 대한 정보가 필수적이다.
  • 구현: 액터 생성 직후 SetOwner(this)를 호출하여, RPC를 요청한 플레이어(Pawn 혹은 Controller)를 해당 액터의 소유자로 등록해야 한다.

✅ 핵심 요약

개념설명비고
Server RPC클라이언트가 호출하지만 서버에서 실행되는 함수Implementation, Validate 구현 필수
SpawnActor실행되는 영역(Memory)에만 액터를 생성함멀티플레이에서는 반드시 서버에서 수행해야 함
bReplicates액터의 존재를 네트워크 상에 전파할지 여부생성자 등에서 true로 설정 필요
SetOwner액터의 소유자(Owner)를 명시적으로 지정아군/적군 식별 및 권한 확인에 사용됨
profile
Shin Ji Yong // Unreal Engine 5 공부중입니다~

0개의 댓글