TIL

[Unity] Fusion 2 공부 # 네트워크 객체를 만들고 제어하기까지

앙박 2025. 4. 9. 23:39

  Fusion2에서 네트워크 객체란 각 틱마다 시뮬레이션 되며 피어들에게 동기화 될 수 있는 GameObjct를 가리킨다.

Tick과 예측

 

 멀티 플레이는 동일한 실제 세계 시간에 정확히 동일한 연산이 이뤄질 수 없다. RTT가 0이 될 수 없기 때문이다. 대신 시뮬레이션 속 동일한 틱에서 동일한 연산이 이뤄지도록 하는 것이 최선이다. 물론 이것도 RTT 때문에 완벽히 수행될 수는 없다. 하지만 로컬 시뮬레이션을 돌려 서버의 다음 시뮬레이션을 예측하는 방법으로 눈속임 할 수는 있다. 원래는 시뮬레이션을 서버에서만 돌리고 클라이언트들에게 통보하는 방식이라 클라이언트의 시뮬레이션에는 딜레이가 있을 수 밖에 없다. 하지만, 클라이언트가 독자적인 시뮬레이션을 돌린 후에 서버로부터 받은 정보를 덮어 씌우는 방식이라면? 이 방법이 잘 먹힌다면 거의 동일하게 작동하는 것처럼 보일 것이다.

 

Fusion2 공식 문서에서 소개하는 네트워크 러너

 

시뮬레이션 실행과 네트워크 동기화 등의 작업은 NetworkRunner 컴포넌트가 수행한다. 위에서 말한 동일한 Tick 위에서의 동일한 연산 같은 기술들도 알아서 해준다. 우리는 그저 어떤 정보를 네트워크에 동기화 시킬 것인지만 정해주면 된다. 예시로, 각 플레이어가 조종하게 될 플레이어블 오브젝트나 유저들을 위협할 몬스터 객체가 동기화 대상에 해당한다.

 

플레이어가 세션에 접속하면 객체 생성

 

 동기화 될 객체는 NetworkRunner의 Spawn() 메소드를 통해 생성할 수 있다. 람다 함수로 SetPlayerObject() 메소드를 넣어 오브젝트롤 플레이어에게 귀속시킬 수도 있다.

네트워크 오브젝트

 

 NetworkRunner가 스폰할 수 있는 네트워크 객체는 한 가지 컴포넌트를 필수로 요구한다. 그게 NetworkObject인데 모든 Peer 간에 동일한 NetworkID를 가지고 있다. 또한 같은 객체의 모든 NetworkBehaviour를 찾아 관리한다. 

네트워크 비해비어

 

 네트워크 객체는 네트워크 비해비어를 상속받은 스크립트를 가질 수 있다. 대표적으로 Spawnd(), FixedUpdateNetwork(), Render() 함수를 가지고 있으며 각각 객체가 생성될 때, 시뮬레이션 틱이 바뀔 때, FixedUpdateNetwork() 메소드가 호출된 후에 실행된다. RPC(Remote Procedure Call)는 클라이언트가 호스트에게 함수 실행을 요청하는 녀석이다(호스트 모드 기준). 어차피 대부분의 네트워크 연산을 서버가 하긴 하지만, 특정 상황에서 클라이언트가 무언가 요청할 일이 생기면 RPC를 사용한다. 그 예로 채팅을 입력했을 때 그 내용을 모든 클라이언트에게 뿌려달라 요청하는 RPC가 있다. 

 

 RPC에서 쓰인 InputAuthority와 StateAuthority는 Fusion2에서 중요한 개념이다. NetworkRunner가 가지고 있는 정보 중 하나인 InputAuthority는 그 runner의 입력을 처리하는 녀석이다. 어떤 runner의 InputAuthority를 보유하고 있는 플레이어만이 입력을 넣을 수 있다.

 

 StateAuthority는 네트워크 객체들의 값들을 수정/쓰기 할 수 있는 권한이다. 호스트 모드에서 시뮬레이션 연산이 유일하게 가능한 Host가 StateAuthority를 가지고 있다 보면 된다.

 

 따라서 위 RPC는 클라이언트(InputAuthority)가 호스트(StateAuthority)에게 자신이 소유한 객체의 정보를 수정해달라 요청하는 내용이다.