アプリにサブスペースを追加する

対象の XR デバイス
このガイダンスは、このようなタイプの XR デバイス向けのエクスペリエンスを構築する際に役立ちます。
XR ヘッドセット
有線 XR グラス

サブスペースは、アプリ内の 3D 空間を区切ったパーティションです。これにより、3D モデルの配置、3D レイアウトの構築、2D コンテンツへの奥行き追加ができるようになります。サブスペースは、空間化が有効になっている場合にのみレンダリングされます。ホーム スペースまたは非 XR デバイスでは、そのサブスペース内のコードは無視されます。

SpatialPanelSpatialRowSpatialColumn などのサブスペース コンポーザブルを使用して、レイアウトを作成し、3D 空間に 2D コンテンツを配置できます。3D コンテンツを配置するには、3D モデルの場合は SceneCoreEntity、ステレオ画像の場合は SpatialExternalSurface など、適切な Subspace コンポーザブルを使用します。OrbiterSpatialDialog などの一部の XR コンポーネントは、2D UI 階層のどこでも使用できる標準の 2D コンポーザブルですが、SubspaceComposable はアプリのサブスペースで呼び出す必要があります。これを行うには、Subspace サブスペース コンポーザブルを使用します。

サブスペース階層について

最上位の Subspace は、アプリによって呼び出される最も外側のサブスペースです。Subspace の呼び出しごとに、新しい独立した空間 UI 階層が作成されます。ネストされている親 Subspace の空間位置、向き、スケールは継承されません。

SpatialPanelOrbiterSpatialPopup などのコンポーネント内に埋め込みまたはネストされた Subspace を作成するには、PlanarEmbeddedSubspace を使用します。

PlanarEmbeddedSubspaceSubspace には、次の 2 つの主な違いがあります。

  • それらは、呼び出された 2D レイアウトに参加します。つまり、サブスペースの高さと幅は、その 2D 親レイアウトの高さと幅によって制約されます。
  • 呼び出されたエンティティの子として動作します。つまり、SpatialPanel 内にネストされたサブスペース コンポーザブルを呼び出すと、そのサブスペースは呼び出し元の SpatialPanel の子になります。

PlanarEmbeddedSubspace のこれらの動作により、次のような機能が実現します。

  • 親エンティティとともに子を移動する
  • オフセット SubspaceModifier を使用して子の位置をオフセットする
  • 2D UI の上に浮かび、2D レイアウトの適切なスペースの高さと幅に一致する 3D オブジェクトを表示する

サブスペースのレイアウトを調整する

Android XR では、アプリのレイアウトはデフォルトでフルスペース モードの SubspaceVolumeConstraints にバインドされます。そのため、ユーザーが利用できる表示スペースの量を考慮し、それに応じてレイアウトを調整する必要があります。recommendedContentBoxInFullSpace は、ActivitySpace 内の境界ボックスの具体的な寸法を提供し、コンテンツをユーザーの視野内に配置できるようにします。

アプリの主要コンテンツはこのボックス内に収まるようにしてください。推奨される境界を超えるコンテンツがある場合は、ユーザーが頭を動かして空間を探索するようなレイアウトを検討してください。recommendedContentBoxInFullSpace のデフォルトの制約は、SubspaceModifier.requiredSizeIn などのカスタム サイズベースの修飾子を適用することでオーバーライドできます。無制限の動作の場合は、allowUnboundedSubspace = true を設定します。

必要に応じて、現在の Session を使用して 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 の完全なリファレンス ドキュメントをご覧ください。