
싱글플레이 환경에서는
SpawnActor함수 호출만으로 액터 생성이 가능했으나, 멀티플레이 환경에서는 클라이언트가 생성한 액터가 타인에게 보이지 않는 동기화 문제가 발생한다. 이를 해결하기 위해 Server RPC를 활용하여 서버에 생성을 요청하는 구조를 구현하고, 생성된 액터의 소유권(Ownership)을 명확히 설정하는 과정을 정리했다.
_Implementation, _Validate) 작성법 습득SpawnActor 호출 시 발생하는 문제점과 서버 권한(Authority)의 중요성 이해LandMine(지뢰) 액터를 구현하고 입력 키(F)에 SpawnActor 로직을 연결했으나, 클라이언트 A가 설치한 지뢰가 서버나 클라이언트 B의 화면에는 렌더링되지 않는 현상이 발생했다.
SpawnActor는 해당 로컬 클라이언트의 메모리(World)에만 액터를 생성한다. 서버는 이 액터의 존재를 인지하지 못하므로, 다른 클라이언트에게 이를 전파(Replicate)할 수 없다.Server RPC는 일반적인 C++ 함수와 달리, 언리얼 네트워크 프레임워크에 의해 선언과 구현이 분리된다.
UFUNCTION(Server, Reliable, WithValidation) 매크로를 사용하여 선언한다.Reliable: 패킷 손실 시 재전송을 보장하여, 지뢰 생성과 같은 중요한 로직이 반드시 실행되도록 한다.WithValidation: 서버 보안을 위해 유효성 검사 함수를 추가한다._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; // 유효성 검사 통과
}
Server RPC를 통해 지뢰를 생성하고 액터의 bReplicates = true 속성을 활성화하면 모든 클라이언트에서 지뢰를 볼 수 있다. 하지만, 로그 확인 시 생성된 지뢰가 누구의 소유인지 구분되지 않는 문제가 발생할 수 있다.
SetOwner(this)를 호출하여, RPC를 요청한 플레이어(Pawn 혹은 Controller)를 해당 액터의 소유자로 등록해야 한다.| 개념 | 설명 | 비고 |
|---|---|---|
| Server RPC | 클라이언트가 호출하지만 서버에서 실행되는 함수 | Implementation, Validate 구현 필수 |
| SpawnActor | 실행되는 영역(Memory)에만 액터를 생성함 | 멀티플레이에서는 반드시 서버에서 수행해야 함 |
| bReplicates | 액터의 존재를 네트워크 상에 전파할지 여부 | 생성자 등에서 true로 설정 필요 |
| SetOwner | 액터의 소유자(Owner)를 명시적으로 지정 | 아군/적군 식별 및 권한 확인에 사용됨 |