수정중인 페이지 입니다.

상태 전송

소개

Fusion은 상태 전송에 의존하는 많은 네트워크 아키텍처를 지원합니다. Fusion은 단순성을 염두에 두고 구축되었으며 유니티 작업 흐림에 자연스럽게 통합되는 동시에 델타 압축, 클라이언트 측 예측 및 지연 보상과 같은 고급 상태 전송 기능을 즉시 제공합니다.

메인 화면으로

상태 전송 기본 지침서

"상태 전송"이라는 용어는 게임 상태가 모든 클라이언트에 어떻게 배포되는지를 나타냅니다. 상태 전송 아키텍처에서 게임 상태는 서버에서 클라이언트로 전송됩니다. 상태는 클라이언트가 게임 상태를 로컬로 복제하는 데 필요한 모든 것을 포함합니다. Fusion은 NetworkBehaviours로 알려진 MonoBehaviours들의 특화된 속성을 통해 게임 상태를 나타냅니다. 특정 순간(틱)에 네트워크로 연결된 모든 게임 객체의 전체 [Networked] 속성 집합을 스냅샷이라고 합니다.

Fusion에서 사용하는 2가지 상태 전송 모드는 다음과 같습니다:

  1. 델타-압축, 또는 DC, 압축된 전체 스냅샷을 전송합니다. 그리고,
  2. 최종 일관성, 또는 EC, 관심 관리 필터를 사용하여 각 클라이언트에 전송되는 스냅샷에 전체 게임 상태의 어떤 부분을 포함할지 결정합니다.

두 경우 모두 네트워크 지연 시간으로 인해 조정된 상태는 클라이언트가 수신할 때는 이미 오래된 상태입니다. 이를 보완하기 위해 Fusion은 가장 최근에 수신된 상태에서 이전 업데이트(약 스냅샷 틱 + RTT)의 마지막 예측 틱까지 로컬 [Networked] 속성의 상태를 다시 시뮬레이션합니다. 여기에서 Fusion은 다음에 클라이언트로부터 입력을 받을 때 서버가 있을 위치와 일치하는 새로운 미래 상태를 추가로 예측할 수 있습니다.

State Transfer (Snapshot)
서버에서 클라이언트로 완료 상태를 전송.

최종 일관성 모드에서는 수신된 데이터가 전체 네트워크 상태의 하위 집합만 나타냅니다. 상태는 항상 주어진 NetworkObject들의 집합의 동일한 속성에 노출되므로 애플리케이션에 투명합니다.

State Transfer (Eventual Consistency)
플레이어에서 관심 있는 객체를 서버에서 클라이언트로 전송.

메인 화면으로

클라이언트- Vs. 서버-권한

Fusion은 2 종류의 권한 모드에서 동작할 수 있습니다:

  • 서버-권한 모드: 클라이언트 중 하나가 서버와 클라이언트(호스트) 역할을 모두 수행하는 전용 헤드리스 유니티 인스턴스를 사용하는 엄격한 클라이언트/서버 설정이며
  • 클라이언트-권한 모드: 각 클라이언트는 소유한 객체들에 대해 모든 권한을 갖고 있습니다.

클라이언트 권한 모드에서는 재시뮬레이션이 없으며, 모든 클라이언트는 항상 전달을 시뮬레이션하며 다른 클라이언트로부터 받은 상태 스냅샷을 현재의 사실로 받아들여야 합니다.

메인 화면으로

압축

상태 전송의 분명한 단점은 대역폭 사용입니다. Fusion은 네트워크 게임 상태에 변경 사항만 보내고 해당 데이터에 대한 최소 비트 레벨 표현을 선택하여 패키지 크기를 줄이기 위해 많은 노력을 기울입니다. 최종 일관성의 경우 수신자와 관련된 변경 사항만 포함하므로 훨씬 더 줄어듭니다.

정확도

데이터를 효율적으로 압축하는 데 있어 가장 중요한 측면은 정확도입니다. Fusion에서는 NetworkProjectConfig > Accuracy Defaults의 글로벌 레벨에서 또는 [Accuracy] 속성을 사용하여 각 개별 변수에 대해 설정할 수 있습니다.

Accuracy
네트워크 프로젝트 구성의 Fusion 기본 정확도 설정

정확도는 Fusion에서 부동 소수점 숫자를 정수로 변환하는 데 사용됩니다. 예를 들어, Fusion은 0.00과 1.00 사이의 값을 소수점 두 자리의 정확도 대신 0과 100 사이의 단일 정수를 저장합니다. 값은 여전히 동일한 메모리 크기(4바이트)가 필요하지만 훨씬 더 효율적으로 압축할 수 있으므로 대역을 절약할 수 있습니다. 애프리케이션은 모든 네트워크 속성에 대해 의미 있는 정확도를 선택하여 전송 크기를 줄일 수 있습니다.

메인 화면으로

델타 압축

앞에서 정의한 정확도를 사용하여 델타는 전송해야 하는 실제 비트 수를 줄이는 방식으로 압축됩니다. 여기서 부동 소수점을 4바이트 정수로 변환하면 훨씬 더 밀집한 비트 표현 덕분에 몇 비트로 줄일 수 있습니다.

델타 압축은 클라이언트가 마지막으로 수신한 틱의 총 상태와 현재 틱의 총 상태 간의 차이를 계산합니다. 예를 들어, 서버가 클라이언트로부터 틱 95를 받았고 현재 틱 100인 것을 확인한 경우, 다음 델타는 5개의 틱에 걸쳐 계산됩니다.

Delta Flow
델타 스냅샷의 흐름과 클라이언트의 확인 응답.

서버가 클라이언트로부터 확인을 받을 때까지 델타는 증가하며, 이렇게 하면 일반적으로 전송된 패키지 중 여러 개가 중복됩니다. 이것이 비효율적으로 보일 수 있지만, Fusion의 가장 큰 장점은 손실된 패킷에 대해 걱정할 필요가 없다는 것입니다. 클라이언트가 어떤 델타를 받든 클라이언트의 상태에 관계없이 항상 적용할 수 있습니다. 오래된 델타가 늦게 나타나는 경우 현재 상태에 영향을 미치지 않고 삭제되거나 복구 절차를 유발하는 지연 시간이 필요합니다.

Fusion은 대역폭을 위해 최악의 경우 지연 시간을 크게 줄이기 위해 효과적으로 대역폭을 조정하고 있습니다.

메인 화면으로

관심 관리

Fusion이 최종 일관성 모드에서 실행되도록 설정되면 API를 사용하여 각 플레이어로 전송되는 데이터를 제어함으로써 대역폭 더욱 효과적으로 줄일 수 있습니다. 이를 일반적으로 "관심 관리"라고 합니다.

이를 통해 개별 플레이어가 세상을 바라보는 인식에 영향을 미치지 않고 유선을 통해 전송되는 데이터의 양을 크게 줄일 수 있습니다. 특히 게임을 플레이할 수 있도록 하려면 관심 관리가 필수인 경우가 많은 대규모 게임에서는 더욱 그렇습니다.

플레이어가 관심을 갖고 있는 네트워크 게임 객체의 목록을 제어하는 데에는 3 가지 방식이 있습니다:

  • 관심 지역 (플레이어별로 여러 개)
  • 글로벌 객체 (모든 플레이어)
  • 사용자 지정 관심 관리 (플레이어-객체 쌍 별)

메인 화면으로

관심 지역

관심 지역 또는 AoI는 데이터 전송에 NetworkObject들을 자동으로 추가하는 월드 스페이스 스피어를 정의합니다. 이것은 플레이어 아바타 주변의 단일 스피어가 될 수 있으며, 플레이어 시야 거리 또는 플레이어가 업데이트해야 하는 위치(예: 미션 목표 주변 영역)와 일치하는 반지름을 가질 수 있습니다.

플레이어의 AoI를 지정하는 것은 NetworkRunner에서 간단한 API 호출입니다.

Runner.AddPlayerAreaOfInterest(PlayerRef player, Vector3 worldPosition, float radius);

노트: 공유 모드에 사용되는 반경은 고정되어 있으며 NetworkProjectConfig에서 설정됩니다.

ServerModeHostMode에서 서버 / 호스트에서 FixedUpdateNetwork()의 모든 프레임을 호출합니다. 클라이언트에서 호출할 경우 플레이어 참조가 로컬 플레이어여야 합니다. 이는 AOI 책임이 Photon Cloud에 의해 처리되는 클라이언트 권한 모드에서만 가능합니다.

서버가 AoI 포함에 대해 고려해야 할 네트워크 객체를 알기 위해, 특히 Photon 클라우드가 객체가 세계의 어디에 있는지 알기 위해서는 게임 객체는 사전 구축된 NetworkBehaviour: NetworkTransform, NetworkRidigBody 또는 NetworkCharacterController의 변형을 사용해야 합니다.

메인 화면으로

글로벌 객체

AoI의 공간적 표현 외에도 NetworkObject 컴포넌트에서 객체를 global로 표시할 수 있습니다. 이것은 그들이 세계 랭킹에 상관없이 모든 플레이어들의 AoI에 포함될 것입니다.

State Transfer AoI
글로벌 객체에 대한 AoI 설정

메인 화면으로

사용자 지정 관심 관리

각각의 플레이어들은 그들이 항상 관심 있는 개별적인 객체를 가질 수 있습니다. 특정 NetworkObject의 데이터를 항상 플레이어로 보내려면 SetPlayerAlwaysInterested()를 한 번 호출하십시오.

Runner.SetPlayerAlwaysInterested(PlayerRef player, NetworkObject obj, bool always)

메인 화면으로

네트워크 토폴로지

Fusion 은 몇 개의 네트워크 토폴로지를 지원합니다.

Fusion Network Topologies
Fusion 네트워크 토폴로지.

메인 화면으로

전용 서버

전체 서버 권한으로 유니티 헤드리스 인스턴스를 배포합니다. 이것은 물리 객체 및 렌더링 원시 요소(사용하지 않더라도)를 포함하여 게임 세계에 대한 완전한 지식을 갖춘 신뢰할 수 있는 권위 있는 엔티티를 보유하는 데 도움이 되는 고전적인 클라이언트/서버 설정입니다. 전용 서버는 일반적으로 공용 정적 IP에서 호스팅 되므로 UDP 홀 펀칭이나 네트워크 릴레이가 필요하지 않습니다.

전용 서버의 주요 단점은 모든 게임 세션에서 전체 유니티 인스턴스를 회전시키는 비용입니다.

메인 화면으로

플레이어 호스팅

플레이어 호스팅 서버 모드는 Photon Cloud가 제공하는 전체 호스트 마이그레이션 지원을 포함한 펀치스루 및 릴레이가 예비로 제공됩니다. UDP 홀 펀칭이 실패하고 Fusion이 피어 간에 직접 연결을 설정할 수 없는 경우 플레이어는 릴레이를 통해 연결해야 합니다. 이는 산발적으로 발생하며 플레이어 10명 중 1명에게만 발생합니다. 플레이어 호스팅에서 지연 시간이 발생할 수 있는 잠재적인 요소가 있기는 하지만 게임 플레이 측면에서는 거의 눈에 띄지 않습니다.

플레이어 호스팅 모드에서 로컬 인스턴스는 서버이며 클라이언트가 아닙니다. 이 모드에서는 여전히 로컬 플레이어를 사용할 수 있으며 해당 플레이어의 입력을 폴링하고 예상대로 렌더링 시 인터폴링합니다. 전반적으로 이 모드는 전용 서버와 동일합니다(즉, 게임 코드에 눈에 띄는 변화가 없습니다). 즉, 신뢰할 수 있는 기관을 희생하여 전용 서버 비용을 없앱니다. 즉, 악성 호스트가 속임수를 쓸 수 있습니다.

메인 화면으로

단일 플레이어

Fusion을 사용하면 네트워크 코드를 변경하지 않고 로컬로 실행할 수 있습니다. 로직은 플레이어 호스팅 모드에서 실행되지만 외부 네트워크 연결을 열지 않습니다. 따라서 애플리케이션이 게임 모드를 무제한으로 전환할 필요가 없습니다.

메인 화면으로

공유 모드

최종 일관성(EC) 및 관심 관리를 사용하여 데이터 기반 서버 관리 스냅샷을 포함한 Photon Cloud에 대한 클라이언트 권한도 높은 플레이어 수로 확장됩니다. 공유 모드는 전체 유니티 인스턴스를 실행하는 데 드는 막대한 오버헤드 없이 전용 서버의 장점 중 일부를 달성하기 위해 Photon Cloud를 사용합니다.

선택사항: Fusion의 Photon Server 플러그인은 유니티 없이도 게임 상태에 완전히 접근할 수 있습니다. 이렇게 하면 사용자 지정 Fusion 서버 플러그인을 쉽게 작성할 수 없어 게임 상태 검증을 통해 치트 및 악용 방지를 할 수 있습니다.

기술문서 TOP으로 돌아가기