함수 내부에서의 구분
BeginPlay(), Tick(), EndPlay()와 같은 이벤트 함수 혹은
NetMulticast 함수는 Owning Client, Server, Other Client 모두에서 호출이 된다
그렇기에 특정 PC에서 로직이 실행되도록 구현하기 위해서는 아래의 함수들을 활용해야 한다
- HasAuthority()
서버인 경우에 true를 반환한다
Listen 서버의 경우에는 true일 때, 서버 or 방장 클라이다
Standalone 모드에서는 항상 true가 반환된다
if (HasAuthority() == true)
{
// Server
}
else
{
// Owning Client or Other Client
}
- IsLocallyControlled()
현재 액터(ex. 폰)를 현재 클라이언트에서 컨트롤하는지 확인해서
Owning Client인 경우에 true를 반환한다
해당 함수는 Pawn 또는 Controller 같은 클래스에서 올바르게 동작한다
if (IsLocallyControlled() == true)
{
// Owning Client
}
else
{
// Other Client or Server
}
- GetOwner() == GetPlayerController(0)
만약 Pawn이 아닌 다른 액터라면 GetOwner()를 통해 확인을 해야 한다
그러기 위해선 해당 액터의 Owner 설정은 필수이다
이처럼 해당 조건식을 사용하면, Owning Client인 경우에 true를 반환한다
그리고 GetOwner()를 통해 APawn을 가져와 IsLocallyControlled()를 체크하는 방식도 가능하다
if (GetOwner() == UGameplayStatics::GetPlayerController(0))
{
// Owning Client
}
...
APawn* OwnerPawn = Cast<APawn>(GetOwner());
if (OwnerPawn && OwnerPawn->IsLocallyControlled())
{
// Owning Client
}
Get/SetOwner()의 진실
Owner를 사용하기 전 반드시 알아야 할 개념이 있다
Owner는 일반적으로 Server에서 설정을 하고 클라들에게는 복제가 되지 않는다
그래서 Server에서 GetOwner()를 호출해 활용하는 것은 문제가 없지만
각 클라들에서 GetOwner()를 사용하면 nullptr이 반환될 가능성이 높다
그렇기에 속성을 추가적으로 만들어 복제를 하는 방식처럼
추가적인 과정이 필요하다
SetOwner() 설정 위치
SetOwner()를 통해 Owner를 설정하는 경우
두 가지 경우에 따라 설정하는 위치가 달라진다
1. Pawn
폰의 Owner를 설정하는 경우에는
서버에서만 호출되는 PossessedBy 함수 내부에 설정을 하면 된다
virtual void PossessedBy(AController* NewController);
2. 소유 액터
폰이 아닌 폰이 소유할 수 있는 특정 액터의 Owner를 설정하는 경우에는
서버에서 해당 액터를 생성할 때
아래와 같이 설정을 하면 된다
참고로 서버에는 여러 개의 PlayerController가 존재하기 때문에,
클라이언트가 직접 자신의 Controller 정보를 제공해야 올바른 Owner를 설정할 수 있다
UFUNCTION(Server, Reliable, WithValidation)
void Server_SpawnLandMine(AController* OwningController, FVector SpawnLocation);
...
void AMyCharacter::Server_SpawnLandMine_Implementation(AController* OwningController, FVector SpawnLocation)
{
if (!OwningController) return; // 방어 코드
ASLandMine* SpawnedLandMine = GetWorld()->SpawnActor<ASLandMine>(LandMineClass, SpawnLocation, FRotator::ZeroRotator);
if (SpawnedLandMine)
{
SpawnedLandMine->SetOwner(OwningController); // 올바른 Owning Client의 컨트롤러 설정
}
}
'게임 엔진 > [코드조선] 언리얼 데디서버' 카테고리의 다른 글
애니메이션 동기화 (0) | 2025.03.07 |
---|---|
Replicated, ReplicatedUsing 키워드 (0) | 2025.03.07 |
RPC 활용 (0) | 2025.03.07 |
RPC 키워드 사용법 (0) | 2025.03.07 |
RPC (Remote Procedure Call) (0) | 2025.03.07 |