Ajouter un sous-espace à votre application

Appareils XR concernés
Ces conseils vous aident à créer des expériences pour ces types d'appareils XR.
Casques XR
Lunettes XR filaires

Un sous-espace est une partition d'un espace 3D au sein de votre application. Vous pouvez y placer des modèles 3D, y créer des mises en page 3D et ajouter de la profondeur à des contenus qui seraient en 2D autrement. Un sous-espace n'est rendu que lorsque la spatialisation est activée. Dans l'espace Maison ou sur les appareils non XR, tout code se trouvant dans ce sous-espace est ignoré.

Vous pouvez utiliser des composables d'espace sous-jacent tels que SpatialPanel, SpatialRow et SpatialColumn pour créer votre mise en page et placer du contenu 2D dans un espace 3D. Pour placer du contenu 3D, utilisez le composable Subspace approprié, comme SceneCoreEntity pour les modèles 3D et SpatialExternalSurface pour les images stéréoscopiques. Certains composants XR tels que Orbiter ou SpatialDialog sont des composables 2D standards qui peuvent être utilisés n'importe où dans la hiérarchie de votre UI 2D, mais un SubspaceComposable doit être appelé dans le sous-espace de votre application. Pour ce faire, utilisez le composable de sous-espace Subspace.

À propos des hiérarchies de sous-espaces

Subspace de premier niveau est le sous-espace le plus externe invoqué par votre application. Chaque appel à un Subspace crée une hiérarchie d'UI spatiale nouvelle et indépendante. Il n'hérite pas de la position spatiale, de l'orientation ni de l'échelle d'un Subspace parent dans lequel il est imbriqué.

Pour créer un Subspace intégré ou imbriqué dans un SpatialPanel, Orbiter, SpatialPopup ou un autre composant, utilisez PlanarEmbeddedSubspace.

PlanarEmbeddedSubspace présente deux différences majeures par rapport à Subspace :

  • Ils participent à la mise en page 2D dans laquelle ils sont appelés. Cela signifie que la hauteur et la largeur du sous-espace seront limitées par la hauteur et la largeur de sa mise en page parente 2D.
  • Ils se comportent comme des enfants de l'entité dans laquelle ils sont appelés. Cela signifie que si vous appelez un composable d'espace secondaire imbriqué dans un SpatialPanel, cet espace secondaire est un enfant du SpatialPanel dans lequel il est appelé.

Ces comportements de PlanarEmbeddedSubspace permettent d'activer des fonctionnalités telles que :

  • Déplacer l'enfant avec l'entité parente
  • Décaler l'emplacement de l'enfant à l'aide du décalage SubspaceModifier
  • Présentation d'un objet 3D qui flotte au-dessus de votre UI 2D et correspond à la hauteur et à la largeur de l'espace approprié dans la mise en page 2D

Adapter les mises en page pour un sous-espace

Sur Android XR, la mise en page de votre application est liée au VolumeConstraints de Subspace en mode d'affichage complet par défaut. Pour cette raison, vous devez tenir compte de l'espace visible disponible pour l'utilisateur et ajuster votre mise en page en conséquence. recommendedContentBoxInFullSpace fournit les dimensions spécifiques du cadre de sélection à l'intérieur de ActivitySpace afin que le contenu puisse être placé dans le champ de vision de l'utilisateur.

Le contenu principal de votre application doit tenir dans cette zone. Si vous avez du contenu qui doit dépasser les limites recommandées, envisagez une mise en page qui encourage les utilisateurs à explorer l'espace en bougeant la tête. La contrainte par défaut de recommendedContentBoxInFullSpace peut être remplacée en appliquant un modificateur personnalisé basé sur la taille, tel que SubspaceModifier.requiredSizeIn. Pour un comportement sans limites, définissez allowUnboundedSubspace = true.

Appelez recommendedContentBoxInFullSpace à l'aide de la Session actuelle pour obtenir ces dimensions spécifiques selon vos besoins. Consultez l'exemple suivant :

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

Ajouter un sous-espace à votre application

L'exemple de code suivant montre comment ajouter Subspace et PlanarEmbeddedSubspace à votre application :

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 {}
    }
}

Pour en savoir plus, consultez la documentation de référence complète sur Subspace et PlanarEmbeddedSubspace.