홀로그램을 제자리에 유지하거나, 사용자와 함께 이동하거나, 경우에 따라 다른 홀로그램을 기준으로 배치하는 것은 Mixed Reality 애플리케이션을 만드는 데 큰 부분을 차지합니다. 이 문서에서는 World Locking Tools를 사용하는 권장 솔루션을 안내하지만 Unity 프로젝트에서 공간 앵커를 수동으로 설정하는 방법도 설명합니다. 코드를 시작하기 전에 Unity가 자체 엔진에서 좌표 공간 및 앵커를 처리하는 방법을 이해하는 것이 중요합니다.
세계 크기 조정 좌표계
오늘날 게임, 데이터 시각화 앱 또는 가상 현실 앱을 작성할 때 일반적인 방법은 다른 모든 좌표가 안정적으로 다시 매핑할 수 있는 하나의 절대 세계 좌표계 를 설정하는 것입니다. 이 환경에서는 항상 해당 세계의 두 개체 간의 관계를 정의하는 안정적인 변환을 찾을 수 있습니다. 이러한 개체를 이동하지 않은 경우 상대 변환은 항상 동일하게 유지됩니다. 이러한 종류의 전역 좌표계는 모든 기하 도형을 미리 알고 있는 순수 가상 세계를 렌더링할 때 쉽게 얻을 수 있습니다. 오늘날 방 규모 VR 앱은 일반적으로 바닥에 원점이 있는 이런 종류의 절대 방 규모 좌표계를 설정합니다.
반면, HoloLens와 같은 테더링되지 않은 혼합 현실 디바이스는 전 세계에 대한 동적 센서 기반 이해를 가지고 있으며, 건물 전체 층을 가로질러 여러 미터를 걸을 때 사용자의 주변 시간에 대한 지식을 지속적으로 조정합니다. 세계적 규모의 환경에서 모든 홀로그램을 순진한 강성 좌표계에 배치하면, 그 홀로그램은 세계를 기반으로 하거나 서로를 기준으로 시간이 지남에 따라 표류하게 됩니다.
예를 들어 헤드셋은 현재 전 세계 두 위치가 4미터 떨어져 있다고 생각한 다음 나중에 그 이해를 구체화하여 위치가 실제로 3.9미터 떨어져 있다는 것을 알게 될 수 있습니다. 그 홀로그램이 처음에 단일 강성 좌표계에서 4 미터 떨어져 배치된 경우, 그 중 하나는 항상 실제 세계에서 0.1 미터 떨어져 나타납니다.
사용자가 모바일일 때 물리적 세계에서 홀로그램의 위치를 유지하기 위해 Unity에 공간 앵커를 수동으로 배치할 수 있습니다. 그러나 이는 가상 세계 내에서 자체 일관성을 희생합니다. 서로 다른 앵커는 서로 간에 지속적으로 이동하며 전역 좌표 공간을 통해 이동합니다. 이 시나리오에서는 레이아웃과 같은 간단한 작업이 어려워집니다. 물리학 시뮬레이션도 문제가 될 수 있습니다.
WLT(World Locking Tools )는 사용자가 이동할 때 가상 장면 전체에 분산된 공간 앵커의 내부 공급을 사용하여 단일 강성 좌표계를 안정화하여 두 세계의 최고를 제공합니다. WLT는 카메라의 좌표와 모든 프레임의 공간 앵커를 분석합니다. WLT는 사용자의 머리 좌표에 있는 보정을 보정하기 위해 전 세계 모든 항목의 좌표를 변경하는 대신 머리의 좌표를 수정합니다.
프로젝트가 준비되면 Mixed Reality > World Locking Tools에서 장면 구성 유틸리티를 실행합니다.
Important
장면 구성 유틸리티는 언제든지 다시 실행할 수 있습니다. 예를 들어 AR 대상이 레거시에서 XR SDK로 변경된 경우 다시 실행해야 합니다. 장면이 이미 제대로 구성된 경우 유틸리티를 실행해도 아무 효과가 없습니다.
시각화 도우미
초기 개발 중에 시각화 도우미를 추가하면 WLT가 제대로 설정되고 작동하는지 확인하는 데 도움이 될 수 있습니다. 프로덕션 성능이 필요하거나 어떤 이유로 더 이상 필요 없게 되면 비주얼라이저 제거 유틸리티를 사용하여 제거할 수 있습니다. 비주얼라이저에 대한 자세한 내용은 도구 설명서에서 찾을 수 있습니다.
Mixed Reality OpenXR 플러그 인은 Unity의 ARFoundation ARAnchorManager 구현을 통해 기본 앵커 기능을 제공합니다. ARFoundation의 ARAnchors에 대한 기본 사항을 알아보려면 AR 앵커 관리자용 ARFoundation Manual을 방문하세요.
월드 앵커는 특정 시점에 물리적 세계에서 찾을 수 없을 수도 있습니다. 그러면 Unity는 고정된 개체의 변환을 업데이트하지 않습니다. 이 상황은 앱이 실행되는 동안에도 발생할 수 있습니다. 위치 변경 사항을 처리하지 못하면 개체가 세계의 올바른 물리적 위치에 나타나지 않습니다.
위치 변경에 대한 알림을 받습니다.
이벤트를 구독합니다 OnTrackingChanged . 이 OnTrackingChanged 이벤트는 기본 공간 앵커가 찾을 수 있거나 찾을 수 없는 상태 간에 변경될 때마다 호출됩니다.
private void Anchor_OnTrackingChanged(WorldAnchor self, bool located)
{
// This simply activates/deactivates this object and all children when tracking changes
self.gameObject.SetActiveRecursively(located);
}
앵커가 즉시 isLocated 있는 경우 앵커의 속성은 반환 시로 trueAddComponent<WorldAnchor>() 설정됩니다. 따라서 OnTrackingChanged 이벤트가 트리거되지 않습니다. 더 깨끗한 패턴은 앵커를 연결한 OnTrackingChanged 후 초기 IsLocated 상태로 처리기를 호출하는 것입니다.
공간 앵커는 애플리케이션 세션 간의 실제 공간에 홀로그램을 저장합니다. HoloLens 앵커 저장소에 저장되면 공간 앵커를 찾아 다른 세션에서 로드할 수 있으며 인터넷 연결이 없을 때 이상적인 대체 기능입니다.
Important
로컬 앵커는 디바이스에 저장되는 반면, Azure Spatial Anchors는 클라우드에 저장됩니다. 충돌 없이 동일한 프로젝트에 로컬 및 Azure 앵커를 포함할 수 있습니다. 앵커를 저장하기 위해 Azure 클라우드 서비스를 통합하는 방법에 대한 자세한 내용은 Azure Spatial Anchors를 참조 하세요.
기본적으로 World Locking Tools는 로컬 공간 앵커의 지속성을 지원하는 디바이스에서 세션 전체에서 실제 세계를 기준으로 Unity의 좌표계를 복원합니다. 애플리케이션을 종료하고 다시 실행한 후 실제 세계에서 홀로그램이 같은 위치에 표시되도록 하려면 애플리케이션이 홀로그램에 동일한 포즈를 복원하기만하면 됩니다.
애플리케이션을 더 세부적으로 제어해야 하는 경우 검사기에서 자동 저장 및 자동 로드를 사용하지 않도록 설정하고 스크립트에서 지속성을 관리할 수 있습니다. 자세한 내용은 공간 좌표계 유지를 참조 하세요.
World Locking Tools는 HoloLens 디바이스에서만 로컬 앵커 지속성을 지원합니다. Android, iOS 및 HoloLens 디바이스의 경우 Azure Spatial Anchors와 통합하여 세션 및 디바이스에서 좌표 공간의 지속성 및 공유를 지원합니다. Azure Spatial Anchors와 함께 World Locking Tools를 사용하는 자세한 내용 및 샘플은 ASA(Azure Spatial Anchors)와 결합된 WLT(World Locking Tools)를 참조하세요.
호출된 API를 XRAnchorStore 사용하면 세션 간에 앵커를 유지할 수 있습니다. 디바이스 XRAnchorStore 에 저장된 앵커의 표현입니다. Unity 장면에서 앵커를 ARAnchors 유지하거나, 스토리지에서 새 ARAnchors앵커로 앵커를 로드하거나, 스토리지에서 앵커를 삭제할 수 있습니다.
참고 항목
이러한 앵커를 저장하고 동일한 디바이스에 로드합니다. 디바이스 간 앵커는 Azure Spatial Anchors를 통해 지원됩니다.
네임스페이스
Unity 2020 및 OpenXR의 경우:
using Microsoft.MixedReality.ARSubsystems.XRAnchorStore
또는 Unity 2019/2020 + Windows XR 플러그 인:
using UnityEngine.XR.WindowsMR.XRAnchorStore
공용 메서드
{
// A list of all persisted anchors, which can be loaded.
public IReadOnlyList<string> PersistedAnchorNames { get; }
// Clear all persisted anchors
public void Clear();
// Load a single persisted anchor by name. The ARAnchorManager will create this new anchor and report it in
// the ARAnchorManager.anchorsChanged event. The TrackableId returned here is the same TrackableId the
// ARAnchor will have when it is instantiated.
public TrackableId LoadAnchor(string name);
// Attempts to persist an existing ARAnchor with the given TrackableId to the local store. Returns true if
// the storage is successful, false otherwise.
public bool TryPersistAnchor(TrackableId id, string name);
// Removes a single persisted anchor from the anchor store. This will not affect any ARAnchors in the Unity
// scene, only the anchors in storage.
public void UnpersistAnchor(string name);
}
앵커 저장소 참조 가져오기
Unity 2020 및 OpenXR을 사용하여 XRAnchorStore를 로드하려면 ARAnchorManager의 하위 시스템인 XRAnchorSubsystem에서 확장 메서드를 사용합니다.
public static Task<XRAnchorStore> LoadAnchorStoreAsync(this XRAnchorSubsystem anchorSubsystem)
Unity 2019/2020 및 Windows XR 플러그 인을 사용하여 XRAnchorStore를 로드하려면 ARReferencePointManager/ARAnchorManager의 하위 시스템인 XRReferencePointSubsystem(Unity 2019) 또는 XRAnchorSubsystem(Unity 2020)에서 확장 메서드를 사용합니다.
// Unity 2019 + Windows XR Plugin
public static Task<XRAnchorStore> TryGetAnchorStoreAsync(this XRReferencePointSubsystem anchorSubsystem);
// Unity 2020 + Windows XR Plugin
public static Task<XRAnchorStore> TryGetAnchorStoreAsync(this XRAnchorSubsystem anchorSubsystem);
앵커 저장소 로드
Unity 2020 및 OpenXR에서 앵커 저장소를 로드하려면 다음과 같이 ARAnchorManager의 하위 시스템에 액세스합니다.
WorldAnchorStore는 홀로그램이 애플리케이션 인스턴스에서 특정 실제 위치에 유지되는 홀로그램 환경을 만듭니다. 사용자는 원하는 위치에 개별 홀로그램을 고정하고 나중에 앱 세션을 통해 동일한 위치에서 찾을 수 있습니다.
이를 WorldAnchorStore 통해 세션 간에 세계 앵커의 위치를 유지할 수 있습니다. 세션 간에 홀로그램을 유지하려면 특정 월드 앵커를 사용하는 것을 별도로 추적 GameObjects 합니다. 월드 앵커를 사용하여 루트를 GameObject 만들고 로컬 위치 오프셋을 사용하여 자식 홀로그램을 고정할 수 있습니다.
이전 세션에서 홀로그램을 로드하려면 다음을 수행합니다.
를 가져옵니다 WorldAnchorStore.
세계 앵커의 ID를 제공하는 세계 앵커 앱 데이터를 로드합니다.
ID로 월드 앵커를 로드합니다.
이후 세션에 대한 홀로그램을 저장하려면 다음을 수행합니다.
를 가져옵니다 WorldAnchorStore.
ID를 지정하여 월드 앵커를 저장합니다.
ID와 함께 세계 앵커와 관련된 앱 데이터를 저장합니다.
WorldAnchorStore 가져오기
작업을 수행할 준비가 되면 알 수 있도록 참조 WorldAnchorStore를 유지합니다. 이 호출은 비동기이므로 앱이 시작되자마자 다음을 호출할 수 있습니다.
이제 특정 월드 앵커를 WorldAnchorStore저장하고 로드하는 데 사용할 수 있는 참조가 있습니다.
세계 앵커 저장
세계 앵커를 저장하려면 세계 앵커의 이름을 지정하고 이전에 얻은 위치에 전달 WorldAnchorStore 합니다. 동일한 문자열 store.Save 에 두 개의 앵커를 저장하려고 하면 false를 반환합니다. 새 저장을 저장하기 전에 이전 저장을 삭제합니다.
private void SaveGame()
{
// Save data about holograms that this world anchor positions
if (!this.savedRoot) // Only save the root once
{
this.savedRoot = this.store.Save("rootGameObject", anchor);
Assert(this.savedRoot);
}
}
월드 앵커 로드
월드 앵커를 로드하려면 다음을 수행합니다.
private void LoadGame()
{
// Saved data about holograms that this world anchor positions:
this.savedRoot = this.store.Load("rootGameObject", rootGameObject);
if (!this.savedRoot)
{
// Game root not saved. Re-place objects or start over.
}
}
이전에 저장한 앵커를 제거하고 이전에 저장된 store.Clear() 모든 데이터를 제거하는 데 사용할 store.Delete() 수도 있습니다.
기존 앵커 열거
저장된 앵커를 나열하려면 .를 호출 GetAllIds합니다.
string[] ids = this.store.GetAllIds();
for (int index = 0; index < ids.Length; index++)
{
Debug.Log(ids[index]);
}
여러 디바이스에 홀로그램 유지
Azure Spatial Anchors를 사용하여 로컬 월드 앵커에서 지속형 클라우드 앵커를 만들 수 있습니다. 디바이스가 동시에 함께 있지 않더라도 앱은 여러 HoloLens, iOS 및 Android 디바이스에서 클라우드 앵커를 찾을 수 있습니다. 클라우드 앵커는 영구적이므로 여러 디바이스는 시간에 따라 동일한 물리적 위치에서 해당 앵커를 기준으로 렌더링된 콘텐츠를 볼 수 있습니다.