지속성에 대한 유용한 정보
지속성은 기본 플랫폼에서 지원되는 경우 사용할 수 있습니다. 현재는 Unity의 기본 제공 VR 지원(레거시 XR)을 사용하는 HoloLens 디바이스 제품군으로 제한됩니다.
기본 지속성
World Locking Tools의 기본 지속성은 기본적으로 사용하도록 설정됩니다. 이는 두 가지 부분으로 제공됩니다.
여기서 관련 확인란은 "자동 로드" 및 "자동 저장"이며, 둘 다 선택되어 있습니다. 둘 다 회색으로 표시된 것을 볼 수 있습니다. 이는 "기본값 사용" 선택 항목의 일부이기 때문입니다. "기본값 사용"을 사용하지 않도록 설정하면 자동화 옵션의 임의 조합을 선택할 수 있습니다.
추가 읽기는 이러한 설정을 사용할 때와 스크립트에서 조작 시 가능합니다.
자동 저장
자동 저장 옵션은 WLT가 애플리케이션을 실행하는 동안 자주 정기적으로 상태를 저장하도록 지시합니다. 애플리케이션은 언제든지 상태 손실을 최소화하여 종료될 수 있습니다.
AutoLoad
자동 로드 옵션은 시작 시 이전에 저장된 상태를 로드하도록 WLT에 지시합니다. 이렇게 하면 애플리케이션이 마지막 세션에서 중단된 지점(w.r.t. WLT)부터 새 세션을 다시 시작할 수 있습니다.
전체 지속성
자동 저장 및 자동 로드를 모두 사용하도록 설정하면 WLT는 세션 간에 원활하게 작동합니다. 전역 공간의 위치와 방향은 첫 번째 실행 시 임의적이지만(이전 상태가 저장되어 있지 않으므로 시작 시 머리 포즈를 원점으로 사용) 후속 실행에서는 동일한 좌표 프레임을 공유합니다.
이로 인해 애플리케이션이 이전 세션의 공간과 분리된 공간에서 새 세션을 시작할 때 흥미로운 동작이 발생합니다. 자세한 내용은 아래 위치별 지속성 섹션을 참조하세요.
참고
자동 저장 및 자동 로드 설정은 전역 SpacePin에도 적용됩니다. 자세한 내용은 다음을 참조하세요.
지속성에 대한 애플리케이션 제어
기본 전체 지속성은 광범위한 애플리케이션에 적합합니다.
그러나 일부 애플리케이션은 프로세스에 대한 더 세부적인 제어가 필요할 수 있습니다.
자동 저장 및 자동 로드라는 두 가지 속성으로 WLT 자동 지속성을 사용하도록 설정하는 것이 이상해 보일 수 있습니다. 두 가지가 독립적으로 사용되는 사례를 조사하면 전체 지속성 시스템에 대한 인사이트를 파악할 수 있습니다.
자동 저장하지만 자동 로드되지 않음
이 구성을 사용하면 WLT가 주기적으로 상태를 저장하도록 설정됩니다. 그러나 시작 시 지속형 상태를 자동으로 로드하지는 않습니다.
대신 시스템이 이 디바이스에서 처음 실행되는 것처럼 새 상태로 시작됩니다. Load()에 대한 명시적 요청 후에만 이전 세션의 상태를 복원합니다.
따라서 애플리케이션은 이전 세션 상태를 복원하는 것이 적절한지 여부를 결정하고 필요한 경우 복원되는 데이터를 수정할 수도 있습니다.
일반 WLT 저장 상태는 "LocalState/frozenWorldState.hkfw" 파일에 있습니다. WLT에서 이 파일을 생성하면 애플리케이션의 재량에 따라 해당 파일이 다른 위치로 복사되고 다시 복원될 수 있습니다.
맞춤(SpacePin) 데이터에 대한 저장 파일은 기본적으로 "LocalState/Persistence/Alignment.fwb"로 설정됩니다. 그러나 맞춤 관리자의 SaveFileName을 통해 애플리케이션에서 이를 재정의할 수 있습니다.
이 구성을 사용하여 이전 세션의 상태를 로드하는 결정은 시작 시 이루어져야 합니다. 이전 세션의 저장된 상태를 실행하면 이 세션의 상태로 덮어써집니다. 보다 유연한 설정은 아래의 수동 저장 및 로드를 참조하세요.
수동 저장하지만 자동 로드
이 구성에서 WLT는 시작 시 사용 가능한 이전 세션의 모든 상태를 로드합니다. 그러나 상태를 자동으로 저장하지는 않습니다. 이렇게 하면 Save()를 호출하여 상태를 저장할 가치가 있는지 여부와 시기를 애플리케이션에서 결정할 수 있습니다.
자동 로드는 시작 시 사용 가능한 상태를 로드만 하도록 WLT에 지시합니다. 애플리케이션은 Load()에 대한 명시적 호출을 사용하여 언제든지 저장된 상태를 자유롭게 복원할 수 있습니다.
수동 저장 및 로드
애플리케이션은 저장 및 로드 프로세스를 완전히 제어하도록 선택할 수 있습니다.
그러면 상태는 애플리케이션에서 Save()에 대한 명시적 호출이 있을 경우에만 저장되고 Load()에 대한 명시적 호출이 있을 경우에만 로드됩니다.
Load() 호출에 의해 로드된 상태는 이 세션의 앞부분 또는 이전 세션에서 저장되었을 수 있습니다.
지속성 사용 안 함
위에서 설명한 대로 지속성은 항상 스크립트에서 애플리케이션에서 사용할 수 있습니다. 스크립트 또는 검사기의 WorldLockingContext를 통해 자동화된 지속성을 사용하도록 설정하고 사용하지 않도록 설정할 수 있습니다. 자동화된 지속성을 사용하지 않도록 설정하면 WLT는 애플리케이션의 명시적 요청 없이 상태를 저장하거나 로드하려고 시도하지 않습니다.
물론 AutoLoad 지시문은 시작 시 로드 여부에만 영향을 주므로 시작 후 스크립트에서 값을 변경해도 아무 효과가 없습니다.
개발 중 주의 사항
위에서 설명한 것처럼 전역 WLT 및 맞춤에 대한 저장 파일의 위치는 애플리케이션에 대해 전역입니다. 특히 SpacePin이라고도 하는 맞춤 노드는 이름으로 유지됩니다(아래 참조). 애플리케이션이 한 장면의 SpacePin 집합으로 상태를 저장한 다음, 다른 장면의 SpacePin 집합으로 상태를 로드하고, 두 SpacePin 집합이 공통 이름을 공유하는 경우의 동작은 정의되지 않습니다.
이 문제를 해결하는 방법은 여러 가지가 있습니다. 가능하면 프로젝트 내에서 SpacePin 이름을 다시 사용하지 않는 것이 가장 좋습니다. 다시 배포한 후 예기치 않은 장면 슬라이딩 동작이 표시되면 WLT 저장 상태를 삭제해 보세요. 마찬가지로, 애플리케이션을 근본적으로 변경할 때 조심성이 많은 분들은 WLT 저장 파일을 디바이스에서 삭제하거나 새 버전을 설치하기 전에 애플리케이션을 제거하는 것이 좋을 수 있습니다.
위치별 지속성
시나리오
여러 물리적 위치에서 실행되는 흥미로운 애플리케이션 클래스가 있습니다. 애플리케이션이 방 A에서 실행되고, 디바이스가 닫히고, 재배치된 다음, 방 B에서 애플리케이션이 다시 시작될 수 있습니다. 방 B는 방 A에서 복도를 따라가면 있거나 다른 대륙에 있을 수 있습니다. 애플리케이션과 디바이스는 알 방법이 없습니다.
간단히, 애플리케이션이 수동 WLT 지속성을 위해 구성되어 있다고 가정해 보겠습니다.
연습
연결되지 않은 방 A와 B를 고려해 보세요.
애플리케이션은 방 A에서 시작되었습니다. 방 안에 연속된 고정 좌표 공간을 설정하면 전체 방이 조각 1에 매핑됩니다. 영구 홀로그램 개체 X가 방에 배치됩니다. 그런 다음, 애플리케이션이 상태를 저장하고 종료됩니다.
디바이스 전원이 꺼지고, 방 B로 이동되고, 다시 시작됩니다.
디바이스는 이를 방 A가 아닌 것으로 인식하므로 WLT는 ID == 29와 같은 새 조각 ID를 해당 콘텐츠에 할당합니다. 왜 29일까요? 1이 아니기 때문입니다. 조각 ID는 임의의 값입니다. 단, 한 조각의 ID는 FragmentId.Invalid 또는 FragmentId.Unknown이 아니거나 알려진 다른 조각과 동일하지 않습니다.
이제 두 조각이 있으며 병합할 방법이 없습니다(상대 위치에서 사용할 수 있는 정보가 없으므로).
관심 있는 애플리케이션 개발자가 이렇게 질문할 수 있습니다. 방 A에 영구 개체 X를 배치했는데, 방 B에서 애플리케이션이 시작될 때 개체 X가 로드되면 어떻게 되나요?
정답은 동작은 애플리케이션 개발자가 결정해야 할 일로 남아 있다는 것입니다. 현재 조각 ID는 개체 X가 방 A에 배치된 경우에 사용할 수 있고 유지할 수 있습니다. 그러면 애플리케이션에서 시작 시 현재 조각이 생성되었을 때와 같은지 여부에 따라 개체 X를 표시할지 여부를 결정할 수 있습니다.
여기서 개발자는 현재 조각 ID가 하나인 경우에만 개체 X가 로드되고, 현재 조각이 29인 경우에만 방 B의 개체 Y가 로드되도록 결정합니다.
공간과 연결된 조각 ID의 지속성은 World Locking Tools의 지속성의 일부로 저장됩니다. 그러나 개체와 연결된 조각 ID의 지속성과 이를 기반으로 수행할 작업은 애플리케이션의 몫입니다.
개체의 연결된 조각 ID와 함께 전역 공간에서 해당 Pose를 저장할 수 있습니다. 그런 다음, 조각 ID가 일치하면 개체가 로드된 후 해당 Pose를 복원하여 마지막 세션 동안 물리적 세계의 해당 위치로 되돌릴 수 있습니다. World Locking Tools 지속성을 사용하면 Pose가 주위의 물리적 세계 피쳐를 기준으로 세션 전체에서 고정된 상태로 유지됩니다.
SpacePin의 지속성
SpacePin은 AlignmentAnchor의 애플리케이션 쪽 래퍼로 간주할 수 있습니다. SpacePin(및 파생 클래스)은 Unity 구성 요소인 반면, AlignmentAnchor는 전적으로 개념적입니다. AlignmentAnchor에 해당하는 클래스 또는 형식은 없습니다. 따라서 여기서는 SpacePin 및 AlignmentAnchor가 같은 의미로 사용됩니다(일반적으로 SpacePin 선호).
그런데 SpacePin을 모르면 AlignmentManager가 SpacePin을 지속할 수 있으므로 혼동의 여지가 있습니다. AlignmentManager는 SpacePin의 본질을 구현하는 AlignmentAnchor를 관리하며, 이를 통해 SpacePin을 재구성할 수 있기 때문입니다.
SpacePin은 다른 World Locking Tools보다 애플리케이션 입력에 의해 본질적으로 더 많이 구동되기 때문에 일반적인 WLT 지속성 시스템보다 SpacePin의 지속성에 대한 애플리케이션 수준의 컨트롤이 더 많습니다.
SpacePin(및 AlignmentAnchor)은 이름으로 지속된다는 점을 기억해야 합니다. 이는 동일한 IAlignmentManager에 있는 두 개의 활성 SpacePin이 동일한 이름을 갖지 않는다는 일반적인 요구 사항보다 약간 더 강력한 요구 사항입니다. SpacePin을 지속하는 경우 활성 여부에 관계없이 동일한 데이터베이스에 있는 두 개의 SpacePin이 동일한 이름을 가질 수 없습니다.
맞춤 관리자 데이터베이스
각 IAlignmentManager에는 RestoreAlignmentAnchor(문자열 uniqueName, Pose virtualPose)의 구현에 암시된 대로 SpacePin 데이터베이스가 이름별로 있습니다.
전역 맞춤 데이터베이스
WorldLockingManager.GetInstance()가 소유하는 하나의 전역 IAlignmentManager가 있습니다. 설명한 대로, 기본 저장 파일 위치는 SaveFileName 속성에 의해 결정됩니다. SaveFileName은 인터페이스 IAlignmentManager가 아닌 AlignmentManager 클래스의 속성입니다. IAlignmentManager 구현은 파일 또는 파일 이름의 개념 없이 지속성을 구현할 수 있습니다. SaveFileName은 AlignmentManager가 지속성을 구현하는 방식의 아티팩트이므로 AlignmentManager로 제한됩니다.
로컬 맞춤 데이터베이스
AlignSubtree.alignmentManager 필드로 표시되는 각 AlignSubtree마다 하나씩 임의의 수의 하위 공간 맞춤 관리자가 있을 수 있습니다. 또한 애플리케이션은 자체 AlignmentManager 인스턴스 또는 IAlignmentManager에서 파생된 자체 클래스를 만들 수 있습니다.
각 AlignSubtree 구성 요소의 AlignmentManager에는 고유한 저장 파일 위치가 있으며 이는 기본적으로 GameObject의 이름(확장명 ".fwb")으로 설정됩니다. 예를 들어 AlignSubtree 구성 요소가 "MyRoot"라는 GameObject에 있는 경우 저장 파일의 이름은 "MyRoot.fwb"입니다. 슬래시 '/'를 사용하여 하위 폴더에 배치할 수 있습니다. 두 AlignSubtree 구성 요소가 동일한 저장 파일 위치를 사용하는 것은 좋지 않을 수 있습니다.
하지만 사실은
장기적으로 볼 때, 더 가벼운 로컬 고유 요구 사항을 관리하는 것보다 SpacePin/AlignmentAnchor에 전역적으로 고유한 이름을 지정하는 것이 더 간단하고 강력하므로 매우 권장됩니다. 하지만 원하는 대로 하세요.