TIL

[Unity] Fusion2 공부 # 예측

앙박 2025. 4. 7. 23:54

당신이 총을 발사하기까지의 과정

 

 네트워크에는 ping이라고 불리는 개념이 있는데, 특정 장치(예: 서버나 다른 컴퓨터)에 데이터 패킷을 보내고, 응답이 돌아올 때까지의 왕복 시간(RTT, Round Trip Time)을 측정하는 녀석이다. 보통 ms(밀리초) 단위로 표시되고 한국에서는 10 ~ 30ms 정도의 RTT를 가진다. 이 때문에 FPS 게임에서 마우스를 클릭해 총이 발사되기까지 10~30ms 정도의 지연 시간이 발생한다(동작의 처리는 서버에서 하기 때문에, 클라이언트는 동작 요청을 보내고 서버로부터 응답을 받아야 한다.). 근데 멀티에는 다양한 플레이어가 있고 각자 RTT가 다르다. 총을 발사했다는 정보가 각 플레이어게 도달하는 시간이 각자 다르다는 건데, 그러면 누군가에겐 총알이 맞은 것처럼 보이지만 누군가는 피한 것처럼 보이며 엉망징창이 될 것이다. 이 현상을 Fusion2는 어떻게 해결하고 있을까?

 

TICK

 시스템 클록에 의해 측정되는 시간인 Tick이라는 개념이 있다. Fusion2는 요 Tick을 기준으로 네트워크 동기화를 진행하는데, 서버 측 프로그램에서의 tick 위에 모든 플레이어가 위치하도록 하는 방식이다. 근데 이것만으로는 이전과 다를게 없고, '예측'이라는 개념까지 들어가야 어느정도의 네트워크 동기화가 이루어진다.

 

FixedUpdateNetwork 

 Fusion2에서 제공하는 NetworkBehaviour 스크립트에는 FixedUpdateNetwork 메소드가 존재한다. 이 메소드는 로컬 시뮬레이션에서 일반적인 유니티의 FixedUpdate와 정확히 동일하게 작동한다. 메소드는 매 Tick마다 호출되고, 서버는 이전 틱과 비교한 네트워크 변화를 계산하고 압축해 브로드캐스트한다.

 

 여기가 중요한 부분인데, Peer들도 독자적인 시뮬레이션을 돌리며 로컬에서 각자의 계산을 진행한다는 점이다. 때문에 로컬에서는 일반적인 싱글 게임과 같이 입력에 즉각적으로 반응한다. 다만, 로컬에서 시뮬레이션을 돌린다 한들 최종적으로는 서버로부터 받은 정보에 맞춰 게임을 다시 시뮬레이션하기 때문에 결국 서버가 왕이긴 하다.

 

아니 그래서 어떻게 동기화 하는 거야잇

 Peer측에서 돌리는 시뮬레이션이 다른 Peer들의 다음 행동을 예측하는 방식으로 동기화한다. 근데 안타깝게도 플레이어의 입력 자체는 절대로 예측할 수 없기 때문에 반쪽짜리 예측에 불과하다. 그래도 ping이 사람의 반응속도에 비하면 굉장히 빠른 터라 이질감이 거의 안 들긴 한다. 물론 나같은 반응속도 120ms의 사나이한테는 다소 치명적일 수 있겠다.