인프런 커뮤니티 질문&답변

우현우님의 프로필 이미지
우현우

작성한 질문수

이득우의 언리얼 프로그래밍 Part3 - 네트웍 멀티플레이 프레임웍의 이해

8강 RPC 기초

IsLocalControlled와 오너쉽

작성

·

282

·

수정됨

0

8강 48분 40초에서 Client, Server RPC의 사용 조건인 엑터의 오너쉽 여부를 IsLocalControlled함수로 파악하라고 되어있습니다.

근데 서버에서 ROLE_Authority / ROLE_AutonomousProxy에 해당 하는 엑터는 IsLocalControlled가 false인데 클라이언터와의 커넥션은 가지고 있어 client RPC가 사용 가능하고,

ROLE_Authority / ROLE_SimulatedProxy는 IsLocalControlled가 true이지만 커넥션 없을 수도 있어 Client RPC를 사용하지 못할 수 있지 않나요?

hasAuthority등으로 서버, 클라이언트 여부를 먼저 파악한뒤 클라이언트 일 때 커넥션 오너쉽을 확인하기 위한 용도로 isLocalConrolled를 사용할 수 있다는 뜻인지, 아니면 제가 isLocalConrolled 자체를 잘못 이해한 건지 헷갈립니다.

 

그리고 오너쉽, 소유라는 단어의 개념이 혼동됩니다.

46분 40초에서 pawn의 '오너쉽', 50분의 표에서 클라 '소유', 서버 '소유'에서의 '오너쉽'과 '소유'는 해당 프로세스가 해당 엑터에서 isLocalControlled가 true가 나와 컨트롤 권한을 가지고 있다는 의미이고,

Client, Server RPC의 사용 조건인 엑터의 '오너쉽' 여부에서의 '오너쉽'은 최상위 오너 엑터가 커넥션을 가진 playerContoroller인 경우를 의미하는게 맞나요?

 

 

답변 2

0

이득우님의 프로필 이미지
이득우
지식공유자

IsLocallyControlled는 다음의 로직으로 구성되어 있습니다.

bool AController::IsLocalController() const
{
	const ENetMode NetMode = GetNetMode();

	if (NetMode == NM_Standalone)
	{
		// Not networked.
		return true;
	}
	
	if (NetMode == NM_Client && GetLocalRole() == ROLE_AutonomousProxy)
	{
		// Networked client in control.
		return true;
	}

	if (GetRemoteRole() != ROLE_AutonomousProxy && GetLocalRole() == ROLE_Authority)
	{
		// Local authority in control.
		return true;
	}

	return false;
}

이 함수는 해당 액터가 RPC 통신을 위한 조건을 만족하는지 판별하는 함수로 정리할 수 있습니다. 이를 소유한다 또는 (커넥션) 오너십을 가진다고 표현했습니다. 여기서 추가로 리슨 서버 머신에서 직접 컨트롤하는 액터는 네트웍 통신을 하지 않고 로컬에서 바로 실행된다는 점만 추가로 고려해주시면 됩니다.
( 이러한 점 때문에 리슨서버에서는 방장은 랙이 없다는 엄청난 특혜를 가지는 것이지요 )
언리얼 엔진 소스에서 오너십에 대한 판별은 결국 플레이어 컨트롤러로 귀결되도록 설정되어 있습니다.
아래는 이를 참고할 만한 소스입니다.

bool AActor::HasLocalNetOwner() const
{
	// I might be the top owner if I am a Pawn or a Controller (owner will be null)
	const AActor* TopOwner = this;

	if (Owner != nullptr)
	{
		// I have an owner so search that for the top owner
		for (TopOwner = Owner; TopOwner->Owner; TopOwner = TopOwner->Owner)
		{
		}
	}

	// Top owner will normally be a Pawn or a Controller
	if (const APawn* Pawn = Cast<APawn>(TopOwner))
	{
		return Pawn->IsLocallyControlled();
	}

	const AController* Controller = Cast<AController>(TopOwner);
	return Controller && Controller->IsLocalController();
}

bool APawn::IsLocallyControlled() const
{
	return ( Controller && Controller->IsLocalController() );
}

 

우현우님의 프로필 이미지
우현우
질문자

친절한 답변 감사드립니다

그러면 서버 프로세스에 존재하는 다른 클라이언트가 조작하는 캐릭터, 즉 local role: ROLE_Authority / remote role: ROLE_AutonomousProxy에 해당하는 캐릭터는 커넥션 오너쉽이 없다고 보는건가요?

제가 이해하기론 커넥션 오너쉽은 엑터의 최상위 오너, 즉 컨트롤러가 다른 프로세스로의 커넥션을 소유하고 있는지를 의미하고, islocalcontoroller는 해당 컨트롤러 또는 엑터가 현재 프로세스에서 키입력을 받아 마땅한지를 리턴하는 함수이므로 다른 개념이라고 생각하고 있었습니다.

대표적인 예가 질문에서 언급한 두가지 경우인데 islocalcontrolled의 결과와 client rpc가능여부가 매칭되지않는것 같습니다

이득우님의 프로필 이미지
이득우
지식공유자

오너십 및 LocalController에 대한 해석은 문서를 통해 유추하기 보다는, 소스 코드를 직접 보고 이해하는 것이 더 명확합니다.
둘은 다른 용도로 기획되었지만, 액터의 HasLocalNetOwner의 구현은 결국 IsLocalController 함수의 결과를 반환함을 알 수 있습니다.

다음은 액터 헤더에 있는 HasLocalNetOwner함수의 주석 설명입니다.

/**

* @return true if this actor can call RPCs or false if no such owner chain exists

*/
말씀주신 ROLE_Authority / remote role: ROLE_AutonomousProxy 의 상태는 HasLocalNetOwner 함수가 false로 리턴이 되므로 HasLocalNetOwner도 false로 리턴되겠지요.

우현우님의 프로필 이미지
우현우
질문자

계속 질문드려서 죄송합니다.
ROLE_Authority / remote role: ROLE_AutonomousProxy는 HasLocalNetOwner가 false가 나오지만 클라이언트 RPC 호출이 가능하지 않나요? 주석에서 말하는 RPC에 포함되지 않는건가요?

이득우님의 프로필 이미지
이득우
지식공유자

RPC의 정의는 로컬 컴퓨터에서 호출하되, 실행은 원격 컴퓨터에서 되는 함수를 의미합니다.
ROLE_Authority / ROLE_AutonomousProxy 의 경우는 서버에서 서버 소유의 액터에게 RPC를 호출한 것으로 볼 수 있는데, 이는 원격이 아니기에 RPC의 범주로 볼 순 없겠지요.
그런데 RPC가 아님에도 RPC 명령은 무시되지 않아 _Implementation 함수가 호출되는데, 이는 RPC가 아닌 로컬 함수 콜로 즉각 호출됩니다.

우현우님의 프로필 이미지
우현우
질문자

client 0이 서버에 접속해서 서버 월드에 스폰된 client 0 character는 서버에서 ROLE_Authority / ROLE_AutonomousProxy이고 서버에서 해당 캐릭터에 IsLocalController를 호출하면 false가 나옵니다. 근데 서버에서 해당 캐릭터에 Client RPC를 호출하면 클라이언트 프로세스에서 해당 캐릭터의 Implement가 호출이 되는데 이건 RPC가 맞지 않나요?

이득우님의 프로필 이미지
이득우
지식공유자

아 질문의 요지를 잘못 이해했었네요.
오랜만에 내용을 봐서 그런지 혼동되서 리슨 서버쪽에서의 플레이어에 대해서만 생각했었네요.

말씀주신 부분이 맞습니다. 플레이어 컨트롤러가 최상단 액터면 (커넥션)오너십이 있다고 표현하고 RPC 통신의 조건을 만족합니다.
그리고 RPC조건을 체크하는 함수는 HasLocalNetOwner와 HasNetOwner 두 개가 있는데, HasLocalNetOwner만 설명했네요.
HasNetOwner 함수는 TopMost 액터가 플레이어 컨트롤러인 경우 true를 반환하며 RPC 통신 여부는 이 함수를 사용해 결정합니다.

정리하면 IsLocallyControlled 함수는 현재 조종 중인 컴퓨터를 판별하는 용도로 사용하는 것이 맞습니다.
잘못된 답변으로 혼동을 드려서 미안합니다.

우현우님의 프로필 이미지
우현우
질문자

HasNetOwner라는 함수가 있었군요. 이해가 되었습니다. 감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다.
님이 질문하신 내용은 특정 강의 내용에 대한 세부적인 부분이라 직접적으로 답변드릴 수 있는 내용이 아니며, 프로그래밍 관련 요청된 정보와도 매칭되지 않습니다.

언리얼 엔진의 네트워크 멀티플레이 프레임워크에 대한 이해와 IsLocalControlled, ROLE_Authority, ROLE_AutonomousProxy, ROLE_SimulatedProxy 등의 개념은 언리얼 엔진의 공식 문서나 해당 강의의 Q&A 섹션, 언리얼 엔진 관련 커뮤니티나 포럼에서 좀 더 자세한 해석이나 설명을 찾으실 수 있을 것입니다.

오너쉽과 소유에 대한 단어의 개념 혼동을 해결하기 위해서는 언리얼 엔진에서의 엑터와 네트워크 객체의 관계, 그리고 이들 사이의 상호작용 방식에 대해 좀 더 심도 있게 공부하시는 것을 추천드립니다. 또한, 공식 문서에서는 네트워킹 아키텍처 및 관련 함수들에 대해 상세하게 설명하고 있으므로, 참고하시면 도움이 될 것입니다.

더 궁금한 사항이 있으시다면 해당 강의의 질문 게시판이나 언리얼 엔진 관련 커뮤니티를 활용해 보세요.

우현우님의 프로필 이미지
우현우

작성한 질문수

질문하기