XR で Android アプリを 3D にする

2D モバイルアプリまたは大画面 Android アプリは、デフォルトで Android XR で動作し、3D 空間内の 2D パネルとして表示されます。没入型の XR 機能を追加して、既存の 2D Android アプリを拡張し、フラット スクリーン エクスペリエンスから動的 3D 環境に移行できます。

Android アプリを XR に移行する際は、次の重要な原則を考慮してください。

  • 空間機能: Android XR には、アプリで利用できるさまざまな空間機能が用意されていますが、すべての機能を実装する必要はありません。アプリの視覚的な階層、レイアウト、ユーザー ジャーニーを補完するアニメーションを戦略的に実装します。カスタム環境と複数のパネルを組み込んで、没入感のあるエクスペリエンスを作成することを検討してください。空間要素の最適な統合を決定するには、空間 UI 設計ガイダンスをご覧ください。
  • アダプティブ UI: XR では、無限のキャンバスと自由にサイズ変更可能なウィンドウにシームレスに適応する広々とした UI を柔軟に設計できます。最も重要な考慮事項の一つは、大画面設計ガイダンスを使用して、この広大な環境に合わせてアプリのレイアウトを最適化することです。アプリが現在モバイル専用の場合でも、魅力的な環境を利用してユーザー エクスペリエンスを向上させることができますが、大画面向けに最適化された UI は、Android XR 向けにアプリを最適化する最善の方法の一つです。
  • UI フレームワーク: XR 用 Jetpack Compose を使用して UI を構築することをおすすめします。アプリで現在ビューを使用している場合は、XR でのビューの使用で、ビューの操作時に Compose の相互運用性を活用する方法を確認するか、Jetpack SceneCore ライブラリを直接使用することを検討してください。
  • Google Play ストアでの公開: XR 拡張アプリが Google Play ストアで見つけやすくするには、次の手順を行います。
    • 不要な機能要件を削除して、アプリを効率化することを検討してください。
    • アプリが Google Play ストアの検索結果から除外されないように、Google Play Console でアプリの XR 公開がオプトアウトされていないことを確認します。
<uses-sdk tools:overrideLibrary="androidx.xr.scenecore, androidx.xr.compose"/>

2D UI コンポーネントを 3D に変換する際のヒント

これらのヒントを参考にすることで、アプリが XR 向けに最適化されているように感じられるようになります。

  • 大画面の互換性を優先する: アプリの UI が大画面の設計原則に準拠していることを確認して、広大な XR 環境でテキストとコンテンツを最適に読みやすくします。
  • 空間機能を戦略的に使用する: アプリのユーザー ジャーニーの中で、空間機能を組み込むことでエクスペリエンスを向上させ、プラットフォームの独自の機能を活用できる重要なタイミングを特定します。
  • ユーザーの快適性を考慮して空間パネルを配置する: 空間パネルを使用してレイアウトを設計する場合は、圧迫感や近づきすぎないように、ユーザーから快適な距離に配置します。
  • 空間レイアウトに適応型 UI を使用する: ペインや段階的な表示などの適応型 UI のコンセプトを利用して、レイアウトを複数の空間パネルに効果的に分解し、情報の表示を最適化します。
  • 永続的な要素とパターンにオービターを使用: ナビゲーションやコントロールなど、永続的でコンテキストに応じた UX 要素にオービターを予約します。明確さを維持し、混乱を避けるため、オービターの使用を制限します。
  • エレベーションを慎重に使用: コンテンツとともにスクロールせず、静止したままの臨時コンポーネントに空間エレベーションを適用します。視覚的な不快感を防ぎ、視覚的な階層のバランスを維持するために、広範囲をエレベートしないでください。
  • マテリアル デザインでビルドする: マテリアル デザイン コンポーネントとアダプティブ レイアウトの最新のアルファ版でビルドする場合は、「EnableXrComponentOverrides」ラッパーを追加して、アプリで XR の変更を有効にできます。詳しくは、XR 向けマテリアル デザインのドキュメントをご覧ください。

Jetpack Compose for XR には、XR の拡張機能を管理する新しいコンポーネントが導入されているため、開発者が管理する必要はありません。たとえば、SpatialPopupSpatialDialog を使用して、2D の対応するオブジェクトを置き換えることができます。これらのコンポーネントは、空間 UI を使用できない場合は一般的な 2D UI として表示され、可能であればアプリの空間 UI が表示されます。使用方法は、対応する 2D UI 要素を 1 行変更して置き換えるのと同じくらい簡単です。

ダイアログを SpatialDialog に変換する

// Previous approach
Dialog(
    onDismissRequest = onDismissRequest
) {
    MyDialogContent()
}

// New XR differentiated approach
SpatialDialog(
    onDismissRequest = onDismissRequest
) {
    MyDialogContent()
}

ポップアップを SpatialPopup に変換する

// Previous approach
Popup(onDismissRequest = onDismissRequest) {
    MyPopupContent()
}

// New XR differentiated approach
SpatialPopup(onDismissRequest = onDismissRequest) {
    MyPopupContent()
}

2D UI 要素をエレベートする

より細かい制御で UI をエレベートする場合は、SpatialElevation を使用して、アプリ内の任意の Compose を、SpatialElevationLevel で設定した Z 軸上の空間パネルより上のレベルにエレベートできます。次の例に示すように、これによりユーザーの注意を引くことができ、階層を改善して読みやすさを高めることができます。

// Elevate an otherwise 2D Composable (signified here by ComposableThatShouldElevateInXr).
SpatialElevation(spatialElevationLevel = SpatialElevationLevel.Level4) {
    ComposableThatShouldElevateInXr()
}

コードに関する主なポイント

  • 大きなエリアや平面(ボトムシートやサイドシートなど)を空間化またはエレベートしないでください。
  • コンテンツと一緒にスクロールできる UI 要素をエレベートしないでください。

2D コンポーネントをオービターへ移行する

オービターはフローティング要素で、通常はユーザーが操作できるコントロールが含まれています。オルビターは、空間パネルや空間レイアウトなどの他のエンティティに固定できます。コンテンツにスペースを広く確保し、メインのコンテンツを妨げることなくユーザーが機能に素早くアクセスできるようにします。

空間化されていないナビゲーション レール

空間化されていないナビゲーション レール

空間化された(XR 対応)ナビゲーション レール

空間化された(XR 対応)ナビゲーション レール

次のサンプルコードは、2D UI コンポーネントをオービターに変換する方法を示しています。

// Previous approach
NavigationRail()

// New XR differentiated approach
Orbiter(
    position = OrbiterEdge.Start,
    offset = dimensionResource(R.dimen.start_orbiter_padding),
    alignment = Alignment.Top
) {
    NavigationRail()
}

オルビターに関する主なポイント

  • オービターは、既存の UI 要素を空間パネルに接続するように設計されたコンポーネントです。
  • オビッター用に移行する要素と避けるべきパターンについては、Android XR アプリ設計ガイダンスをご覧ください。
  • ナビゲーション レール、トップ アプリバー、ボトム アプリバーなど、少数のナビゲーション コンポーネントのみを適応することをおすすめします。
  • 空間 UI が有効になっていない場合、オービターは表示されません。たとえば、ホームスペースやスマートフォン、タブレット、折りたたみ式デバイスには表示されません。

2D コンポーネントを空間パネルに移行する

空間パネルは、Android XR アプリの UI の基本的な構成要素です。

パネルは、UI 要素、インタラクティブなコンポーネント、没入型コンテンツのコンテナとして機能します。設計時に、ユーザー操作用のオービターなどのコンポーネントを追加したり、特定の操作に注意を向けるために UI 要素を空間的にエレベートしたりできます。

コードに関する主なポイント

  • パネルに移行する要素と避けるべきパターンについては、Android XR アプリの設計ガイダンスをご覧ください。
  • 空間パネルの配置に関するベスト プラクティスに沿って配置します。
    • パネルは、ユーザーの目の中心から 1.5 m の位置にスポーンする必要があります。
    • コンテンツは、ユーザーの視野の中央 41° に表示する必要があります。
  • ユーザーが移動してもパネルは同じ位置にとどまります。アンカーはパススルーでのみ使用できます。
  • パネルの角は、システムで推奨されている 32 dp の丸みを維持します。
  • タップ ターゲットは 56 dp 以上で、48 dp 未満にしない。
  • 特に透明な背景を使用している場合は、読みやすくするためにコントラスト比を維持します。
  • Android デザインの色の原則に従い、マテリアル デザインのカラーシステムを使用して、アプリのダークモードとライトモードを実装します。
  • 既存の UI 要素で空間パネル API を使用する。

2D UI を単一の空間パネルに移行する

デフォルトでは、アプリはホームスペースに 1 つのパネルで表示されます。詳しくは、ホームスペースとフルスペースを切り替える方法をご覧ください。コンテンツをフルスペースに表示するには、SpatialPanel を使用します。

以下に例を示します。

if (LocalSpatialCapabilities.current.isSpatialUiEnabled) {
    Subspace {
        SpatialPanel(
            SubspaceModifier
                .resizable(true)
                .movable(true)
        ) {
            AppContent()
        }
    }
} else {
    AppContent()
}

2D UI を複数の空間パネルに移行する

アプリの UI に単一の空間パネルを使用するか、2D UI を複数の空間パネルに移行できます。アプリの UI に複数のパネルを使用する場合は、パネルを配置して回転できます(2D で UI をレイアウトする場合と同様に)。最初に、実現したいことを明確に設計します。次に、Spatial UI Layout API(SpatialBoxSpatialRowSpatialColumnSpatialLayoutSpacerSpatialAlignment)とサブスペース修飾子を使用して、パネルを配置して回転します。複数のパネルを実装する際には、避けるべき重要なパターンがいくつかあります。

  • 重要な情報をユーザーが確認できないように、パネルが重なり合うことは避けてください。
  • パネルでユーザーを圧倒しないようにします。
  • 不快な場所や目立たない場所にパネルを設置しないでください。例: ユーザーの後ろに配置されたパネルは認識しにくい。
  • 空間 UI の開発について詳しくは、ガイダンスをご覧ください。

空間化されていないコンテンツ

空間化されていないコンテンツ

オビター内の空間化された(XR 対応)メディア コントロールと、複数の空間パネルに分割されたコンテンツ

オビター内の空間化された(XR 対応)メディア コントロールと、複数の空間パネルに分割されたコンテンツ

SpatialRow {
    SpatialPanel(
        SubspaceModifier
            .width(384.dp)
            .height(592.dp)
    ) {
        StartSupportingPanelContent()
    }
    SpatialPanel(
        SubspaceModifier
            .height(824.dp)
            .width(1400.dp)
    ) {
        App()
    }
    SpatialPanel(
        SubspaceModifier
            .width(288.dp)
            .height(480.dp)
    ) {
        EndSupportingPanelContent()
    }
}

空間機能を確認する

特定の UI 要素を表示するかどうかを判断する際は、特定の XR デバイスやモードを確認しないでください。機能ではなくデバイスやモードを確認すると、特定のデバイスの機能が時間の経過とともに変化した場合に問題が発生する可能性があります。代わりに、次の例に示すように、LocalSpatialCapabilities.current.isSpatialUiEnabled を使用して、必要な空間化機能を直接確認します。このアプローチにより、新しいデバイスの登場や機能の変更のたびにアップデートする必要なく、アプリを幅広い XR エクスペリエンスに適切に適応させることができます。

if (LocalSpatialCapabilities.current.isSpatialUiEnabled) {
    SupportingInfoPanel()
} else {
    ButtonToPresentInfoModal()
}

// Similar check for audio
val spatialAudioEnabled = LocalSpatialCapabilities.current.isSpatialAudioEnabled

環境を使用してユーザーの周囲を変更する

ユーザーの周囲を変更してアプリに没入感を演出する場合は、環境を使用します。コードに環境を追加するのは簡単な変更であり、アプリの既存の UI に大きな影響を与えることなく行うことができます。環境の設定について詳しくは、ガイダンスをご覧ください。

3D コンテンツを追加する

3D モデルや空間動画などの 3D コンテンツは、没入感のあるエクスペリエンスを作成し、空間的な理解を深めるのに役立ちます。アプリで 3D コンテンツを表示できるのは、空間機能が利用可能な場合のみです。そのため、まず空間機能が利用可能かどうかを確認する必要があります。

3D モデル空間動画空間オーディオを追加する方法については、該当するガイドをご覧ください。