
소유권(Ownership)은 반드시 이해해야 할 매우 중요한 개념입니다. 이미 “클라이언트가 소유한 액터”와 같은 항목이 포함된 표를 본 적이 있을 것입니다.
서버 또는 클라이언트가 액터(Actor)를 '소유'할 수 있습니다.
예를 들어, PlayerController는 로컬 플레이어(클라이언트 또는 리슨 서버)가 소유합니다.
또 다른 예시는 씬(Scene)에 생성되거나 배치된 문(door)입니다. 이런 경우 대부분 서버가 소유하게 됩니다.
앞선 내용을 다시 살펴보면, 예를 들어 클라이언트가 자신이 소유하지 않은 액터에서 서버 RPC를 호출하면 해당 호출이 무시된다는 것을 알 수 있습니다.
즉, 클라이언트는 서버가 소유한 액터에서 “Server_Interact”를 호출할 수 없습니다. 그렇다면 이 문제를 어떻게 해결할 수 있을까요?
클라이언트가 소유한 클래스/액터를 사용하면 됩니다. 여기서 PlayerController가 빛을 발합니다. 이미 PlayerController 클래스를 논의할 때, UserWidget 버튼 클릭을 기반으로 값을 증가시키는 RPC를 보내는 비슷한 예시를 다룬 적이 있습니다.

따라서 액터에서 Input을 활성화하고 ServerRPC를 호출하는 대신, PlayerController에 ServerRPC를 생성하고 서버가 액터에서 인터페이스 함수(예: 'Interact')를 호출하도록 합니다.
💡 정보
Interfaces는 멀티플레이어에만 국한된 것이 아니며, 아직 잘 모른다면 꼭 찾아보시길 추천합니다.
게임플레이 프레임워크 개요에서 이미 언급했듯이, PlayerController는 플레이어가 '소유'하는 첫 번째 클래스입니다. 하지만 이것이 무슨 의미일까요?
각 '연결(Connection)'에는 해당 연결을 위해 특별히 생성된 PlayerController가 있습니다. 이러한 이유로 생성된 PlayerController는 해당 연결이 소유합니다.
따라서 액터가 누군가에 의해 소유되는지 확인하려면, 소유자를 위쪽(재귀적으로)으로 쭉 따라가 가장 바깥쪽 소유자에 도달해야 하며, 이 소유자가 PlayerController라면, 그 PlayerController를 소유한 연결(Connection)도 해당 액터를 소유하게 됩니다.
꽤 간단하죠? 예시를 들어볼까요?
Pawn/Character는 PlayerController에 의해 조종(possess)됩니다. 이 기간 동안 PlayerController가 해당 Pawn의 소유자가 됩니다. 즉, 이 PlayerController를 소유한 연결(Connection)도 Pawn을 소유하게 됩니다.
이것은 PlayerController가 Pawn을 조종하는 동안에만 해당됩니다. 조종을 해제(Un-possess)하면 클라이언트는 더 이상 Pawn을 소유하지 않게 됩니다.
그렇다면 왜 이것이 중요하며, 어디에 필요할까요?
RPC는 소유된 연결(Connection)에 따라 클라이언트 또는 서버에서 호출될 때 다르게 동작합니다.
또한 조건부 복제(Conditional Replication)에 대해 읽었을 텐데, 이는 변수들이 특정 조건에서만 복제되는 것을 의미합니다.
다음 섹션에서는 위 목록의 관련성 부분을 설명합니다.