일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- stride
- 언리얼엔진
- DP
- DSP
- linear difference equation
- Security
- TSet
- MLFQ
- MAC
- Race condition
- dirty cow
- 배경 그림
- 게임 개발
- dtft
- Rr
- CTF
- Double free
- frequency-domain spectrum analysis
- STCF
- 게임개발
- 운영체제
- 메카님
- AINCAA
- 유니티
- Unity #Indie Game
- ret2libc
- 언리얼 엔진
- pdlc
- sampling theory
- 유스케이스
- Today
- Total
다양한 기록
[UE Network] Movement Replication 본문
캐릭터 움직임의 리플리케이션 플로우
1. 클라이언트의 로컬 움직임 기록
- 현재 틱에서 입력 가속과 캐릭터의 움직임 기록
- PerformMovement 실행 -> CharacterMovement에서 설정한 속성에 맞게 캐릭터가 이동됨
- 특정 클래스에 움직임 저장
- 서버 RPC를 호출해서 서버로 클라이언트의 움직임 정보를 보냄
2. 서버의 움직임 평가
- MoveAutonomous 함수 실행해서 캐릭터를 자율적으로 이동시킴
- 서버 캐릭터와 클라이언트 캐릭터의 위치에 따라 ClientAdhustPosition RPC 호출해서 조정 가능
3. 캐릭터의 위치 조정
캐릭터 무브먼트 컴포넌트는 여러가지 이동 시스템 제공
+ 네트워크 게임 플레이 통합 기능도 제공
모두 기본적으로 리플리케이티드 되도록 빌드됨
TickComponent() 함수를 호출하는 동안에는
PerformMovement() 함수를 호출
입력을 하면 입력을 원하는 가속도로 변환해서 이동 계산을 진행함
이게 매 틱마다 진행됨
* ACharacter는 폰에 이동기능 + 여러 네트워크 기능
Movement Replication Summary
세가지 역할
Network Role | Description |
Autonomous Proxy | 클라이언트에 있고, 클라이언트의 입력을 처리해주는 프록시 |
Authority | 서버에 있는, 권한을 가지는 액터 |
Simulated Proxy | 서버의 움직임을 단순히 복제해주는 프록시 |
틱마가 서로 RPC 호출해서 움직임 정보를 동기화
Autonomous Proxy (Owning Player's Client)
1. PerformMovement()를 호출해서 실제로 이동을 구현
2. 이동 정보를 SavedMoves 큐에 넣어줌
3. 최적화를 위해 유사한 움직임 항목들은 결합하고 ServerMove RPC를 호출해서 필요한 정보를 서버로 전송
Authoritative Actor (Server)
4. ServerMove 수신하고 PerformMove{* MoveAutonomous}를 써서 클라이언트의 움직임을 재현
5. 자율적으로 서버의 캐릭터를 이동, 클라이언트가 보고한 위치와 일치하는지 확인
6. 일치시 이동이 유효하다는 신호 전송, 그렇지 않으면 ClientAdjustPosition RPC 날림
7. ReplicatedMovement 구조 복제해서 Simulated Proxy에 움직임 정보를 전송
Autonomous Proxy (Owning Player's Client)
8. ClientAdjustPosition 받고 서버의 이동을 다시 체크하고 자신이 가진 SavedMoves 큐에서
서버가 처리한 움직임 정보를 찾고 단계를 다시 추적해서 새로운 최종 위치를 얻음
이후 반복
Simulated Proxy는 보여주기만 하면 되어 시각 처리만 하면 됨
Autonomous Proxy 클라이언트의 진행
[ReplacateMoveToServer 함수]
- 클라이언트 캐릭터의 움직임을 보관하는 네트워크용 클라이언트 데이터 생성
- 클라이언트의 데이터에 저장된 움직임 중에 참도할 중요할 움직임 기록 (OldMove)
- 현재 틱의 움직임을 기록하는 신규 움직임 생성 (NewMove)
- 입력을 처리하기 전의 각종 초기화 상태를 저장 (ex. StartLocation)
- 필요 시 최종 움직임과 현재 움직임을 병합 시도 (최적화를 위해)
- 클라이언트 로컬에서의 움직임 진행 (PerformMovement)
- 신규 움직임에 움직임 결과 상태를 저장 (ex. SavedLocation)
- ServerMove 함수를 호출해 OldMove와 NewMove를 서버에 전송
TickComonent() -> ControlledCharacterMove() -> ReplacateMoveToServer ()
TickComponent에서 무브먼트 컴포넌트를 가지고 있는 캐릭터가 접속에 대한 소유권을 가지고 있는
AutonomousProxy일 때 ControlledCharacterMove을 호출함
ControlledCharacterMove에서는 캐릭터가 서버에 있다면 RPC할 거 없이 바로 PerformMovement 호출
클라는 ReplacateMoveToServer 호출해줘야 함
[ServerMove 함수]
클라이언트의 최종 움직임 정보를 서버에 보내는 함수
- 타임 스탬프 : 움직임에 대한 정보
- 가속 정보 : 입력으로 발생된 최종 가속 정보를 작은 사이즈로 인코딩
- 위치 정보 : 캐릭터의 최종 위치 정보, 캐릭터가 베이스 위에 있는 경우는 상대 위치를 사용
- 플래그 : 특수한 움직임(점프, 웅크리기)에 대한 정보
- 회전 정보 : 압축된 회전 정보(Yaw 회전 중심으로 저장)
- 본 정보 : 스켈레탈 메시 컴포넌트인 경우 기준이 되는 본 정보
- 무브먼트 모드 정보 : 캐릭터 컴포넌트의 무브먼트 모드 정보
서버 무브 안에 ServerMoveOld 있는데
원래 저기에 UFUNCTION(unreliable, server, withValidation) 있었는데,
ServerMove()에 Deprecated 주석 생겨있고 ufunction도 없음
현재는 다른 함수를 쓰는 듯함
서버의 처리
[ServerMove_Implmentation 함수]
- 서버 캐릭터의 움직임을 보관하는 네트워크용 서버 데이터 생성
- 클라이언트로부터 받은 타임스탬프 값을 검증
* 오랫동안 패킷이 오지 않았었는데 예측해서 움직이는 건 위험함
- 압축된 가속, 회전 데이터를 디코딩하고 클라이언트와 서버의 타임 스탬프 정보를 기록
- MoveAutonomous 함수를 호출해 서버 캐릭터를 이동시킴
- 클라이언트와의 차이를 비교하고 에러를 수정
* 상당한 시간차가 감지되면 수정 정보를 기록 (PendingAdjustment)
[ClientAdjustPosition 함수]
클라이언트에게 수정할 위치 정보를 알려주는 함수
중복 없이 서버 틱의 마지막에서 수정이 필요할 때만 전송
- 타임 스탬프
- 델타 타임
- 무브먼트 모드 정보
- 새로운 속도
- 새로운 위치
- 새로운 회전
- 새로운 베이스와 베이스 본 이름
[ClientAdjustPosition_Implmentation]
- 타임 스탬프 값을 통해 서버로부터 확인받은 움직임 정보를 기록 (LastAckedMove)
- 서버에서 전달받은 위치로 루트 컴포넌트(캐릭터)의 위치를 변경
- 서버에서 전달받은 속도로 무브먼트 컴포넌트의 속도를 수정
- 베이스 정보와 위치를 수정
- 서버에 의해 클라이언트 위치가 업데이트 되었다고 기록 (bUpdatePosition)
* 서버의 수정 정보를 바탕으로 MoveAutonomous 함수를 호출해 클라이언트에서 남은 움직임을 재생
* ClientData가 있고 bUpdatePosition이 true이면 MoveAutonomous가 캐릭터 움직임 컨트롤 전에 호출됨
움직임 리플리케이션 디버싱
DefaultEngine.ini 파일에서 LogNetPlayerMovement=VeryVerbose로 설정
콘솔 변수, p.NetShowCorrections 1 지정 시 드로우 디버깅 후출
서버에서의 오차 발생 시 드로우 디버그
- 전달받은 클라이언트 위치를 붉은색으로 표시
- 서버에서의 움직인 위치를 녹색으로 위치
오차를 전달받은 클라이언트에서의 드로우 디버그
- 클라이언트가 지정했던 위치를 붉은색으로 표시
- 서버가 수정해준 위치를 녹색으로 표시
- 수정은 발생했지만 서버와 클라이언트 위치가 거의 동일한 경우 노란색
MovementMode 잠구기 전에 RPC를 받는 경우가 있음
추가적인 변수를 넣어서 입력을 막을 필요가 있음