Ownership이란 무엇이며 왜 중요한가
12강. Ownership이란 무엇이며 왜 중요한가
1. 이번 강의에서 해결할 문제
클라이언트가 월드의 아이템 Actor에서 Server RPC를 호출했는데 아무 일도 일어나지 않습니다. 함수 선언이 맞아도 그 Actor가 해당 클라이언트의 Owning Connection에 속하지 않으면 요청이 서버로 전달되지 않습니다. Ownership은 단순한 객체 부모 관계가 아니라 네트워크 라우팅과 권한의 핵심입니다.
2. 학습 목표
3. 핵심 개념
클라이언트 연결은 서버가 만든 PlayerController와 연결됩니다. 그 Controller가 Possess한 Pawn과 Owner 체인을 통해 연결에 귀속된 Actor·Component가 소유 RPC 경계를 형성합니다. 서버는 모든 Actor에 Authority가 있지만 모든 Actor가 특정 클라이언트 소유인 것은 아닙니다.
Client Connection
↔ server-side PlayerController
→ possessed Character (Owner / Controller 관계)
→ replicated InteractionComponent
World Pickup (Owner 없음)
× 클라이언트가 직접 Server RPC를 보내기 부적합
4. 단계별 실습
파일 경로: Source/CaptureArena/Interaction/CaptureInteractionComponent.h
UCLASS(ClassGroup = "Capture", meta = (BlueprintSpawnableComponent))
class CAPTUREARENA_API UCaptureInteractionComponent : public UActorComponent
{
GENERATED_BODY()
public:
UCaptureInteractionComponent();
void RequestInteract(AActor* Candidate);
protected:
UFUNCTION(Server, Reliable)
void Server_RequestInteract(AActor* Candidate);
};
UCaptureInteractionComponent::UCaptureInteractionComponent()
{
PrimaryComponentTick.bCanEverTick = false;
SetIsReplicatedByDefault(true);
}
void UCaptureInteractionComponent::RequestInteract(AActor* Candidate)
{
const APawn* OwnerPawn = Cast<APawn>(GetOwner());
if (!OwnerPawn || !OwnerPawn->IsLocallyControlled()) return;
Server_RequestInteract(Candidate);
}
void UCaptureInteractionComponent::Server_RequestInteract_Implementation(
AActor* Candidate)
{
APawn* OwnerPawn = Cast<APawn>(GetOwner());
if (!IsValid(OwnerPawn) || !IsValid(Candidate)) return;
const float DistanceSq = FVector::DistSquared(
OwnerPawn->GetActorLocation(), Candidate->GetActorLocation());
if (DistanceSq > FMath::Square(250.0f))
{
return;
}
// Candidate의 서버 전용 상호작용 인터페이스 호출
}
Component의 Owner인 Character가 해당 클라이언트의 소유 체인에 있고 Actor와 Component가 복제되므로 Server RPC를 라우팅할 수 있습니다. Candidate 포인터를 받더라도 서버는 유효성, 거리, 상태와 인터페이스를 다시 검사합니다.
실패 재현: 레벨에 놓인 Owner 없는 Pickup에 같은 Server RPC를 선언하고 클라이언트에서 직접 호출합니다. 서버에 도달하지 않는 로그를 확인한 뒤 RPC를 Character Component 경계로 되돌립니다.
5. 코드가 동작하는 이유
RPC 시스템은 호출 Actor의 Owning Connection으로 송수신 대상을 결정합니다. 소유 Character의 Component는 연결을 찾을 수 있지만 공용 World Actor는 특정 클라이언트 연결을 대표하지 않습니다. 따라서 클라이언트 입력은 소유 Controller/Pawn/Component에서 서버로 들어오고 서버가 공용 Actor를 조작합니다.
6. 자주 하는 실수와 해결법
7. 직접 실습
8. 이해 점검 질문 3개
9. 핵심 요약
Ownership이란 무엇이며 왜 중요한가 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.