Unreal Engine에서 피치 복제 및 축 압축
죄송합니다, 번역할 텍스트를 제공해 주시겠어요? 현재는 소스 링크만 포함되어 있어 번역할 내용이 없습니다. 텍스트를 알려주시면 바로 한국어로 번역해 드리겠습니다.
Pawn 클래스
APawn 클래스에서 사용할 수 있는 함수 GetBaseAimRotation() 은 복제된 피치를 반환하며 Blueprint와 C++ 모두에서 사용할 수 있습니다.
Blueprint 단계
- Get Base Aim Rotation을 호출하고 그 전방 벡터를 얻습니다.
- 해당 방향을 월드 공간에서 Pawn의 로컬 공간으로 역변환합니다 (Pawn의 월드 변환을 사용).
- 결과 벡터를 분해하고 Pitch 컴포넌트를 읽습니다.

C++ 구현
Kismet Math Library를 사용하거나 네이티브 vector/rotator 함수를 사용할 수 있습니다—두 접근 방식 모두 동일한 결과를 제공합니다.
Kismet 라이브러리를 사용할 경우 적절한 헤더를 포함하는 것을 기억하세요 (#include "Kismet/KismetMathLibrary.h").
헤더
// MyCharacter.h
class AMyCharacter : public ACharacter
{
// ...
/** Returns the replicated pitch value. */
float GetReplicatedPitch() const;
};
Kismet Math Library 사용
// MyCharacter.cpp
float AMyCharacter::GetReplicatedPitch() const
{
// World‑space aim direction from the replicated rotation
const FVector AimDirectionWorld = UKismetMathLibrary::GetForwardVector(GetBaseAimRotation());
// Convert to pawn‑local space
const FVector AimDirectionLocal = UKismetMathLibrary::InverseTransformDirection(
GetActorTransform(),
AimDirectionWorld
);
// Build a rotator from the local X axis and read Pitch
const FRotator AimRotationLocal = UKismetMathLibrary::MakeRotFromX(AimDirectionLocal);
return AimRotationLocal.Pitch;
}
네이티브 함수 사용
float AMyCharacter::GetReplicatedPitch() const
{
// World‑space aim direction from the replicated rotation
const FVector AimDirectionWorld = GetBaseAimRotation().Vector();
// Convert to pawn‑local space (no scaling)
const FVector AimDirectionLocal = ActorToWorld().InverseTransformVectorNoScale(AimDirectionWorld);
// Build a rotator from the local vector and read Pitch
const FRotator AimRotationLocal = AimDirectionLocal.Rotation();
return AimRotationLocal.Pitch;
}
두 버전 모두 소유 클라이언트에서 복제된 동일한 피치 값을 반환합니다.
내부 동작
GetBaseAimRotation()은 폰에 유효한 컨트롤러가 있는지(즉, 로컬에서 제어되는지) 여부에 따라 다르게 동작합니다. 컨트롤러가 없을 경우(시뮬레이션 프록시)에는 다른 로직을 사용합니다.
컨트롤러가 존재할 때
FVector POVLoc;
FRotator POVRot;
if (Controller != nullptr && !InFreeCam())
{
Controller->GetPlayerViewPoint(POVLoc, POVRot);
return POVRot; // 플레이어의 실제 뷰 회전값을 사용
}
이 함수는 단순히 컨트롤러의 현재 뷰 회전값을 반환합니다.
컨트롤러가 없을 때(시뮬레이션 프록시)
// 폰 자체의 회전을 대체값으로 사용
POVRot = GetActorRotation();
// 피치가 0이면 복제된 RemoteViewPitch를 사용
if (FMath::IsNearlyZero(POVRot.Pitch))
{
const UWorld* World = GetWorld();
const UDemoNetDriver* DemoNetDriver = World ? World->GetDemoNetDriver() : nullptr;
// 리플레이/녹화 경로 – 일반 게임플레이에서는 무시
if (DemoNetDriver && DemoNetDriver->IsPlaying() &&
DemoNetDriver->GetPlaybackEngineNetworkProtocolVersion() GetControlRotation().Pitch);
}
}
SetRemoteViewPitch는 부동소수점 피치를FRotator::CompressAxisToByte를 사용해 바이트(uint8)로 변환합니다.- 클라이언트 측에서는
GetBaseAimRotation()이 그 바이트를FRotator::DecompressAxisFromByte를 통해 다시 전체float피치로 복원합니다.
요약
- **
GetBaseAimRotation()**을 사용하여 복제된 뷰 회전을 얻습니다. - 전방 벡터를 로컬 공간으로 변환하고 피치를 추출합니다 (Kismet Math Library 또는 네이티브 함수 중 하나 사용).
- 내부적으로 언리얼은 서버에서 피치를 단일 바이트(
RemoteViewPitch)로 압축하고 원격 클라이언트에서 압축을 해제하여 복제를 저비용·효율적으로 처리합니다.
같은 패턴을 적용해 자체 복제·압축 변수를 추가하고 PreReplication에서 처리하면 다른 축이나 사용자 정의 값을 복제할 수 있습니다.
UE4에서 Pawn 피치 복제하기
아래는 pawn 클래스 내부에서 피치 복제를 처리하는 관련 코드입니다.
1. 원격 뷰 피치 가져오기
void APawn::GetRemoteViewPitch()
{
// Example of retrieving the remote view pitch
float Pitch = RemoteViewPitch; // RemoteViewPitch is a byte
float DecompressedPitch = FRotator::DecompressAxisFromByte(Pitch);
// Use DecompressedPitch as needed…
}
2. 원격 뷰 피치 설정하기
void APawn::SetRemoteViewPitch(float NewRemoteViewPitch)
{
// Compress pitch to 1 byte
RemoteViewPitch = FRotator::CompressAxisToByte(NewRemoteViewPitch);
}
참고:
SetRemoteViewPitch는 네트워크 전송을 위해float축 값을 1바이트로 압축합니다.
사용 방법
- Pawn 클래스 검사 – pawn의 소스 파일을 열고 위 두 함수를 찾습니다.
- 흐름 이해 –
SetRemoteViewPitch는 서버(또는 소유 클라이언트)에서 피치를 압축하여 복제하기 전에 호출됩니다.GetRemoteViewPitch(또는 구현한 해당 getter)는 원격 머신에서 바이트를 다시 사용 가능한float로 복원합니다.
- 내장 복제 활용 – 대부분의 경우 UE4의 기본 피치 복제를 사용하면 됩니다.
- 축 압축 커스터마이징 – 다른 축을 압축해야 한다면 같은 패턴을 따르세요: 복제 전 함수에서 압축하고, 복제된 값을 읽을 때 복원합니다.
마무리 생각
처음엔 세부 사항이 다소 복잡하게 느껴질 수 있지만, pawn 클래스의 이 함수들을 다시 살펴보면 이해가 확고해집니다. 대부분의 경우 엔진의 기본 피치 복제로 충분하지만, 축을 수동으로 압축하는 방법을 알면 커스텀 네트워킹 요구에 유연하게 대응할 수 있습니다.
행운을 빕니다!