This document is about: FUSION 2
SWITCH TO

메타 아바타


Available in the Industries Circle
Circle
Fusion 인더스트리 프로토타이핑 애드온

이 애드온은 메타 아바타를 Fusion과 통합하는 방법을 보여줍니다.

주요 내용은 다음과 같습니다:

  • Fusion 네트워크 변수를 사용하여 아바타 동기화
  • Fusion Voice와 립싱크 통합
Fusion Oculus Meta Avatar

Meta XR SDK

여기에는 다른 샘플에 사용되는 OpenXR 플러그인 대신 Oculus XR 플러그인이 사용됩니다.

Meta XR SDK는 범위가 지정된 레지스트리 https://npm.developer.oculus.com/ (자세한 내용은 Meta 문서 참조)를 통해 추가되었습니다.

메타 레지스터의 주요 설치 패키지는 다음과 같습니다:

  • Meta XR Core SDK
  • Meta XR Platform SDK: Oculus 사용자 ID에 액세스하고 Meta 아바타를 로드하는데 필요합니다.

Oculus 리그 및 빌딩 블록

OpenXR 플러그인 대신 Oculus XR 플러그인을 기반으로 헤드셋과 손 위치를 캡처할 수 있는 특정 리그가 만들어졌습니다.

이 하드웨어 수집 리그는 Meta 빌딩 블록을 통해 생성되었습니다.

  • 이 단계에서 생성된 프리팹은 MetaOVRHandsSynchronization 애드온의 /Prefabs/Rig/BaseBuildingBlocks/[BuildingBlock] BaseRig 프리팹에서 사용할 수 있습니다.
  • 이전에 동기화 컴포넌트가 추가된 추가 기능에 사용된 프리팹은 /Prefabs/HardwareRig/[BuildingBlock] HardwareRigForMetaAvatar 프리팹에서 사용할 수 있습니다.
Meta의 빌딩 블록 기반 리그

MetaAvatar 게임 객체는 메타 아바타가 제 기능을 하는 데 필요한 모든 컴포넌트를 한데 묶습니다.

  • LipSyncOVRAvatarLipSyncContext라는 컴포넌트를 가지고 있습니다: Oculus SDK에서 립싱크 기능을 설정하기 위해 제공합니다.
  • BodyTracking은 Oculus SDK(Asset/Avatar2/Example/Common/Scripts)에서 나온 SampleInputManager의 컴포넌트입니다. OvrAvatarInputManager의 기본 클래스에서 파생된 클래스로 아바타 개체에 추적 입력을 설정하는 OVR Hardware Rig를 말합니다.
  • AvatarManager는 메타바타를 로드하는 데 사용되는 OVRAvatarManager라는 컴포넌트를 가지고 있습니다.

러너

Runner 게임 객체에 위치한 ConnectionManagerOnPlayerJoined 콜백이 호출되면 Photon Fusion 서버와의 연결을 처리하고 사용자 네트워크 프리팹을 생성합니다.
네트워크를 통해 음성을 스트리밍 하려면 Fusion Voice Client가 필요합니다. 프라이머리 레코더 필드는 Runner에 있는 Recorder 게임 객체를 말합니다.

Fusion으로 Photon Voice 통합에 대한 자세한 내용은Voice - Fusion 통합 페이지를 참조하십시오.

Runner의 게임 객체는 MetaAvatarMicrophoneAuthorization 컴포넌트 덕분에 마이크 인가를 요청하는 기능도 담당합니다. 마이크 접근이 허용되면 Recorder 객체를 활성화합니다.

하위 객체인 RecorderRecorder의 오디오 스트림을 수신하여 OVRAvatarLipSyncContext로 전달하는 AudioLipSyncConnector 컴포넌트를 포함하고 있습니다.

사용자가 스폰 한 네트워크 프리팹

ConnectionManagerOnPlayerJoined 콜백이 호출되면 사용자 네트워크 프리팹인 NetworkRigWithOVRHandsMetaAvatar Variant를 생성합니다.

이 프리팹은 다음을 포함합니다:

  • MetaAvatarSync : 시작할 때 임의의 아바타를 선택하고 네트워크를 통해 아바타를 스트리밍 하는 기능을 담당합니다.

  • NetworkedAvatarEntity : Oculus OvrAvatarEntity에서 파생되었습니다. 네트워크 리그가 로컬 사용자를 나타내는지 원격 사용자를 나타내는지에 따라 아바타 객체를 구성하는 데 사용됩니다.

아바타 동기화

개요

MetaAvatarSync 클래스는 아바타 동기화의 오케스트레이션을 담당합니다.
ConfigureAsLocalAvatar() 메소드 덕분에 사용자 네트워크 프리팹이 로컬 사용자를 위해 생성되면 관련 NetworkAvatarEntity는 다음으로부터 데이터를 받았습니다:

  • 립싱크를 위한 OvrAvatarLipSyncContext
  • 바디 트래킹을 위한 SampleInputManager

네트워크 변수 덕분에 데이터가 네트워크를 통해 스트리밍됩니다.

원격 사용자를 위해 사용자 네트워크 프리팹이 생성되면 MetaAvatarSync ConfigureAsRemoteAvatar()가 호출되고 관련 NetworkAvatarEntity 클래스가 데이터 스트리밍을 통해 아바타를 빌드하고 애니메이션화합니다.

Fusion Oculus Meta Avatar

아바타 모드

MetaAvatarSync는 2가지 모드를 지원합니다 :

  • UserAvatar : 사용자의 메타 아바티 로드
  • RandomAvatar : 무작위 메타 아바타 로드

따라서, 로컬 사용자 네트워크화된 프리팹이 생성될 때, 아바타는 이 구성에 따라 선택됩니다.

C#

public override void Spawned()
{
    base.Spawned();

    if (Object.HasInputAuthority)
    {
        LoadLocalAvatar();
    }
    else
    {
        if (!avatarConfigured)
        {
            ConfigureAsRemoteAvatar();
        }
    }
    changeDetector = GetChangeDetector(ChangeDetector.Source.SnapshotFrom);
    // Trigger initial change if any
    OnUserIdChanged();
    ChangeAvatarIndex();
}

async void LoadLocalAvatar()
{
    if (avatarMode == AvatarMode.UserAvatar)
    {
        // Make sure to download the user id
        ConfigureAsLocalAvatar();
        UserId = await avatarEntity.LoadUserAvatar();
    }
    else
    {
        ConfigureAsLocalAvatar();
        AvatarIndex = UnityEngine.Random.Range(0, 31);
        avatarEntity.LoadZipAvatar(AvatarIndex);
    }
}

AvatarIndex가 네트워크 변수이므로, ChangeDetector 덕분에 이 값이 감지될 때 모든 플레이어들은 업데이트 되어집니다.

C#

    [Networked]
    public int AvatarIndex { get; set; } = -1;

    ChangeDetector changeDetector;

C#

    public override void Render()
    {
        base.Render();
        foreach (var changedPropertyName in changeDetector.DetectChanges(this))
        {
            if (changedPropertyName == nameof(UserId)) OnUserIdChanged();
...
        }
    }

아바타 데이터

하드웨어 리그의 SampleInputManager 컴포넌트는 사용자의 움직임을 추적합니다.
플레이어 네트워크 리그가 로컬 사용자를 나타내는 경우 NetworkedAvatarEntity에서 참조합니다.
이 설정은 MetaAvatarSync (ConfigureAsLocalAvatar())에 의해 수행됩니다.

각각의 LateUpdate(), MetaAvatarSync는 해당 지역 플레이어의 아바타 데이터를 캡처합니다.

C#

    private void LateUpdate()
    {
    // Local avatar has fully updated this frame and can send data to the network
    if (Object.HasInputAuthority)
    {
        CaptureAvatarData();
    }
}

CaptureLODAvatar 메소드는은 아바타 객체 스트림 버퍼를 받아 AvatarData라는 네트워크 변수에 복사합니다.
용량은 중간 또는 높은 LOD에서 메타바타를 스트리밍하기에 충분하므로 1200으로 제한됩니다(실제 구성의 경우 메모리 낭비를 방지하기 위해 이 숫자는 실제 필요한 데이터 양과 일치해야 함).
단순화를 위해 이 샘플에는 중간 LOD만 스트리밍됩니다.

버퍼 크기 AvatarDataCount도 네트워크를 통해 동기화됩니다.

C#

    [Networked, Capacity(1200)]
    public NetworkArray<byte> AvatarData { get; }
 
    [Networked]
    public uint AvatarDataCount { get; set; }

따라서 아바타 스트림 버퍼가 업데이트되면 원격 사용자에게 정보를 제공하고 수신된 데이터를 원격 플레이어를 나타내는 네트워크 리그에 적용합니다.

C#

    public override void Render()
    {
        base.Render();
        foreach (var changedPropertyName in changeDetector.DetectChanges(this))
        {
...
            if (changedPropertyName == nameof(AvatarData)) ApplyAvatarData();
        }
    }

개인화된 메타 아바타 로딩

로컬 사용자 아바타 로딩

앞에서 본 바와 같이 사용자의 메타 아바타를 로드하려면 AvatarModeAvatarMode.UserAvatar로 설정해야 합니다.
그래서 Spawned 콜백 중에 NetworkedAvatarEntityLoadUserAvatar()로 사용자 계정 아바타를 요청합니다.

C#

/// <summary>
/// Load the user meta avatar based on its user id
/// Note: _deferLoading has to been set to true for this to be working
/// </summary>

public async Task<ulong> LoadUserAvatar()
{
    // Initializes the OVR PLatform, then get the user id
    await FinOculusUserId();
    if(_userId != 0)
    {
        // Load the actual avatar
        StartCoroutine(Retry_HasAvatarRequest());
    }
    else
    {
        Debug.LogError("Unable to find UserId.");
    }
    return _userId;
}

이 메소드는 UserId [Networked] 변수에 저장된 Meta의 계정 사용자 ID를 반환하여 모든 클라이언트에서 사용자 ID가 동기화되도록 합니다.

C#

    [Networked]
    public ulong UserId { get; set; } = 0;

사용자 아바타를 로드하려면 다음과 같이 하십시오:

  • Defer Loading은 플레이어의 프리팹의 NetworkedAvatarEntity 컴포넌트에서 true로 설정해야 합니다. 그러면 처음에 아바타가 자동으로 로딩되지 않습니다.

원격 사용자의 아바타 로딩

UserId를 수신하면 원격 사용자는 이 ID와 관련된 아바타의 다운로드를 트리거합니다:

C#

    public override void Render()
    {
        base.Render();
        foreach (var changedPropertyName in changeDetector.DetectChanges(this))
        {
            if (changedPropertyName == nameof(UserId)) OnUserIdChanged();
            ...
        }
    }
    void OnUserIdChanged()
    {   
        if(Object.HasStateAuthority == false && UserId != 0)
        {
            Debug.Log("Loading remote avatar: "+UserId);
            avatarEntity.LoadRemoteUserCdnAvatar(UserId);
        }
    }

메타 아바타 접근

메타바타를 로드하려면 Oculus > Oculus Platform 유니티 설정 메뉴에서 애플리케이션에 대한 App Id를 추가해야 합니다.
App Id는 Meta 관리 화면의 API > App Id 필드에서 확인할 수 있습니다.
또한 이 애플리케이션은 Data use checkup 섹션을 완료해야 하며, User Id, User profile , Avatars 접근이 필요합니다:

Fusion Oculus Meta Avatar Data use checkup

사용자의 아바타 테스트

개발 중에 로컬 메타 계정과 관련된 아바타를 볼 수 있으려면, 로컬 사용자 계정이 Oculus Platform 설정에서 제공된 App Id와 관련된 조직의 구성원이어야 합니다.
크로스 플랫폼 설정(Quest와 데스크톱 빌드 사이)에서 아바타를 보려면 이 페이지의 Group App IDs Together 장에 명시된 대로 Quest와 Rift 애플리케이션을 그룹화해야 합니다.Meta 아바타 SDK용 앱 구성

립씽크

마이크 초기화는 Photon Voice Recorder에 의해 수행됩니다.

OVRHardwareRigOvrAvatarLipSyncContext는 오디오 버퍼와 함께 직접 호출이 가능하도록 구성되어 있습니다.
아래와 같이 OvrAvatarLipSyncContext에 전달하기 위해 레코더 오디오 판독에 후크를 연결합니다.

Recorder 클래스는 읽기 오디오 버퍼를 IProcessor 인터페이스를 구현하는 클래스로 전달할 수 있습니다.
사용자 지정 오디오 프로세서를 만드는 방법에 대한 자세한 내용은 Photon Voice - FAQ페이지를 참조하십시오.

이러한 프로세서를 음성 연결에 등록하기 위해 Recorder와 동일한 게임 오브젝트에 VoiceComponent 서브클래스인 AudioLipSyncConnector를 추가합니다.
이로 인해 PhotonVoiceCreatedPhotonVoiceRemoved 콜백이 수신되어 연결된 음성에 포스트 프로세서를 추가할 수 있게 되었습니다.
연결된 포스트 프로세서는 AvatarAudioProcessorIProcessor<float> 또는 IProcessor<short>를 구현합니다.

MetaAvatarSync 컴포넌트는 플레이어 연결 중에 레코더에 있는 AudioLipSyncConnector를 검색하여 이 프로세서의 lipSyncContext 필드를 설정합니다.

이렇게 하면 수신된 오디오 버퍼를 가진 OvrAvatarLipSyncContext에서 AvatarAudioProcessor Process 콜백이 호출될 때마다 수신된 오디오 버퍼를 통해 ProcessAudioSamples가 호출되어 아바타 모델에서 립씽크가 계산되도록 합니다.

이렇게 하면 MetaAvatarSync 업데이트가 늦어지는 동안 아바타 개체에서 RecordStreamData_AutoBuffer로 캡처하면 다른 아바타 객체 정보와 함께 립싱크가 스트리밍됩니다.

의존성

  • Meta Avatar2 SDK
  • Meta XR Core SDK
  • Meta XR Platform SDK
  • Photon Voice SDK
  • MetaOVRHandsSynchronization 애드온

데모

데모 씬은 Assets\Photon\FusionAddons\MetaAvatar\Demo\Scenes\ 폴더에 있습니다.

다운로드

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

지원하는 토폴로지

  • 공유 모드

변경 내역

  • Version 2.0.0: 최초 릴리즈
Back to top