앱에 하위 공간 추가

해당 XR 기기
이 안내는 이러한 유형의 XR 기기용 환경을 구축하는 데 도움이 됩니다.
XR 헤드셋
유선 XR 안경

하위 공간은 앱 내의 3D 공간 파티션으로, 여기에서 3D 모델을 배치하고 3D 레이아웃을 빌드하고 2D 콘텐츠에 깊이를 더할 수 있습니다. 하위 공간은 공간화가 사용 설정된 경우에만 렌더링됩니다. 홈 스페이스 또는 XR이 아닌 기기에서는 해당 하위 스페이스 내의 코드가 무시됩니다.

SpatialPanel, SpatialRow, SpatialColumn과 같은 하위 공간 컴포저블을 사용하여 레이아웃을 만들고 3D 공간에 2D 콘텐츠를 배치할 수 있습니다. 3D 콘텐츠를 배치하려면 3D 모델의 경우 SceneCoreEntity, 스테레오 이미지의 경우 SpatialExternalSurface과 같은 적절한 하위 공간 컴포저블을 사용하세요. Orbiter 또는 SpatialDialog과 같은 일부 XR 구성요소는 2D UI 계층 구조의 어디에서나 사용할 수 있는 표준 2D 컴포저블이지만 SubspaceComposable은 앱의 하위 공간에서 호출해야 합니다. 이렇게 하려면 Subspace 하위 공간 컴포저블을 사용합니다.

하위 스페이스 계층 구조 정보

최상위 Subspace는 앱에서 호출하는 가장 바깥쪽 하위 공간입니다. Subspace에 대한 각 호출은 새 독립형 공간 UI 계층 구조를 만듭니다. 중첩된 상위 Subspace의 공간 위치, 방향 또는 크기를 상속하지 않습니다.

SpatialPanel, Orbiter, SpatialPopup 또는 기타 구성요소 내에 삽입되거나 중첩된 Subspace를 만들려면 PlanarEmbeddedSubspace를 사용하세요.

PlanarEmbeddedSubspaceSubspace과 다음과 같은 두 가지 주요 차이점이 있습니다.

  • 이러한 요소는 호출되는 2D 레이아웃에 참여합니다. 즉, 하위 공간의 높이와 너비는 2D 상위 레이아웃의 높이와 너비에 의해 제한됩니다.
  • 호출된 엔티티의 하위 요소로 작동합니다. 즉, SpatialPanel 내에 중첩된 하위 공간 컴포저블을 호출하면 해당 하위 공간은 호출된 SpatialPanel의 하위 공간이 됩니다.

PlanarEmbeddedSubspace의 이러한 동작은 다음과 같은 기능을 지원합니다.

  • 상위 항목과 함께 하위 항목 이동
  • 오프셋 SubspaceModifier을 사용하여 하위 요소의 위치 오프셋
  • 2D UI 위에 떠 있고 2D 레이아웃의 적절한 공간 높이와 너비에 일치하는 3D 객체 표시

하위 공간에 맞게 레이아웃 조정

Android XR에서 앱의 레이아웃은 기본적으로 전체 공간 모드의 SubspaceVolumeConstraints에 바인딩됩니다. 따라서 사용자에게 제공되는 표시 공간의 양을 고려하고 이에 따라 레이아웃을 조정해야 합니다. recommendedContentBoxInFullSpace는 콘텐츠가 사용자의 시야 내에 배치될 수 있도록 ActivitySpace 내의 경계 상자에 대한 구체적인 크기를 제공합니다.

앱의 기본 콘텐츠는 이 상자 안에 있어야 합니다. 권장 경계를 초과해야 하는 콘텐츠가 있는 경우 사용자가 머리를 움직여 공간을 탐색하도록 유도하는 레이아웃을 고려하세요. recommendedContentBoxInFullSpace의 기본 제약 조건은 SubspaceModifier.requiredSizeIn와 같은 맞춤 크기 기반 수정자를 적용하여 재정의할 수 있습니다. 무한 동작의 경우 allowUnboundedSubspace = true를 설정합니다.

필요에 따라 현재 세션을 사용하여 recommendedContentBoxInFullSpace를 호출하여 이러한 특정 측정기준을 가져옵니다. 아래 예를 참고하세요.

val session = LocalSession.current
session?.scene?.activitySpace?.recommendedContentBoxInFullSpace

앱에 하위 공간 추가

다음 코드 예는 앱에 SubspacePlanarEmbeddedSubspace을 추가하는 방법을 보여줍니다.

setContent {
    // This is a top-level subspace
    Subspace {
        SpatialPanel {
            MyComposable()
        }
    }
}

@Composable
private fun MyComposable() {
    Row {
        PrimaryPane()
        SecondaryPane()
    }
}

@Composable
private fun PrimaryPane() {
    // This is an embedded subspace, because PrimaryPane is in a SpatialPanel
    // and that SpatialPanel is in the top-level Subspace
    PlanarEmbeddedSubspace {
        SpatialPanel {}
    }
}

자세한 내용은 SubspacePlanarEmbeddedSubspace에 관한 전체 참조 문서를 확인하세요.