(새 프로젝트에는 5.1에서 도입된 새로운 네트워킹 시스템을 사용해야 합니다. 다음 내용은 이전 네트워킹 시스템을 사용하는 레거시 프로젝트를 대상으로 작성되었습니다.)
특정 네트워크 뷰에서 상태 동기화의 활성화는 State Synchronization 드롭다운 메뉴에서 Reliable Delta Compressed 또는 Unreliable 을 선택하면 됩니다. 그리고 Observed 프로퍼티를 활용해 어떤 유형의 데이터를 동기화할 지 선택해야 합니다.
Unity는 Transform, Animation, Rigidbody, MonoBehaviour 컴포넌트를 동기화할 수 있습니다.
트랜스폼은 포지션, 회전, 크기를 저장해 직렬화 됩니다. 부모자식 정보는 네트워크로 전달되지 않습니다.
Animation은 실행하는 애니메이션 상태, 즉 시간, 무게, 속도, 활성화된 프로퍼티를 각각 직렬화합니다.
Rigidbody는 포지션, 회전, 속도, 각속도를 직렬화합니다.
스크립트(MonoBehaviour)는 OnSerializeNetworkView() 함수를 호출합니다.
현재 네트워크 뷰는 신뢰할 수 있는 델타 압축과 신뢰할 수 없음이라는 두 가지 신뢰성 수준을 지원합니다.
둘 다 장단점이 있으며 무엇을 사용할지는 게임의 구체적인 내용에 따라 결정됩니다.
대역폭 최소화에 대한 추가 정보는 대역폭 최소화 페이지를 참조하십시오.
Reliable Delta Compressed 모드는 클라이언트에게 마지막으로 받은 데이터와 현재 상태를 자동으로 비교합니다. 마지막 업데이트 이후 데이터가 변경되지 않았다면 데이터가 전송되지 않습니다. 그러나 데이터는 프로퍼티 별로 비교됩니다. 예를 들어, 트랜스폼의 포지션이 변경됐으나 회전은 변경되지 않은 경우 포지션만 네트워크에 전송됩니다. 변경된 데이터만 전송함으로써 대역폭이 절약됩니다.
Unity는 수신이 결정될 때까지 재전송해서 모든 UDP 패킷이 안정적으로 도착하게 합니다. 패킷이 드롭되면 이후에 전송되는 모든 패킷은 드롭된 패킷이 다시 전송되고 수신될 때까지 적용되지 않습니다. 그 때까지는 드롭이 발생한 이후의 모든 패킷은 버퍼에서 대기합니다.
Unreliable 모드에서 Unity가 패킷의 수신 여부를 확인하지 않고 전송합니다. 즉 어떤 정보가 수신됐는지 모르기 때문에 변경된 데이터만을 보내는 것은 안전하지 않습니다. 업데이트 때마다 전체 상태를 보냅니다.
네트워크 레이어는 신뢰할 수 없고 정렬되지 않은 UDP 프로토콜을 사용하지만 TCP처럼 정렬된 있는 패킷을 신뢰할 수 있게 보내는 데 활용될 수 있습니다. 내부적으로 Unity는 ACK과 NACK으로 패킷 전송을 제어해 어떤 패킷도 드롭되지 않게 합니다. 신뢰할 수 있고 정렬된 패킷을 활용할 때의 단점은 패킷이 드롭되거나 지연되는 경우 해당 패킷이 안전하게 도착할 때까지 모두가 정지해버립니다. 이는 네트워크 지연이 심한 곳에서 전송 지연을 일으킬 수 있습니다.
신뢰할 수 없는 전송은 데이터가 프레임마다 변경될 것을 알 때 유용합니다. 레이싱 게임을 예로 들면 플레이어의 차량이 항상 움직일 것을 예상할 수 있기 때문에 놓친 패킷의 효과는 다음 패킷으로 정정됩니다.
일반적으로는 패킷을 놓치는 것보다 빠르고 빈번한 업데이트가 더 중요한 경우 신뢰할 수 없는 전송을 활용해야 합니다. 반대로 데이터가 자주 변경되지 않는 경우 대역폭을 절약하기 위해 신뢰할 수 있는 델타 압축을 사용합니다.
서버가 게임 세계 상태에 완전한 권한을 가진 경우 클라이언트는 서버에서 수신하는 업데이트에 기초해 게임 상태를 변경하면 됩니다. 이 때의 문제는 서버의 응답을 기다리면서 발생하는 지연이 게임플레이에 영향을 미친다는 것입니다. 예를 들어 플레이어가 전진하는 키를 눌러도 서버에서 업데이트된 상태를 수신할 때까지 움직이지 않는 상황이 발생하는 것입니다. 이런 지연은 연결의 지연시간에 달려 있기 때문에 연결이 나쁠수록 제어 시스템이 매끄럽지 않게 됩니다.
이 문제에 대한 하나의 해결책이 Client-side Prediction 입니다. 클라이언트가 대략적으로 동일한 내부 모델을 활용해 서버의 예상되는 업데이트 움직임을 예측하는 방법입니다. 이 때 플레이어는 입력에 즉각 반응하지만 서버는 그 포지션을 마지막 업데이트로부터 봅니다. 마침내 상태 업데이트가 서버에서 도착하면 클라이언트는 실제 벌어진 일과 예상한 바를 비교합니다. 서버는 플레이어 주변의 환경을 더 잘 파악하고 있는 반면 클라이언트는 자신에게 필요한 것만 알기 때문에 비교한 내용상에 차이가 발생할 수 있습니다. 예측의 오류가 발생할 때 정정되며 계속 정정된다면 결과가 보다 부드러워지고 눈에 띄지 않습니다.
클라이언트 측 예측의 기본 원리를 상대 플레이어에도 적용할 수 있습니다. Extrapolation 은 마지막으로 알게 된 상대의 포지션, 속도, 방향을 저장하고 이를 기반으로 가까운 미래에 상대의 상태를 예측하는 방법입니다. 다음의 상태 업데이트가 알맞은 포지션에 도착하면 클라이언트 상태가 정확한 정보로 업데이트됩니다. 예측이 틀렸다면 캐릭터가 갑작스럽게 점프할 수 있습니다. FPS 게임에서 플레이어의 동작은 일관성이 없기 때문에 이런 예측이 잘 들어맞지 않습니다. 이 때 지연이 심해지면 예측 오류가 누적되면서 상대가 심하게 점프할 수 있습니다.
Interpolation 은 패킷이 클라이언트에 전송되는 도중에 드롭된 경우 사용할 수 있습니다. 일반적으로 NPC의 동작이 정지했다가 새 패킷이 도착하면 가장 최근 포지션으로 점프하게 만듭니다. 게임 세계의 상태를 얼마간(가령 100ms) 지연시키면서 마지막으로 알려진 포지션과 새 포지션 사이를 보간하여 패킷이 드롭된 두 지점 사이의 움직임을 부드럽게 합니다.