This document is about: FUSION 2
SWITCH TO

데이터 동기화 헬퍼


Available in the Industries Circle
Circle
Fusion XR 프로토타이핑 모듈

데이터 동기화 헬퍼 원칙

데이터 동기화 헬퍼 애드온은 특별한 요구가 있는 사용 사례에 대한 데이터 동기화를 단순화하는 일부 헬퍼 클래스를 제공합니다.

일반적으로 대상 사용 사례는 다음과 같습니다:

  • 매우 정기적으로 작은 데이터 덩어리를 전송하며, 그 전체 목록은 나중에 참여한 플레이어에게도 필요합니다. 3D 펜으로 점을 그리고 나중에 참여한 플레이어도 전체 그림을 그릴 수 있도록 허용합니다.
  • 전체 목록을 보관할 필요가 없지만 다음 데이터 수신 전에 여러 번 보낼 수 있는 매우 정기적으로 작은 데이터 조각을 보내는 것: 예를 들어, 공중에 임시 선을 긋는 마법봉이나 총에 사용하여 모든 총이 발사되는지 확인할 수 있습니다
  • 대용량 원샷 데이터 동기화: 애플리케이션에서 찍은 사진을 다른 사용자에게 전송

RingBufferLossLessSyncBehaviour 클래스

개요

발사체 기본 - 발사체 데이터 버퍼에서 볼 수 있듯이, 링 버퍼는 첫 번째 데이터가 수신되기 전에 여러 개를 보낼 수 있더라도 일련의 작은 데이터를 저장하는 좋은 접근 방식입니다. 링 버퍼 로직은 데이터를 잃지 않고 여러 개를 유지합니다.

그러나 나중에 참여한 플레이어에게도 접근 가능해야 하는 정보(도면점 등)의 경우, 링 버퍼만으로는 해당 정보를 통과한 데이터가 점진적으로 손실됩니다.

RingBufferLossLessSyncBehaviour<TEntry> 클래스는 다음과 같은 문제를 해결합니다:

  • 기본 스토리지는 기존의 링 버퍼 외에도 공유된 데이터의 전체수를 추적합니다.
  • 늦게 참여한 사람이 도착하면 데이터가 누락되었다는 것을 알 수 있습니다.
  • 그런 경우, 이 클래스는 RPC를 통해 다른 사용자에게 메시지를 전송합니다. (원래 작성자가 데이터를 전송할 수 있는 사용자를 찾는 것을 처리합니다.),
  • 누락된 데이터를 가지고 있는 다른 사용자는 Runner.SendReliableDataToPlayer 메소드로 공유합니다.

자세히 살펴보면, 클래스는 NetworkArray<byte>에 의존하여 링 버퍼 데이터(시작 인덱스, 다음 필요 쓰기), 총 데이터 수 및 실제 데이터를 모두 저장합니다:

fusion 인더스트리 애드온 데이터 동기화 헬퍼 networkarray

누락된 데이터는 링 버퍼가 너무 빨리 채워지거나 늦은 참여자의 경우 발생할 수 있으며, 이때 누락된 데이터 범위를 요청하는 메시지가 전송됩니다:

fusion 인더스트리 애드온 데이터 동기화 헬퍼 networkarray 2

RingBufferLosslessSyncBehaviour<TEntry>는 일반적인 NetworkBehaviour의 하위 클래스로 TEntry를 지정하려면 하위 클래스가 필요합니다. TEntry는 공유할 데이터를 나타내는 구조체이어야 하며 RingBuffer.IRingBufferEntry 인터페이스를 구현하여 바이트 배열로 변환하는 인터페이스(AsByteArray)과 바이트 배열에서 콘텐츠를 로드하는 인터페이스(FillFromBytes)를 정의합니다. 이러한 메소드를 구현하는 데 도움이 되는 SerializationTools에는 정적 메소드가 포함되어 있습니다.

사용법

데이터 추가

상태 권한으로서 동기화된 데이터에 개체를 추가하려면 AddEntry(TEntry)를 사용합니다.

콜백 메소드 오버라이딩

예를 들어 일부 콜백은 실시간 데이터 수신 또는 누락된 데이터의 완전한 복구에 대응하기 위해 무시될 수 있습니다.

C#

    // newEntries will contain the new TEntry structs detected in the last data update.The received data at start might not be long enough to form an entry (for late joiners first ring reception, ...), those additional bytes are stored in newPaddingStartBytes
    public virtual void OnNewEntries(byte[] newPaddingStartBytes, TEntry[] newEntries) { }

    // OnDataLoss will warn of data loss: no need to handle the loss, the request are sent automatically
    public virtual void OnDataloss(RingBuffer.LossRange lossRange) { }

    // Called when one loss is restored
    protected virtual void OnLossRestored(LossRequest request, byte[] receivedData) { }

    // When all loss in the total data remains. SplitCompleteData() can be called to retrieve all the TEntry 
    protected virtual void OnNoLossRemaining() { }

    // When a loss is permanent (no one having the data is still in the room 
    public virtual void OnNoAnswerForALossRequest(LossRequest request) { }

IRingBufferEntry 구현

SerializationTools 클래스는 IRingBufferEntry의 예상 메소드를 간단하게 구현할 수 있습니다.

구조체를 바이트 배열(AsByteArray)로 나타내려면 기본적으로 지원되는 모든 유형(float, Vector3, byte, Quaternion, int)을 SerializationTools.AsByteArray에 전달하기만 하면 바이트 배열이 반환됩니다. 예를 들어, 다음과 같은 구조체의 경우:

C#

    [System.Serializable]
    public struct DrawPoint : RingBuffer.IRingBufferEntry
    {
        public Vector3 localPosition;
        public float drawPressure; 
        /* ... */
    }

이 구현 AsByteArray가 최적임:

C#

    public byte[] AsByteArray => SerializationTools.AsByteArray(localPosition, drawPressure);

SerializationTools.Unserialize 메소드는 배열의 위치를 추적하면서 기본적으로 지원되는 유형(float, Vector3, byte, Quaternion, int)에 대한 직렬화 해제를 처리합니다.

따라서 동일한 샘플 구조체에 대해 FillFromBytes를 구현하면 이전에 정의된 AsByteArray로 직렬화된 데이터가 로드됩니다:

C#

    public void FillFromBytes(byte[] entryBytes)
    {
        int unserializePosition = 0;
        SerializationTools.Unserialize(entryBytes, ref unserializePosition, out localPosition);
        SerializationTools.Unserialize(entryBytes, ref unserializePosition, out drawPressure);
    }

RingBufferSyncBehaviour 클래스

RingBufferSyncBehaviour는 기본 링 버퍼에 저장되지 않은 데이터를 복구하라는 메시지 없이 링 버퍼 측면을 처리하는 RingBufferLossLessSyncBehaviour의 상위 클래스입니다.

RingBufferLossLessSyncBehaviour로 사용할 수 있으며, 손실 복구와 관련된 사항은 없습니다(손실은 여전히 감지되지만 여기서는 복구할 수 없습니다).

이 클래스는 클래식 링 버퍼 요구(총 발사체 등)에 사용할 수 있습니다.

링 버퍼 인덱스 추적 자체는 시작 인덱스와 다음 쓰기 인덱스를 업데이트하는 Ringbuffer라는 이름의 구조체에서 수행되며, 제공되면 데이터를 추가하거나 실제 데이터 저장소를 업데이트할 수 있습니다.

StreamingSyncBehaviour 클래스

개요

StreamSynchedBehaviour를 사용하면 임의의 데이터 덩어리를 다른 플레이어에게 전송할 수 있습니다. 이 도우미는 Fusion `SendReliableDataToPlayer API를 사용합니다. 이 API로 메시지를 식별하는 데 사용되는 4부분 키의 첫 번째 부분은 객체 ID를 저장하는 데 사용되며, 따라서 룸에 있는 여러 객체가 잘못된 객체로 데이터를 보낼 염려 없이 데이터를 주고받을 수 있습니다.

StreamSynchedBehaviour의 주요 구체적인 내용은 나중에 참여한 플레이어 사례를 처리하는 것입니다. 특히 공유 모드에서 상태 권한자가 자리를 비운 경우 초기 전송을 놓친 사용자에게 데이터를 보내는 방법입니다.

이것은 나중에 참여한 플레이어가 보낸 RPC 메시지에 의해 수행되며, 상태 권한이나 다른 플레이어가 방을 떠난 경우 전체 캐시를 수신하도록 요청합니다.

사용법

데이터 전송

데이터 전송은 전송할 데이터와 함께 Send(byte[] data)를 호출하여 수행됩니다. 데이터는 청크로 저장된 것으로 수신되며, 하위 클래스는 필요한 경우 이를 병합해야 합니다.

콜백 메소드 오버라이딩

예를 들어 일부 콜백은 실시간 데이터 수신 또는 누락된 데이터 복구 시 대응하도록 무시할 수 있습니다.

C#

    // Provides the 0-1 download progress of a currently received chunk of data
    protected virtual void OnDataProgress(float progress) { }
    // Called on complete reception of a chunk of data
    protected virtual void OnNewBytes(byte[] newData) { }
    // Called to know the client is a late joiner, waiting for data
    protected virtual void OnLateJoinersWaitingForData() { }
    // Called if missing data for a late joiner are unavailable anywhere
    protected virtual void OnMissingData() { }

데모

헬퍼는 하위 클래스를 지정하는 방법을 보여주는 몇 가지 샘플 클래스를 가지고 있습니다:

  • StreamingSyncBehaviourTestStreamSynchedBehaviour
  • RingBufferLossLessSyncBehaviourTestLosslessRingBufferSync
  • RingBufferSyncBehaviourTestRingBufferSync

DemoStreaminghelpers의 씬은 StreamingSyncBehaviourTestStreamSynchedBehaviour 구현을 담고 있습니다. 씬에는 데이터가 적절한 StreamSynchedBehaviour 객체로 전송됨을 보여주기 위해 이러한 컴포넌트 중 2개가 포함됩니다. SendRandomData 버튼을 누르면 연결된 사용자에게 데이터 청크가 전송되며 All data 속성에 나타납니다. 나중에 참여한 플레이어도 사용할 수 있습니다.

DemoRingBuffer에는 TestLosslessRingBufferSyncTestRingBufferSync가 모두 포함되어 있어 무손실 및 일반 링 버퍼를 모두 보여줍니다. 링 개체의 경우 AddSingleEntry(인스펙터에 설명된 엔트리를 데이터에 추가 추가할 Single Entry), AddRandomEntry 또는 AddSeveralRandomEntries를 눌러 인스펙터의 엔트리 필드에 엔트리가 추가됩니다. 연결된 클라이언트와 늦게 참여한 플레이어 클라이언트 모두에 나타납니다. 로그 레벨에 데이터 손실 복구가 포함되어 있으므로 콘솔에서 데이터 손실 복구에 대한 메시지를 볼 수 있습니다. 늦게 참여한 플레이어는 이러한 메시지를 체계적으로 트리거하고, AddSeveralRandomEntries 호출은 일부러 링 버퍼를 너무 빨리 채우므로 이러한 메시지가 나타납니다. 결국 모든 사용자는 동일한 항목을 갖게 됩니다.

다운로드

이 애드온의 최신 버전은 애드온 프로젝트에 포함되어 있습니다.

지원하는 토폴로지

  • 공유 모드

StreamingSyncBehaviour는 호스트 토폴로지에서도 사용할 수 있습니다.

변경 내역

  • 버전 2.0.0: 최초 릴리즈
Back to top