[이득우의 언리얼 프로그래밍 Part3 필기] 12. 물리 움직임 리플리케이션
캐릭터 리플리케이션 -> RPC 사용
액터 리플리케이션은 프로퍼티 리플리케이션을 사용한다.
[언리얼엔진 5 공식문서] Networked Movement in the Character Movement Component
캐릭터 무브먼트 컴포넌트는 걷기, 낙하, 수영, 비행 등 휴머노이드 캐릭터의 일반적인 이동 모드가 포함된 캡슐화된 이동 시스템을 제공하는 액터 컴포넌트입니다. 캐릭터 무브
plug-in-baby.tistory.com
움직임 리플리케이션을 위한 서버의 준비
[ReplicatedMovement]
- 서버에서 SimulatedProxy로 보내는 움직임 정보를 기록한 멤버 변수
- OnRep_ReplicatedMovement 로 이벤트 함수 호출함
- 일반 움직임 물리 움직임의 리플리케이션을 모두 처리하는 용도로 활용됌
- FRepMovement 구조체의 주요 멤버 변수
위치와 회전 : 컴포넌트의 현재 위치와 회전
데이터 정밀도 설정 : 위치, 회전, 속도의 데이터 정밀도, 끊김 현상이 보이지 않을 만큼 최소로 결정
물리 시뮬레이션 여부 플래그 : 물리 시뮬레이션으로 복제할지를 지정
이동 속도 : 컴포넌트의 이동 속도
각 속도 : 컴포넌트의 각 속도. 물리 시뮬레이션 진행시에만 사용
서버 프레임 : 서버에서의 물리 프레임
물리 움직임의 기록
[FRigidBodyState]
액터의 물리 상태를 기록하는 구조체
다음과 같은 멤버 변수로 구성되어 있음.
- 위치 : 소수점 두 자리 정밀도로 기록됨.
- 회전 : 사원수 정보로 기록됨.
- 속도 : 소수점 두 자리 정밀도로 기록됨.
- 각속도 : 소수점 두 자리 정밀도로 기록됨.
- 플래그 : 휴면 상태와 같은 특정 물리 상태를 기록하는데 사용
액터 리플리케이션의 준비
[GatherCurrentMovement]
- 현재 액터의 움직임을 ReplicatedMovement 속성으로 변환해 설정하는 함수
- 액터의 PreReplication 함수에서 호출됨.
- 액터의 물리 움직임과 일반 움직임을 구분해 각각 처리함.
- 일반 움직임은 단순히 액터의 현재 위치, 회전, 속도 값을 ReplicatedMovement 에 저장함.
- 물리 시뮬레이션의 경우 현재 월드에 설정된 물리 씬에서 해당 컴포넌트의 물리 상태를 저장함.
현재 컴포넌트의 물리 상태 정보를 ReplicatedMovement 로 옮김 (FRigidBodyState::FillFrom) - 이를 통해 최종 ReplicatedMovement가 설정되어 클라이언트에 보내짐
액터의 움직임 리플리케이션 옵션을 활성화해주어야 올바로 동작함
액터 움직임 정보의 수신
[OnRep_ReplicatedMovement]
ReplicatedMovement 의 물리 시뮬레이션 속성(bRepPhysics) 여부에 따라 두 가지로 실행됌
일반적인 움직임에 대한 처리
- Simulated Proxy 에 대해서만 처리함
- 컴포넌트의 위치와 회전 정보를 갱신함
- 속도 처리는 별도로 진행하지 않음
물리 움직임에 대한 처리
- ReplicatedMovement의 정보를 현재 컴포넌트의 물리 상태로 옮김. (FRigidBodyState::CopyTo)
- 물리 리플리케이션 씬에서 컴포넌트와 일치하는 타겟을 찾아서 업데이트 (FReplicatedPhysicsTarget)
물리 움직임의 동기화
[ApplyRigidBodyState]
물리 리플리케이션의 틱에서 호출되는 함수
클라이언트의 물리 상태가 서버의 물리 상태의 오차 내에 있을 때까지 계속 호출됨
다음과 같은 로직으로 진행됨
- 서버에서 받은 최종 속도와 핑을 기반으로 클라이언트의 물리 상태를 외삽(Extrapolation) 으로 예측
- 예측한 위치와 방향이 서버와 비교해 올바른지 체크하고 문제가 있다고 판단되면 에러 시간을 누적함
- 누적된 에러 시간 설정값을 넘으면 강제 조정(하드스냅) 을 진행함
- 차이가 크지 않다면 내삽(Interpolation) 을 수행해 위치, 회전, 속도, 각속도를 조정함.
네트워크 스무딩
단순히 캐릭터의 위치와 회전을 복제하여 움직임을 복제하면 캐릭터가 몇 초마다 순간 이동하는 것처럼 보일 것입니다. 이는 로컬 머신의 렌더링 속도가 네트워크를 통해 데이터를 전송하는 속도보다 빠르기 때문입니다. 예를 들어 클라이언트가 240Hz 재생률로 모니터에 렌더링하고 있지만 복제된 움직임은 30Hz로만 전송될 수 있습니다.
네트워크 스무딩은 이 동작을 부드럽게 처리하는 프로세스로, 캐릭터를 대상에 즉시 스냅하는 대신 소스 위치에서 대상 위치로 점진적으로 보간합니다. 소스 위치는 캐릭터의 현재 위치로, 타깃 위치는 클라이언트 예측 데이터로 지정됩니다. 보간 자체는 네트워크 스무딩 모드를 사용하여 어떤 종류의 보간을 사용할지 결정하는 SmoothClientPosition에서 처리됩니다.