< [이득우의 언리얼 프로그래밍 Part3 필기] 10. 캐릭터 공격 구현 개선

언리얼엔진5/[Part3] 이득우의 언리얼 프로그래밍

[이득우의 언리얼 프로그래밍 Part3 필기] 10. 캐릭터 공격 구현 개선

Rocketbabydolls 2024. 5. 10. 22:53

 

 

패킷 렉이 생길 때

 

입력이 서버로 전달되는 과정에서 시간이 오래 소요

서버에서 클라이언트로 전달되는 과정에서 또 소요

애니메이션이 재생되지 않고 대기하는 시간이 길어짐

 

 

 

 

 

 

당연하게도 서버와 클라이언트의 시간은 차이가 나게 된다. 따라서

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를 호출하고 있다.