Back to Blog

Vision Pro Unity 빠른 시작 가이드 (아고라 SDK 포함)

새로운 Apple Vision Pro 헤드셋은 개인용 컴퓨팅과 엔터테인먼트의 새로운 기준을 제시합니다. Apple의 원생 SwiftUI 프레임워크나 Unity 엔진을 활용해 몰입형 애플리케이션을 개발할 수 있는 기능을 통해 가능성의 한계가 무한해집니다.

FaceTime의 SharePlay 기능이 포함되어 동일한 애플리케이션 내에서 애플 기기 간 원활한 비디오 채팅이 가능합니다. 하지만 다른 플랫폼 사용자는 어떻게 될까요? 바로 여기서 Agora RTC SDK가 등장합니다. 이 SDK는 Vision Pro 헤드셋에서 크로스 플랫폼 비디오 채팅을 가능하게 하는 솔루션을 제공합니다. 이 기사에서는 Vision Pro 헤드셋용 Unity 애플리케이션에 크로스 플랫폼 비디오 채팅을 구현하는 과정을 자세히 살펴봅니다.

필수 조건

  • 실리콘 CPU(M1 이상)를 탑재한 Mac 컴퓨터
  • Xcode
  • Apple 개발자 멤버십
  • Unity 2022.3 LTS
  • Unity 개발자 라이선스 — Pro/Plus/Enterprise
  • Agora 개발자 계정
  • visionOS 플러그인을 포함한 Agora Video SDK

파트 1: 프로젝트 설정

3D URP 템플릿을 사용해 Unity 프로젝트를 생성합니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

프로젝트가 준비되면 visionOS 빌드 설정으로 전환합니다. 실제 Vision Pro 기기에 배포하기 전에 시뮬레이터에서 테스트할 예정이므로, 대상 SDK로 시뮬레이터 SDK를 선택합니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

패키지 관리자를 열고 다음 패키지를 이름으로 추가하세요:

  • com.unity.xr.visionos
  • com.unity.polyspatial
  • com.unity.polyspatial.visionos
  • com.unity.polyspatial.xr

아고라 Video SDK를 다운로드합니다. 현재 작성 시점에는 예비 버전에만 접근 가능합니다. 공식 버전이 출시되면 이 문서에 적절한 다운로드 위치를 업데이트하겠습니다.

Unity 에디터에서 Assets > Import Package > Custom Package로 이동하여 다운로드한 Unity 패키지를 선택하여 패키지를 임포트합니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

카메라와 마이크에 접근할 예정이므로 사용 목적 설명을 입력해 주세요. 또한 SDK가 안전하지 않은 포인터를 지원하기 때문에 “안전하지 않은” 코드 실행을 허용해 주세요.

Vision Pro Unity Quickstart with Agora SDK screenshot

Apple visionOS가 XR 플러그인 관리에 선택되어 있는지 확인하세요. 월드 센싱 사용에 대한 설명도 제공하세요. 손 추적을 사용할 경우, 추가로 다른 사용 설명을 제공할 수 있습니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

마지막으로, 앱에 회사 이름을 입력하는 것이 일반적인 관행입니다.

파트 2: 장면 생성

이 데모 프로젝트는 이 GitHub 위치에서 찾을 수 있습니다. 다음 섹션에서는 데모를 만드는 자세한 단계를 설명합니다.

혼합 현실 경험을 만들기 위해서는 Unity의 PolySpatial 패키지가 필요합니다. 해당 기능이 활성화되어 있는지 확인하세요.

Vision Pro Unity Quickstart with Agora SDK screenshot

볼륨 카메라가 자동으로 생성되지 않은 경우, 계층 창에서 + 버튼을 클릭하고 XR > 설정 > 볼륨 카메라를 선택하여 추가할 수 있습니다. 이 카메라는 필수 메인 카메라를 대체하지 않습니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

다음으로 XR > AR Session을 선택하여 AR Session 객체를 장면에 추가합니다. 그런 다음 Volume을 클릭하고 Global Volume을 선택합니다.

선택 사항: Cube라는 이름의 3D 객체 큐브를 생성하고 다음 변환 속성을 적용합니다. 이 최소 데모에는 다른 UI가 없기 때문에 이 큐브는 VisionPro 장치에서 Unity 애플리케이션이 정상적으로 실행되고 있음을 나타내는 참조 객체로 사용됩니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

선택 사항: 정육면체의 외관을 더 흥미롭게 만들기 위해 다음과 같은 스크립트로 계속 회전시켜 주세요:

public class SelfRotate : MonoBehaviour
{
   void Update()
   {
     // Rotate the object around its local Y axis at 10 degree per second
     transform.Rotate(10 * Vector3.up * Time.deltaTime);
   }
}

마지막으로 GameObject를 생성하고 이름을 AgoraManager로 지정합니다. 이 객체는 Part 3에서 구현할 Agora 논리를 위한 컨트롤러 스크립트를 호스팅할 것입니다.

체크포인트 1

완성된 장면은 다음과 같이 보일 것입니다:

Vision Pro Unity Quickstart with Agora SDK screenshot

제3부: AgoraVPManager 설계

AgoraVPManager는 SDK API 예제에서 찾을 수 있는 설계 패턴을 따릅니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

AgoraVPManager 클래스는 RTCEngine의 인스턴스를 사용하여 비디오 채팅 세션을 실행하는 API를 호출합니다. ViewObjects 사전은 뷰 객체에 대한 참조를 유지합니다. Agora 엔진 세션의 라이프사이클은 MonoBehavior의 라이프사이클 메서드 Start, Update 및 OnDestroy에서 각각 처리됩니다. 최상위 클래스는 콜백 이벤트를 처리하기 위해 내부 클래스 UserEventHandler를 사용합니다.

AgoraVPManager 스크립트는 SerializedFields를 사용하여 개발자가 애플리케이션 인증(예: App ID), 사용자 토큰 및 채널 이름과 같은 필요한 자격 증명을 입력할 수 있도록 합니다.

#region EDITOR INPUTS
 [Header(“_____________Basic Configuration_____________”)]
 [FormerlySerializedAs(“APP_ID”)]
 [SerializeField]
 protected string _appID = “”; 
 [FormerlySerializedAs(“TOKEN”)]
 [SerializeField]
 protected string _token = “”;
 [FormerlySerializedAs(“CHANNEL_NAME”)]
 [SerializeField]
 protected string _channelName = “”;
 [SerializeField]
 internal GameObject ViewContainerPrefab;
 [SerializeField]
 GameObject TargetObject; // to be looked at
#endregion

편집자 입력

다음 스크린샷은 Unity 에디터에서 AgoraManager의 구성 요소 인스펙터 뷰를 보여줍니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

AppID 및 토큰

Unity 에디터에서 Agora 개발자 계정에서 생성한 App ID를 입력합니다. 생산 환경에서는 인증을 위해 토큰을 사용해야 합니다. 그러나 이 프로젝트에서는 App ID만 사용하는 것이 더 편리합니다.

채널 이름

응용 프로그램이 동일한 App ID와 채널 이름을 사용하면 서로 다른 플랫폼에서 두 사용자가 서로 통신할 수 있습니다. 예를 들어, Vision Pro Unity 사용자는 데스크톱 웹 브라우저의 사용자와 대화할 수 있습니다. 테스트를 위해 “visionpro”를 사용할 것입니다.

뷰 컨테이너 프리팹

이 객체는 비디오 스트림을 렌더링합니다. Unity 3D 객체 템플릿에서 큐브를 사용합니다. 큐브를 생성하고 파일 패널로 드래그합니다. 프리팹 이름으로 MyCube로 지정합니다. MyCube를 에디터 필드로 드래그합니다.

대상 오브젝트

뷰 오브젝트가 이 트랜스폼을 향하도록 설정합니다. 참조로 볼륨 카메라를 사용합니다.

시작

UI 입력 관리의 복잡성을 추가하지 않고, 애플리케이션은 Start() 시 자동으로 비디오 채팅 세션을 시작합니다. 다음 세 단계를 순서대로 수행합니다:

  • InitEngine();
  • SetBasicConfiguration();
  • JoinChannel();

InitEngine

InitEngine 메서드는 Agora RTC 엔진 인스턴스를 생성하고 사용자 핸들러 및 엔진을 프로필과 함께 초기화합니다.

현재 RTC 기능을 정상적으로 작동시키려면 CHANNEL_PROFILE_LIVE_BROADCASTING 및 AUDIO_SCENARIO_GAME_STREAMING 프로필 옵션을 반드시 사용해야 합니다.

protected virtual void InitEngine()
{
  RtcEngine = Agora.Rtc.RtcEngine.CreateAgoraRtcEngine();
  UserEventHandler handler = new UserEventHandler(this);
  RtcEngineContext context = new RtcEngineContext(_appID, 0,
    CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING,
    AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_GAME_STREAMING,
    AREA_CODE.AREA_CODE_GLOB);
  RtcEngine.Initialize(context);
  RtcEngine.InitEventHandler(handler);
}

기본 구성 설정

라이브 스트리밍 RTC 모드를 사용할 예정이므로, 이 설정에서 각 클라이언트를 방송자로 설정합니다. 또한 visionOS에서 오디오 스트림이 정상적으로 작동하도록 하는 특수 옵션을 활성화합니다.

protected virtual void SetBasicConfiguration()
{
  RtcEngine.EnableAudio();
  RtcEngine.EnableVideo();
  VideoEncoderConfiguration config = new VideoEncoderConfiguration();
  config.dimensions = new VideoDimensions(640, 360);
  config.frameRate = 15;
  config.bitrate = 0;
  RtcEngine.SetVideoEncoderConfiguration(config);
  RtcEngine.SetChannelProfile(CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING);
  RtcEngine.SetClientRole(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER);// For now this private API is needed to make voice chat working
  if (Application.platform == RuntimePlatform.VisionOS)
  {
    RtcEngine.SetParameters(“che.audio.restartWhenInterrupted”, true);
  }
}

채널 가입

채널에 가입할 때 가장 간단한 방법을 사용하며, 고객 사용자 ID(uid)와 미디어 옵션을 생략합니다.

RtcEngine.JoinChannel(_token, _channelName);

The complete function signature:

int JoinChannel(string token, string channelId, uint uid,
 ChannelMediaOptions options);


채널 미디어 옵션을 사용하여 동영상 또는 오디오 스트림을 게시하지 않고 채널을 설정할 수 있습니다.

OnDestroy

세션이 종료될 때 리소스를 Properly 정리하려면 RTC 엔진의 dispose 메서드를 호출해야 합니다.

private void OnDestroy()
{
  if (RtcEngine == null) return; 
  RtcEngine.InitEventHandler(null);
  RtcEngine.LeaveChannel();
  RtcEngine.Dispose();
}

업데이트

이 디자인에서 비디오 디스플레이 뷰는 지정된 위치에 표시됩니다. 카메라(TargetObject로 설정됨)는 참조 객체로 사용됩니다.

private void Update()
{
  foreach(var ob in ViewObjects.Values) {
    ob.transform.LookAt(TargetObject.transform);
  }
}

UserEventHandler

내부 클래스 UserEventHandler는 Agora RTC 엔진 이벤트에 응답하기 위한 일련의 핸들러 메서드를 포함합니다. 이벤트의 전체 목록은 인터페이스 IRtcEngineEventHandler에 정의되어 있습니다. 여기서는 가장 중요한 네 가지 이벤트에만 초점을 맞춥니다:

  • OnError
  • OnJoinChannelSuccess
  • OnUserJoined
  • OnUserOffline

OnError가 처리해야 할 내용은 간단합니다. 나머지 세 가지에 대해 논의하겠습니다.

OnJoinChannelSuccess

로컬 사용자가 채널에 성공적으로 가입한 후, 콜백에 RtcConnection 참조가 제공됩니다. RtcConnection에는 UID와 채널 이름이 포함됩니다. 이전에는 기본값 0을 사용하여 채널에 가입했습니다. 백엔드 시스템은 사용자를 식별하기 위해 고유한 UID를 생성합니다. 지정된 UID를 사용하여 가입한 경우, 이 콜백에는 응답을 위해 동일한 UID가 포함됩니다. 이 구현에서는 사용자의 비디오 스트림을 렌더링하기 위한 뷰를 생성하는 유틸리티 함수를 사용합니다. 로컬 사용자의 경우 실제 UID 대신 항상 0을 사용해야 스트림을 렌더링할 수 있습니다.

public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed)
{
  Vector3 pos = new Vector3(-2.5f, 0, 3.28f);
  CreateUserView(0, connection.channelId, pos);
}

OnUserJoined

OnJoinChannelSuccess와 유사하게, OnUserJoined는 원격 사용자의 채널 가입 이벤트를 나타냅니다. 우리는 렌더링된 뷰 변환 사이에 간격을 두고 사용자를 하나씩 수평으로 추가합니다.

public override void OnUserJoined(RtcConnection connection, uint uid, int elapsed)
{
  var count = _app.transform.childCount;
  Vector3 pos = new Vector3(count * 1.5f, 0, 3.28f);
  CreateUserView(uid, connection.channelId, pos);
}

사용자 오프라인 상태

원격 사용자가 오프라인 상태가 되면 해당 사용자의 뷰를 디스플레이에서 제거하고 참조 기록을 정리합니다.

public override void OnUserOffline(RtcConnection connection, uint uid, USER_OFFLINE_REASON_TYPE reason)
{
  if (_app.ViewObjects.ContainsKey(uid)) _app.ViewObjects.Remove(uid);
  AgoraViewUtils.DestroyVideoView(uid);
}

뷰 생성

CreateUserView 함수는 유틸리티 함수 AgoraViewUtils.MakeVideoView()를 호출하여 렌더링 뷰 객체를 획득하고 변환 계층 구조 아래에 배치합니다. 이는 완전히 UI/UX 디자인에 달려 있습니다. 따라서 CreateUserView는 오버라이드될 수 있도록 가상 함수로 선언됩니다. 여기서 더 중요한 논의 사항은 AgoraViewUtils.MakeVideoView()에서 표시할 텍스처 데이터를 수집하기 위해 SDK에서 제공하는 VideoSurface 클래스의 사용입니다. AgoraViewUtils는 여러 렌더링 대상 옵션을 제공합니다: RawImage, Plane 또는 MeshRender를 가진 프리팹. 우리는 렌더링을 위해 Unity 3D 템플릿에서 가져온 정육면체를 사용합니다. 이 함수는 최종적으로 MakeCustomMesh를 호출합니다.

private static VideoSurface MakeCustomMesh(string goName, GameObject prefab)
{
  var go = GameObject.Instantiate(prefab);
  // configure videoSurface
  var videoSurface = go.AddComponent<VideoSurface>();
  go.transform.Rotate(-90.0f, 0.0f, 0.0f);
  return videoSurface;
}

체크포인트 2

Vision Pro 기기에서 간단한 RTC 앱의 구현이 완료되었습니다. Unity 에디터에서 애플리케이션을 실행할 수 있습니다. 참조 큐브의 왼쪽에 자신의 웹캠 영상이 표시되어야 합니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

제4부: 테스트

Vision Pro 시뮬레이터

제1부에서 시뮬레이터용 타겟 SDK를 설정했음을 기억하십시오. Unity 프로젝트를 빌드하여 Xcode 프로젝트를 얻습니다. 그런 다음 Xcode 프로젝트를 빌드합니다.

SDK만 미리보기

Xcode에 중복 심볼 오류가 긴 목록으로 표시된다면, 이는 시뮬레이터 빌드에 추가된 타겟 때문일 수 있습니다. Xcode 프로젝트에서 ARM64 프레임워크를 제거하십시오.

Vision Pro Unity Quickstart with Agora SDK screenshot

시뮬레이터 테스트

Vision Pro 시뮬레이터에서 애플리케이션을 빌드하고 실행합니다. 웹 브라우저를 열고 Agora WebDemo 페이지로 이동합니다. 테스트를 위해 앱 ID와 채널 이름을 입력합니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

Vision Pro 앱이 시뮬레이터에서 성공적으로 실행되면 다음과 같은 화면이 표시됩니다. 시뮬레이터 환경에서는 Vision Pro에 카메라 캡처 기능이 없기 때문에, 왼쪽에 로컬 사용자의 디스플레이를 표시하기 위해 설정된 빈 사각형 상자가 표시됩니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

장치 테스트

대상 SDK를 장치 SDK로 변경하고 Unity 프로젝트를 다시 빌드합니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

Xcode에서 애플리케이션을 빌드하고 Vision Pro 기기에 배포합니다.

Vision Pro Unity Quickstart with Agora SDK screenshot

RTC 비디오 채팅에서 현지 사용자(귀하의 페르소나)와 원격 사용자를 모두 볼 수 있어야 합니다!

RTE Telehealth 2023
Join us for RTE Telehealth - a virtual webinar where we’ll explore how AI and AR/VR technologies are shaping the future of healthcare delivery.

Learn more about Agora's video and voice solutions

Ready to chat through your real-time video and voice needs? We're here to help! Current Twilio customers get up to 2 months FREE.

Complete the form, and one of our experts will be in touch.

Try Agora for Free

Sign up and start building! You don’t pay until you scale.
Try for Free