# Oculus(Meta Quest)

> Provide an Oculus sign-in option to enable players to authenticate using their Meta Quest accounts on virtual reality platforms.

###### 최소 SDK 버전: 2.3.1##minimum-sdk-version-231

이 문서에서는 게임에서 Oculus 계정을 사용해 플레이어의 인증을 설정하는 다음 시나리오에 대해 설명합니다.

* Oculus 로그인 설정
* 기존 사용자 로그인 또는 새 사용자 생성
* 사용자를 익명 로그인에서 커스텀 ID 제공업체를 통한 플랫폼 로그인으로 업데이트

게임에서 플레이어에게 Oculus 로그인 옵션을 제공하려면 [Oculus Developer Dashboard](https://developer.oculus.com/manage)에서 앱을 생성하고 App ID, App Secret, nonce, userId를 확인합니다.

패키지를 추가하려면 다음 섹션을 참고하십시오.

## Oculus 로그인 설정

Unity Authentication의 ID 제공업체로 Oculus를 설정하려면 다음을 따르십시오.

1. Unity 에디터 메뉴에서 **Edit** > **Project Settings…** 로 이동한 후, 내비게이션 메뉴에서 **Services** > **Authentication**을 선택합니다.
2. **ID Providers**를 Oculus로 설정한 후, **Add**를 클릭합니다.
3. **App ID** 텍스트 필드에 앱 ID를 입력합니다.
4. **App Secret** 텍스트 필드에 앱 비밀 정보를 입력합니다.

로그인된 Oculus 사용자를 가져오고 nonce를 생성하려면 아래 예시 코드를 참고하십시오.

1. 헤드셋을 착용하고 **Settings** > **System** > **Developer**로 이동합니다.
2. **USB Connection Dialog** 옵션을 활성화합니다.
3. USB-C 케이블을 사용해 헤드셋을 컴퓨터에 연결합니다.
4. 데이터 액세스 권한을 요청하는 창이 표시되면 **Allow**를 클릭합니다.
5. 기기가 성공적으로 연결되었는지 확인하기 위해 Unity 프로젝트를 열고 **File** > **Build Settings**로 이동합니다. **Platform** 목록에서 **Android**를 선택하고 **Switch Platform**을 클릭합니다.
6. **Run Device** 목록에서 Oculus 헤드셋을 선택합니다. 목록에 헤드셋이 없는 경우 **Refresh**를 클릭해 목록을 새로 고칩니다.
7. [이 Oculus Integration](https://assetstore.unity.com/packages/tools/integration/oculus-integration-82022) 패키지를 설정하고 설치합니다. [Oculus Developer Center](https://developer.oculus.com/documentation/unity/unity-import/#import-from-dev-center)에서도 패키지를 찾을 수 있습니다.
8. 프로젝트에 임포트한 후, 에디터의 메뉴 바에서 **Oculus** > **Platform** > **Edit Settings**로 이동합니다. Oculus 앱 ID를 입력해야 합니다.

```cs
using UnityEngine;
using Oculus.Platform;
using Oculus.Platform.Models;

public class OculusAuth : MonoBehaviour
{
    private string userId;

    private void Start()
    {
        Core.AsyncInitialize().OnComplete(OnInitializationCallback);
    }

    private void OnInitializationCallback(Message<PlatformInitialize> msg)
    {
        if (msg.IsError)
        {
            Debug.LogErrorFormat("Oculus: Error during initialization. Error Message: {0}",
                msg.GetError().Message);
        }
        else
        {
            Entitlements.IsUserEntitledToApplication().OnComplete(OnIsEntitledCallback);
        }
    }

    private void OnIsEntitledCallback(Message msg)
    {
        if (msg.IsError)
        {
            Debug.LogErrorFormat("Oculus: Error verifying the user is entitled to the application. Error Message: {0}",
                msg.GetError().Message);
        }
        else
        {
            GetLoggedInUser();
        }
    }

    private void GetLoggedInUser()
    {
        Users.GetLoggedInUser().OnComplete(OnLoggedInUserCallback);
    }

    private void OnLoggedInUserCallback(Message<User> msg)
    {
        if (msg.IsError)
        {
            Debug.LogErrorFormat("Oculus: Error getting logged in user. Error Message: {0}",
                msg.GetError().Message);
        }
        else
        {
            userId = msg.Data.ID.ToString(); // do not use msg.Data.OculusID;
            GetUserProof();
        }
    }

    private void GetUserProof()
    {
        Users.GetUserProof().OnComplete(OnUserProofCallback);
    }

    private void OnUserProofCallback(Message<UserProof> msg)
    {
        if (msg.IsError)
        {
            Debug.LogErrorFormat("Oculus: Error getting user proof. Error Message: {0}",
                msg.GetError().Message);
        }
        else
        {
            string oculusNonce = msg.Data.Value;
            // Authentication can be performed here
        }
    }
}
```

**참고**: Oculus 헤드셋을 개발자 모드로 설정해야 합니다. 개발자 모드로 설정하려면 개발에 사용하려는 개발자 계정으로 로그인해야 합니다. [여기](https://developer.oculus.com/sign-up/)에서 Oculus 개발자 계정을 생성할 수 있습니다.

## 기존 플레이어 로그인 또는 신규 플레이어 생성##sign-in-a-returning-player-or-create-new-player

`SignInWithOculusAsync` 메서드를 사용하여 다음 중 하나를 수행할 수 있습니다.

* Oculus 자격 증명을 사용해 새 Unity Authentication 플레이어 생성
* Oculus 자격 증명을 사용해 기존 플레이어 로그인

프로젝트에서 자격 증명과 연결된 Unity Authentication 플레이어가 존재하지 않는 경우, `SignInWithOculusAsync`가 새 플레이어를 생성합니다. 프로젝트에서 자격 증명과 연결된 Unity Authentication 플레이어가 존재하는 경우, `SignInWithOculusAsync`가 해당 플레이어 계정으로 로그인합니다.

이 기능은 캐시된 플레이어를 고려하지 않으며, `SignInWithOculusAsync`가 캐시된 플레이어를 대체합니다.

```cs
async Task SignInWithOculusAsync(string nonce, string userId)
{
  try
  {
    await AuthenticationService.Instance.SignInWithOculusAsync(nonce, userId);
    Debug.Log(“SignIn is successful.”);
  }
  catch (AuthenticationException ex)
  {
    // Compare error code to AuthenticationErrorCodes
    // Notify the player with the proper error message
    Debug.LogException(ex);
  }
  catch (RequestFailedException ex)
  {
    // Compare error code to CommonErrorCodes
    // Notify the player with the proper error message
    Debug.LogException(ex);
  }
}
```

## 플레이어를 익명 로그인에서 Oculus 계정 로그인으로 업데이트##updating-a-player-from-anonymous-to-an-oculus-account

익명 인증을 설정한 후, 플레이어가 Oculus 계정을 생성하고 Oculus 계정을 통해 로그인하도록 업그레이드하려는 경우, 게임이 플레이어에게 Oculus 로그인 창을 표시하고 Oculus에서 세션 티켓을 가져와야 합니다. 그런 다음 `LinkWithOculusAsync` API를 호출해 플레이어를 Oculus 세션 티켓에 연결합니다.

SDK에 캐시된 플레이어가 존재하는 경우, 캐시된 플레이어를 Oculus 계정에 연결할 수 있습니다.

1. `SignInAnonymouslyAsync`를 사용해 캐시된 플레이어의 계정에 로그인합니다.
2. `LinkWithOculusAsync`를 사용해 캐시된 플레이어의 계정을 Oculus 계정에 연결합니다.

```cs
async Task LinkWithOculusAsync(string nonce, string userId)
{
  try
  {
    await AuthenticationService.Instance.LinkWithOculusAsync(nonce, userId);
    Debug.Log(“Link is successful.”);
  }
  catch (AuthenticationException ex) when (ex.ErrorCode == AuthenticationErrorCodes.AccountAlreadyLinked)
  {
    // Prompt the player with an error message.
    Debug.LogError(“This user is already linked with another account. Log in instead.”);
  }
  catch (Exception ex)
  {
    Debug.LogError(“Link failed.”);
    Debug.LogException(ex);
  }
}
```

## Oculus 계정 연결 해제##unlink-oculus-account

플레이어가 Oculus 계정 연결을 해제할 수 있도록 `UnlinkOculusAsync` API를 사용합니다. 연결이 해제되면 계정이 다른 ID에 연결되지 않은 경우 익명 계정으로 전환됩니다.

```cs
async Task UnlinkOculusAsync(string idToken)
{
   try
   {
       await AuthenticationService.Instance.UnlinkOculusAsync(idToken);
       Debug.Log("Unlink is successful.");
   }
   catch (AuthenticationException ex)
   {
       // Compare error code to AuthenticationErrorCodes
       // Notify the player with the proper error message
       Debug.LogException(ex);
   }
   catch (RequestFailedException ex)
   {
       // Compare error code to CommonErrorCodes
       // Notify the player with the proper error message
       Debug.LogException(ex);
   }
}
```
