[이득우의 언리얼 프로그래밍 Part3 필기] 10. 캐릭터 공격 구현 개선
패킷 렉이 생길 때
입력이 서버로 전달되는 과정에서 시간이 오래 소요
서버에서 클라이언트로 전달되는 과정에서 또 소요
애니메이션이 재생되지 않고 대기하는 시간이 길어짐
당연하게도 서버와 클라이언트의 시간은 차이가 나게 된다. 따라서
GetWorld()->GetTimeSeconds() 대신
GetWorld->GetGameState()->GetServerWorldTimeSeconds() 를 사용해야 서버의 시간을 이용해 판정을 할 수 있다.
최적화
FVector_NetQuantize
데이터를 전달할 때 벡터 구조체를 전달하는데, 벡터의 경우에는 float 세개로 구성되어있기 떄문에 12바이트(32, 32, 32)를 차지한다. 따라서 높은 정밀도가 필요하지 않은 경우에는 작은 사이즈로 압축해서 보낸다.
이를 위해서 언리얼 엔진은 FVector_NetQuantize 라는 구조체를 제공한다. 기본적으로 x y z 각 20비트씩 차지한다.
정밀도를 위해 소수점 첫째 자리까지 반올림 한 NetQuantize10, 둘째 자리까지 한 NetQuantize100 이 있다.
https://forums.unrealengine.com/t/what-is-fvector-netquantize/480072
What is FVector_NetQuantize?
Unreal docs says Try to take advantage of the quantization functionality that already exists. e.g. FVector_NetQuantize. These will greatly reduce the size needed to replicate this state over to clients First Question: I don’t understand what exactly is F
forums.unrealengine.com
최적화
- ServerRPC의 일부
//MulticastRPCAttack();
for (APlayerController* PlayerController : TActorRange<APlayerController>(GetWorld()))
{
if (PlayerController && GetController() != PlayerController)
{
if(!PlayerController->IsLocalController())
{
AABCharacterPlayer* OtherPlayer = Cast<AABCharacterPlayer>(PlayerController->GetPawn());
if (OtherPlayer)
{
OtherPlayer->ClientRPCPlayAnimation(this);
}
}
}
}
원래대로라면 NetMultiCast를 통해 모든 클라이언트들과 서버에게 서버 RPC 가 호출될 때 애니메이션을 재생할 것을 요청한다. 그러나 클라이언트가 가시되는 범위 밖에 있거나, 필요한 클라이언트들에게만 명령을 보낼 경우(서버에게 전달할 필요도 없는 경우) 클라이언트 RPC로 구현해 불필요한 명령을 줄일 수 있다.
코드를 보면 월드에서 모든 플레이어 컨트롤러를 가져온 뒤, null체크 후 시뮬레이티드 프록시이고, 로컬 컨트롤러가 아니면
캐스팅을 통해 해당 플레이어에게 RPC를 호출하고 있다.