2026-06-05(금) std::max_elemnet, Server RPC / Client RPC / NetMulticast RPC, TActorIterator

조범근·2026년 6월 5일

TIL

목록 보기
69/81

C++ Week 14

Study

개인 연습 프로젝트, 알고리즘 2문제



Today I Learned


Unreal Multiplay

1. std::max_element

int max_val = *std::max_element(count.begin(), count.end());

std::max_elemnet는 컨테이너 안에서 가장 큰 값을 가진 위치(iterator) 를 찾아주는 함수이다. 여기서 max_elemnet값 자체를 반환하는 게 아니라 iterator를 반환한다는 것이다.

count.begin()부터 count.end() 전까지 탐색해서 가장 큰 값을 가진 위치를 찾고, 그 위치에 있는 값을 꺼내서 max_val에 저장한다.




2. Server RPC / Client RPC / NetMulticast RPC

RPC는 Remote Procedure Call의 약자.
언리얼 멀티플레이에서는 다른 네트워크 위치에 있는 함수가 실행되도록 요청하는 기능이다.

Server RPC

UFUNCTION(Server, Reliable)
void ServerRPCFunction();

클라이언트 -> 서버로 보내는 RPC

예를 들어 플레이어가 채팅을 입력하거나 공격 버튼을 눌렀을 때, 클라이언트가 서버에게 요청한다.

중요한 점은 최종 판단은 보통 서버가 해야 한다는 것입니다.
클라이언트가 마음대로 체력 감소, 점수 증가, 공격 성공을 결정하면 치트에 취약해집니다.



Client RPC

UFUNCTION(Client, Reliable)
void ClientRPCFunction();

서버 -> 특정 클라이언트로 보내는 RPC

보통 PlayerController처럼 특정 플레이어가 소유한 Actor패밀리에서 사용한다.

채팅 구현에서는 서버가 모든 PlayerController를 순회하면서 각 플레이어에게 Client RPC를 호출할 수 있다.

for (TActorIterator<ACXPlayerController> It(GetWorld()); It; ++It)
{
    ACXPlayerController* PC = *It;
    PC->ClientRPCPrintChatMessageString(Message);
}

이렇게 하면 각 PlayerController의 소유 클라이언트에게 메시지가 전달된다.



NetMulticast RPC

UFUNCTION(NetMulticast, Reliable)
void MulticastRPCFunction();

서버에서 호출하면, 해당 Actor를 알고 있는 여러 클라이언트에서 실행되는 RPC이다.

NetMulticats는 무조건 모든 플레이어에게 실행되는 방송이 아니다.

그 RPC가 선언된 ACtor가 각 클라이언트에도 존재해야 한다.

예를들어 PlayerController에서 NetMulticast를 쓰면 문제가 생길 수 있다.

Server    : Player1 PC, Player2 PC 둘 다 있음
Client 1  : Player1 PC만 있음
Client 2  : Player2 PC만 있음

Player1Playercontroller에서 netMulticast를 호출해도, Client 2(Player2)에는 Player1 PlayerController가 없기 떄문에 실행될 Actor 자체가 없다.

그래서 채팅 전체 전송에는 PlayerControllerNetMulticast가 적합하지 않다.

반대로 GameState처럼 모든 클라이언트에 존재하는 Actor라면 NetMulticast를 사용하기 좋다. GameMode는 서버에만 존재하기때문에 사용 불가능.



RPC별 차이

종류방향실행 위치주 사용 목적
Server RPCClient → Server서버입력, 공격, 채팅 요청 등 서버에 판단 요청
Client RPCServer → 특정 Client특정 클라이언트개인 UI, 개인 알림, 특정 플레이어에게만 전달
NetMulticast RPCServer → 관련 Client들서버와 관련 클라이언트들전체 공지, 이펙트, 사운드, 상태 알림

내 클라이언트에서 채팅 입력
Server RPC로 서버에 메시지 전달
서버가 모든 PlayerController를 순회
각 PlayerController에게 Client RPC 호출
각 클라이언트 화면에 채팅 출력

Server RPC = 서버야, 이 함수 실행해줘.
Client RPC = 특정 클라이언트야, 이 함수 실행해.
NetMulticast RPC = 이 Actor를 알고 있는 클라이언트들아, 이 함수 실행해.

PlayerController는 모든 클라이언트가 공유해서 보는 Actor가 아니라, 서버와 해당 플레이어 클라이언트를 잇는 개인 통로에 가깝다. 그래서 전체 채팅에는 PlayerControllerNetMulticast보다, 서버에서 각 PlayerController에게 Client RPC를 보내는 방식이 더 적합하다.




3. TActorIterator

for (TActorIterator<ACXPlayerController> It(GetWorld()); It; ++It)  
{  
ACXPlayerController* CXPlayerController = *It;  
}

C++에서 보던 반복문의 형태와 다르게 생겼다.

초기식은 어떤걸 가리키고있으며, 조건식은 It이 적혀있기만하고, 증감식은 가리키고있는 index가 없는데 ++을 하고있다. C++의 for문이랑 뭐가 다른걸까

3-1. TActorIterator It(GetWorld())

TActorIterator<ACXPlayerController> It(GetWorld());
// 풀어쓰면 아래 뜻과 같다.
TActorIterator<ACXPlayerController> It = 
TActorIterator<ACXPlayerController>(GetWorld());

현재 월드에 있는 ACXPlayerController타입 Actor만 찾아서 순회하겠다. 라는 뜻이다.

여기에서 It(GetWorld())It은 변수 이며, 괄호 안의GetWorld()는 Iterator가 탐색할 월드는 GetWorld()로 지정한다는 뜻이다.

즉, 현재 이 함수가 실행 중인 월드에서 ACXPlayerController들을 찾아라 라는 말이 된다.

3-2. 조건식 It

for (...; It; ...)
// 왜 아래처럼 쓰지 않는걸까?
for (int32 i = 0; i < Count; ++i)

두개의 개념이 다른게 TActorIterator는 내부적으로 bool처럼 검사될 수 있게 만들어져 있다.

It" 현재 가리키는 Actor가 아직 유효한가? ", " 아직 순회할 Actor가 남아 있는가? " 를 체크한다. 그래서 다음과 같이 동작한다.

It이 유효함 -> 반복문 실행

It이 더 이상 유효하지 않음 -> 반복문 종료

while(It)과 같은 역할.

3-3. ++It

++It;

C++의 연산자 오버로딩이다. ++It는 일반 숫자의 ++가 아니다.
Iterator가 다음 Actor를 가리키도록 내부 위치를 이동한다. index가 코드에 안 보일 뿐이지, TActorIterator내부에는 현재 어디까지 순회했는지에 대한 상태가 있다.

std::vector<int32> Numbers;

for (auto It = Numbers.begin(); It != Numbers.end(); ++It)
{
    int32 Value = *It;
}

여기서도 ++It은 숫자를 1 증가시키는 게 아니라 다음 원소로 이동 한다.

0개의 댓글