Conception pour les grands écrans

Dans ce guide, vous allez apprendre à adapter votre jeu pour qu'il fonctionne sur différents facteurs de forme Android.

Avant de commencer, lisez Prendre en charge le redimensionnement sur grand écran. Les jeux modernes sur Android doivent s'adapter à toutes les tailles d'écran sans dépendre des couches de compatibilité du système. De cette façon, vous contrôlez toujours la façon dont votre jeu s'affiche et vous offrez une expérience de jeu premium, même sur des facteurs de forme tels que la XR ou des appareils dont l'écran ne peut pas être pivoté.

Pour ce faire, procédez comme suit :

  1. Désactivez le format letterbox du système et implémentez votre propre format letterbox dans le moteur.
  2. Rendez la zone letterbox utilisable et adaptée au thème.
  3. Abordez les considérations de conception nécessaires pour permettre à votre jeu de s'adapter aux formats 21:9, 1:1 et 9:21.

Commandes pour les tests

Lorsque vous créez et testez votre jeu, vérifiez qu'il affiche lui-même les bandes noires. Vous devez également forcer votre jeu à s'afficher en mode portrait et paysage, car les appareils tels que les téléviseurs et les écrans embarqués ne peuvent pas pivoter par rapport à leur orientation par défaut (portrait ou paysage).

Pour vérifier si votre moteur de jeu utilise le format letterbox du système, utilisez la commande adb shell cmd window set-letterbox-style. Par exemple, la commande suivante colore les bandes noires du système en vert vif et ajoute un rayon d'angle à votre jeu, ce qui permet de voir clairement si votre jeu revient au mode de compatibilité du système d'exploitation :

adb shell "cmd window set-letterbox-style --backgroundType solid_color --backgroundColor '#00FF00' --cornerRadius 30 --isEducationEnabled false"

Pour forcer une orientation à des fins de test, utilisez adb shell cmd window user-rotation lock. Cela vous aide à simuler le comportement de votre jeu sur un appareil qui ne respecte pas les forçages d'orientation de l'application, ou à comprendre ce que les utilisateurs voient sur un appareil XR ou de type PC où les fenêtres peuvent s'afficher en mode portrait ou paysage, indépendamment de l'orientation de l'appareil.

Tout d'abord, mettez votre appareil dans un état où vous pouvez ignorer l'orientation de l'application :

adb shell cmd window set-ignore-orientation-request true
adb shell cmd window fixed-to-user-rotation enabled

Ensuite, testez le passage de votre jeu en mode Paysage :

adb shell cmd window user-rotation lock 1

Ensuite, testez le passage de votre jeu en mode Portrait :

adb shell cmd window user-rotation lock 0

Réinitialisez votre appareil sur la configuration OEM en le redémarrant ou en exécutant les commandes suivantes :

adb shell cmd window reset-letterbox-style
adb shell cmd window fixed-to-user-rotation default
adb shell cmd window user-rotation free
adb shell cmd window set-ignore-orientation-request reset

Pourquoi désactiver le letterboxing du système ?

Le système contrôle toujours le letterboxing du système. En détectant la taille de l'écran et en gérant vous-même la zone d'affichage, vous pouvez limiter les problèmes, tels que les entrées ignorées, qui se produisent lorsque les entrées quittent la zone de jeu. Vous pouvez également étendre les éléments non liés au gameplay jusqu'au bord de l'écran, même si le contenu de votre jeu reste fixe au milieu. Les modes de compatibilité du système peuvent rendre un jeu disponible, mais c'est à vous, en tant que développeur, de faire en sorte que votre jeu soit agréable pour vos joueurs.

Illustrations d'écrans de téléphone, d'appareil pliable, de tablette et d'ordinateur portable mettant en évidence les zones de fenêtre actives.
Figure 1. Facteurs de forme : téléphone, pliable, tablette et ordinateur portable.

Exemple d'implémentation du format letterbox

La plupart des moteurs de jeu vous permettent de contrôler l'emplacement de rendu d'une caméra à l'écran. Pour implémenter votre propre format letterbox, mesurez le format de la zone affichée et ajustez votre rectangle de découpage pour la zone inutilisée au lieu de laisser le système appliquer le format letterbox à votre jeu. L'exemple suivant limite une caméra au rendu dans un format limité, tout en permettant aux caméras ou aux passes de l'interface utilisateur de s'étendre à la taille d'écran logique complète :

Unity

[SerializeField]
private float minAspectRatio = 4f / 3f;

[SerializeField]
private float maxAspectRatio = 21f / 9f;

private Camera _camera;

private void Awake()
{
    _camera = GetComponent<Camera>();
}

public void MaintainAspectRatio()
{
    int viewWidth = Screen.width;
    int viewHeight = Screen.height;

    // 1. Calculate screen aspect ratio
    float scaleScreen = viewWidth / (float)viewHeight;
    Rect rect = _camera.pixelRect;

    // 2. Scale to the fullest of the lower between width or height
    if (scaleScreen > maxAspectRatio)
    {
        // use height, lock width to max at aspect scale
        rect.width = viewHeight * maxAspectRatio;
        rect.height = viewHeight;
    }
    else if (scaleScreen < minAspectRatio)
    {
        // use width, lock height to min at aspect scale
        rect.width = viewWidth;
        rect.height = viewWidth / minAspectRatio;
    }
    else
    {
        // within allowed aspect ratio range, use full screen
        rect.width = viewWidth;
        rect.height = viewHeight;
    }

    rect.x = Mathf.Floor((viewWidth - rect.width) * 0.5f);
    rect.y = Mathf.Floor((viewHeight - rect.height) * 0.5f);

    Debug.Log("camera view width = " + rect.width +
        " height = " + rect.height +
        " x = " + rect.x +
        " y = " + rect.y);

    // 3. Commit the new size to the camera so that it takes effect
    _camera.pixelRect = rect;
}

C++ (Vulkan)

/**
 * @brief Calculates a bounded-aspect-ratio gameplay viewport and scissor
 * rectangle and records them directly into a Vulkan command buffer.
 *
 * @note Requires `VK_DYNAMIC_STATE_VIEWPORT` and `VK_DYNAMIC_STATE_SCISSOR` to
 * be enabled on the bound graphics `VkPipeline`.
 *
 * @param command_buffer   Active `VkCommandBuffer` in the recording state.
 * @param window_width     Full physical window or swapchain width in pixels.
 * @param window_height    Full physical window or swapchain height in pixels.
 * @param min_aspect_ratio Minimum allowed aspect ratio (`width / height`).
 * @param max_aspect_ratio Maximum allowed aspect ratio (`width / height`).
 */
void MaintainAspectRatio(VkCommandBuffer command_buffer, uint32_t window_width,
                         uint32_t window_height, float min_aspect_ratio,
                         float max_aspect_ratio) {
  if (command_buffer == VK_NULL_HANDLE || window_width == 0 ||
      window_height == 0 || min_aspect_ratio <= 0.0f ||
      max_aspect_ratio < min_aspect_ratio) {
    return;
  }

  // 1. Calculate screen aspect ratio.
  const float view_width = static_cast<float>(window_width);
  const float view_height = static_cast<float>(window_height);
  const float scale_screen = view_width / view_height;

  // 2. Scale to the fullest of the lower between width or height.
  float rect_width = view_width;
  float rect_height = view_height;
  if (scale_screen > max_aspect_ratio) {
    // Use height, lock width to max at aspect scale (pillarbox).
    rect_width = std::floor(view_height * max_aspect_ratio);
    rect_height = view_height;
  } else if (scale_screen < min_aspect_ratio) {
    // Use width, lock height to min at aspect scale (letterbox).
    rect_width = view_width;
    rect_height = std::floor(view_width / min_aspect_ratio);
  } else {
    // Within allowed aspect ratio range, use full screen.
    rect_width = view_width;
    rect_height = view_height;
  }

  const float rect_x = std::floor((view_width - rect_width) * 0.5f);
  const float rect_y = std::floor((view_height - rect_height) * 0.5f);

  // 3. Commit the new viewport and scissor to the command buffer so that
  // subsequent gameplay draw calls are transformed and clipped to this region.
  const VkViewport viewport = {
      .x = rect_x,
      .y = rect_y,
      .width = rect_width,
      .height = rect_height,
      .minDepth = 0.0f,
      .maxDepth = 1.0f,
  };
  const VkRect2D scissor = {
      .offset =
          {
              .x = static_cast<int32_t>(rect_x),
              .y = static_cast<int32_t>(rect_y),
          },
      .extent =
          {
              .width = static_cast<uint32_t>(rect_width),
              .height = static_cast<uint32_t>(rect_height),
          },
  };

  vkCmdSetViewport(command_buffer, 0, 1, &viewport);
  vkCmdSetScissor(command_buffer, 0, 1, &scissor);
}

Pour suivre un tutoriel détaillé dans Unity, consultez l'atelier de programmation Optimiser les jeux Unity pour les grands écrans et les pliables.

Gérer les grandes et petites tailles d'écran

Sur les écrans plus petits, comme les téléphones et les écrans extérieurs des pliables, la meilleure expérience utilisateur peut être un jeu verrouillé en mode Portrait ou Paysage. À mesure que les écrans s'agrandissent (tablettes, Chromebooks, écrans de voiture ou écrans intérieurs des pliables), il devient moins souhaitable, voire impossible, de faire pivoter l'appareil, tandis que l'écran physique plus grand permet de jouer au jeu dans des formats hors axe.

Pour offrir une expérience optimale aux joueurs, détectez la taille de l'écran au moment de l'exécution et limitez la rotation si nécessaire, tout en offrant plus de flexibilité aux joueurs à mesure que la taille de l'écran augmente. Android considère que la limite idéale est sw600dp, soit une largeur minimale de 600 pixels indépendants de la densité (600 dp). Cela correspond à WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND. Utilisez computeMaximumWindowMetrics pour valider la taille d'écran disponible dans les configurations multi-écrans.

Pour que votre jeu soit compatible, acceptez toutes les orientations dans votre fichier manifeste, puis, dans onCreate() et onConfigurationChanged(), évaluez la plus petite largeur et définissez le verrouillage de l'orientation de manière appropriée :

  1. Supprimez les verrouillages d'orientation statiques dans votre fichier manifeste et déclarez la gestion des modifications de configuration :

    <activity
        android:name=".MainActivity"
        android:resizeableActivity="true"
        android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|density|keyboard|keyboardHidden" />
    
  2. Ajoutez les importations requises :

    import android.content.pm.ActivityInfo
    import android.content.res.Configuration
    import android.os.Bundle
    import androidx.activity.enableEdgeToEdge
    import androidx.window.core.layout.WindowSizeClass
    import androidx.window.layout.WindowMetricsCalculator
    import kotlin.math.min
    
  3. Gérez à la fois onCreate et onConfigurationChanged :

    override fun onCreate(savedInstanceState: Bundle?) {
        enableEdgeToEdge()
        super.onCreate(savedInstanceState)
        applyAdaptiveOrientationPolicy()
        // ...
    }
    
    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        applyAdaptiveOrientationPolicy()
        // ...
    }
    
  4. Mettez à jour l'orientation demandée en fonction de la plus petite largeur d'écran, en verrouillant les écrans compacts sur l'orientation de conception préférée de votre jeu :

    private fun applyAdaptiveOrientationPolicy() {
        // compute the smallest screen bound in dp
        val maxMetrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this)
        val minDimensionPx = min(maxMetrics.bounds.width(), maxMetrics.bounds.height())
        val displaySmallestWidthDp = minDimensionPx / maxMetrics.density
    
        val targetOrientation = if (displaySmallestWidthDp >= WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) {
            // Large display (>= 600dp): allow free rotation in any orientation
            ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
        } else {
            // Compact display (< 600dp): lock to your game's preferred orientation
            // (use SCREEN_ORIENTATION_SENSOR_LANDSCAPE for landscape-first games)
            ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        }
    
        // Guard against redundant setter calls to avoid configuration change loops
        if (requestedOrientation != targetOrientation) {
            requestedOrientation = targetOrientation
        }
    }
    

Concevoir en tenant compte des problèmes courants

La prise en charge de plusieurs formats et orientations offre à vos joueurs la meilleure expérience utilisateur possible. Contrairement aux téléphones, les écrans plus grands sont souvent fixes en mode paysage ou portrait, et dans certains cas, l'écran est presque carré. Sur ces appareils plus grands, les joueurs effectuent souvent plusieurs tâches en même temps lorsqu'ils jouent à votre jeu. En maximisant l'utilisation de l'espace à l'écran, vous pouvez engager plus de joueurs, plus souvent et pour des sessions de jeu plus longues.

Les sections suivantes proposent des solutions pour que votre jeu offre une expérience de qualité sur tous les facteurs de forme, plutôt que de donner l'impression d'un jeu pour téléphone intégré à un écran non téléphonique.

Caméras prenant en compte l'aspect

Dans les jeux 3D, si un écran est trop haut, les joueurs peuvent avoir l'impression de voir le jeu à travers une fente étroite. S'il est trop large, ils risquent de manquer les interactions prévues. Comme dans les jeux 2D, vous pouvez garder une "zone de sécurité" toujours visible. Le code suivant permet de basculer entre un champ de vision horizontal et un champ de vision vertical en fonction de la comparaison entre le format actif et un format de référence de 1 920 x 1 080. De cette façon, un concepteur peut créer un jeu pour un écran 1080p et s'assurer que tout ce qui est conçu dans ce cadre de référence reste visible :

Unity

[SerializeField]
private Camera _camera;

[SerializeField]
private float _referenceWidth = 1920f;

[SerializeField]
private float _referenceHeight = 1080f;

[SerializeField]
private float _referenceVerticalFov = 60f;

public float ReferenceAspectRatio => _referenceWidth / Mathf.Max(0.0001f, _referenceHeight);

private void Awake()
{
    if (_camera == null)
    {
        _camera = GetComponent<Camera>();
    }
}

// Built-in Render Pipeline callback. In URP, subscribe to
// RenderPipelineManager.beginCameraRendering or call UpdateFov() on resize.
private void OnPreCull()
{
    UpdateFov();
}

public void UpdateFov()
{
    if (_camera == null || _camera.orthographic)
    {
        return;
    }

    float referenceAspect = ReferenceAspectRatio;
    float currentAspect = _camera.aspect;
    if (currentAspect <= 0.0001f)
    {
        return;
    }

    float targetVerticalFov;

    if (currentAspect >= referenceAspect)
    {
        // Viewport is wider than (or equal to) the reference safe area
        targetVerticalFov = _referenceVerticalFov;
    }
    else
    {
        // Viewport is skinnier than the reference safe area
        float referenceHorizontalFov = Camera.VerticalToHorizontalFieldOfView(_referenceVerticalFov, referenceAspect);
        targetVerticalFov = Camera.HorizontalToVerticalFieldOfView(referenceHorizontalFov, currentAspect);
        targetVerticalFov = Mathf.Clamp(targetVerticalFov, 1f, 179f);
    }

    if (!Mathf.Approximately(_camera.fieldOfView, targetVerticalFov))
    {
        _camera.fieldOfView = targetVerticalFov;
    }
}

C++ (Vulkan)

/**
 * @brief Calculates an aspect-aware Vulkan perspective projection matrix using
 * GLM that keeps a reference safe area (e.g., 1920x1080) visible across
 * aspect ratios.
 *
 * @note Uses `glm::perspectiveZO` for Vulkan's `[0, 1]` depth range and
 * inverts `projection[1][1]` for Vulkan's top-left (`+Y` down) clip space.
 *
 * @param viewport_width         Active gameplay viewport width in pixels.
 * @param viewport_height        Active gameplay viewport height in pixels.
 * @param reference_width        Authored safe-area reference width in pixels.
 * @param reference_height       Authored safe-area reference height in pixels.
 * @param reference_vertical_fov Authored vertical FOV in degrees (e.g., 60.0f).
 * @param near_plane             Near clipping plane distance (`zNear > 0.0f`).
 * @param far_plane              Far clipping plane distance (`zFar > zNear`).
 * @return Aspect-aware `glm::mat4` perspective projection matrix for Vulkan.
 */
glm::mat4 CalculateAspectAwareProjectionMatrix(
    float viewport_width, float viewport_height, float reference_width = 1920.0f,
    float reference_height = 1080.0f, float reference_vertical_fov = 60.0f,
    float near_plane = 0.1f, float far_plane = 100.0f) {
  if (viewport_width <= 0.0001f || viewport_height <= 0.0001f) {
    return glm::mat4(1.0f);
  }

  // 1. Compare the active viewport aspect ratio against the reference safe
  // area.
  const float reference_aspect =
      reference_width / std::max(0.0001f, reference_height);
  const float current_aspect = viewport_width / viewport_height;

  float target_vertical_fov_rad = glm::radians(reference_vertical_fov);

  if (current_aspect >= reference_aspect) {
    // Viewport is wider than (or equal to) the reference safe area (Hor+).
    target_vertical_fov_rad = glm::radians(reference_vertical_fov);
  } else {
    // Viewport is skinnier than the reference safe area (Vert+):
    // Convert reference vertical FOV -> reference horizontal FOV -> new
    // vertical FOV at current_aspect so the safe area is never cropped.
    const float tan_half_horiz =
        std::tan(target_vertical_fov_rad * 0.5f) * reference_aspect;
    target_vertical_fov_rad = 2.0f * std::atan(tan_half_horiz / current_aspect);
    target_vertical_fov_rad = std::clamp(
        target_vertical_fov_rad, glm::radians(1.0f), glm::radians(179.0f));
  }

  // 2. Build the Vulkan [0, 1] depth perspective matrix and flip +Y clip space.
  glm::mat4 projection = glm::perspectiveZO(
      target_vertical_fov_rad, current_aspect, near_plane, far_plane);
  projection[1][1] *= -1.0f;
  return projection;
}

Boîtes aux lettres entièrement interactives

Certains jeux ont une zone de jeu fixe par conception, qui correspond souvent à des considérations de conception basées sur le genre, comme le champ fixe d'un shoot-'em-up vertical ou le défilement d'écran utilisé pour une esthétique rétro.

Pour ces jeux, redimensionnez la zone de jeu de sorte qu'un axe du jeu soit toujours maximisé pour remplir la zone de jeu. L'axe maximisé peut changer en fonction des formats relatifs de votre jeu et des limites d'affichage.

Ancrez les éléments d'affichage tête haute et d'interface utilisateur jusqu'au bord de la zone sûre de l'écran : évitez les encoches, mais placez les éléments interactifs tels que les commandes virtuelles, les barres de santé et les mini-cartes aussi loin que possible de la zone de jeu. De cette façon, la partie interactive du jeu utilise l'intégralité de l'écran, et les joueurs sur des facteurs de forme tels que les tablettes et les appareils pliables peuvent jouer confortablement à votre jeu sans avoir à trop étirer leurs doigts.

Enfin, assurez-vous que la zone de letterbox est thématique ou diégétique. Envisagez des bordures qui correspondent à la palette ou au jeu de tuiles à l'écran, une table ou un écran virtuel pour les jeux de société ou rétro, ou des mini-cartes étendues et des visuels décoratifs.

Dans l'exemple suivant, le jeu s'affiche en taille réelle pour la plupart des formats. Lorsque le format est plus étroit que 4:3, il affiche une skybox de couleur thématique tout en continuant à placer des éléments d'interface utilisateur tels que des commandes sur le bord de l'écran :

Jeu à défilement horizontal dans une forêt, affiché en plein écran dans une fenêtre en mode paysage avec des commandes tactiles dans les angles.
Figure 2. Jeu affiché en taille réelle dans un format large standard.
Jeu de forêt à défilement horizontal dans une fenêtre plus étroite que le format 4:3, montrant des bandes noires à thème avec un feuillage jaune et des commandes tactiles ancrées sur les bords extérieurs de l'écran.
Figure 3. Jeu avec un format d'image inférieur à 4:3 affichant une skybox thématique avec des commandes d'interface utilisateur ancrées sur les bords de l'écran.

Brouillard de guerre

De nombreux développeurs de jeux craignent que les joueurs puissent obtenir un avantage déloyal grâce à des formats verticaux ou horizontaux extrêmes. Par exemple, un joueur d'un jeu compétitif comme une arène de bataille en ligne multijoueur (MOBA) peut utiliser un écran très vertical pour avoir une vue plongeante sur la voie d'un adversaire.

Pour les jeux de stratégie et de simulation en vue de dessus, envisagez d'afficher un brouillard de guerre :

  • Ne générez pas de géométrie tant que le joueur ne peut pas la voir.
  • Affichez la géométrie que le personnage du joueur ne peut pas voir activement comme étant estompée, sans aucun élément dynamique.
  • Ne restituez que les adversaires, les objets de collection et les autres objets dynamiques que le personnage du joueur peut voir de manière diégétique.

Si vous combinez cette technique avec des boîtes aux lettres entièrement interactives et que vous affichez votre UI jusqu'au bord de l'écran, le joueur bénéficie d'une expérience à la fois soignée et intentionnelle, sans que vous ayez à repenser la structure des niveaux ou l'équilibre des équipes.

Si vous agrandissez ce jeu pour remplir un écran plus grand sans brouillard de guerre, des parties de la carte que le joueur ne devrait pas voir sont révélées :

RPG en vue de dessus sur un petit écran montrant Sir Bugdroid tenant un bouclier et une lanterne près d'une épée lumineuse sur un piédestal, un pont sur une rivière et des rails de wagonnet.
Figure 4. Vue d'origine de la caméra sur un écran plus petit.
Vue agrandie de la même carte de RPG en vue de dessus sur un grand écran, révélant un golem et un coffre au trésor dans une pièce de donjon, ainsi que des gobelins de l'autre côté de la rivière.
Figure 5. Vue développée révélant des parties de la carte que le joueur ne devrait pas voir.

En affichant un brouillard de guerre et en masquant les éléments dynamiques tels que les ennemis et les objets, vous maintenez l'équité dans le jeu tout en utilisant l'intégralité de l'image disponible pour le jeu :

RPG en vue de dessus sur un petit écran montrant la zone active autour du joueur.
Figure 6. Zone visible active autour du personnage du joueur.
Vue agrandie de la carte RPG en vue de dessus, où le terrain lointain est assombri et où les ennemis et les objets hors du champ de vision du joueur sont masqués.
Figure 7. Vue agrandie avec un brouillard de guerre qui assombrit le terrain lointain et masque les éléments dynamiques.

Estomper la géométrie

De nombreux jeux, en particulier dans le domaine de la stratégie au tour par tour, utilisent une technique similaire au brouillard de guerre décrit dans la section précédente et n'affichent pas la géométrie que le joueur n'a pas découverte ou avec laquelle il ne peut pas interagir pendant un certain setpiece.

Si un champ de vision élargi révèle des parties de votre décor ou de votre cinématique que le joueur ne devrait pas voir, vous pouvez masquer certaines parties de la scène de manière propre. Vous obtiendrez ainsi le même effet pratique qu'un format letterbox, sans la perception d'une bordure statique fixe.

Dans l'exemple suivant, l'extension du jeu à un format plus grand révèle une horde de zombies à l'extérieur des murs du château :

Vue isométrique d'un RPG tactique montrant Bugdroid et Mecha Hamster dans l'enceinte d'un château.
Figure 8. Zone de jeu à l'intérieur des murs du château dans un format plus étroit.
Vue isométrique étendue d'un RPG tactique révélant une horde d'ennemis attendant devant la porte inférieure du château.
Figure 9. Format plus grand révélant une horde de zombies à l'extérieur des murs du château.

Vous pouvez plutôt omettre d'afficher la géométrie du niveau au-delà des limites de la zone de jeu actuelle :

Vue isométrique d'un RPG tactique montrant Bugdroid et Mecha Hamster dans l'enceinte du château.
Figure 10. Aire de jeux dans l'enceinte du château.
Vue RPG tactique isométrique étendue où la géométrie du niveau et les ennemis à l'extérieur des murs du château sont omis.
Figure 11. Format plus grand où la géométrie du niveau n'est pas affichée au-delà de la zone de jeu actuelle.

Limites diégétiques

Dans les jeux 3D immersifs où un champ de vision étendu peut offrir un avantage compétitif dans les jeux multijoueurs à la première ou à la troisième personne, ou révéler des zones non créées de jeux basés sur des décors fixes, envisagez d'intégrer des éléments diégétiques dans le jeu pour limiter le champ de vision plutôt que de vous appuyer sur un format letterbox rectangulaire. Exemples :

  • L'intérieur du cockpit d'un véhicule comme une voiture ou un avion
  • L'intérieur d'un casque
  • Vignette indiquant la limite du champ de vision d'un joueur

Les éléments d'UI et de HUD doivent toujours s'étendre jusqu'au bord de l'écran ou être intégrés aux limites diégétiques. L'idéal est de les rendre dynamiques. Ces éléments diégétiques peuvent également aider les joueurs souffrant du mal des transports, en particulier sur les facteurs de forme XR, en fournissant une aide à l'accessibilité, en plus d'aider à atténuer la complexité des nouveaux formats.

Évitez d'afficher le jeu sur une surface à l'intérieur d'une scène statique non interactive. Bien que cette approche soit préférable au rendu de barres noires pour les bandes noires horizontales et verticales, les joueurs remarquent rapidement les bordures statiques et peuvent être frustrés si leurs jeux préférés s'affichent sur une zone de l'écran de la taille d'un téléphone sur des facteurs de forme autres que les téléphones.

Dans cet exemple, un jeu conçu pour un écran de téléphone standard est affiché dans un téléviseur simulé avec une manette de jeu skeuomorphique pour s'adapter au format plus carré courant sur les écrans intérieurs des pliables :

Jeu de labyrinthe en 3D affiché dans un cadre de téléviseur CRT simulé, avec une manette de jeu skeuomorphique au premier plan.
Figure 12. Jeu affiché dans un cadre de télévision simulé statique avec une manette de jeu skeuomorphique.

Certains jeux 3D peuvent nécessiter de limiter le champ de vision, soit pour des raisons d'équité, soit pour des raisons de conception. Il est préférable d'utiliser un cockpit, un casque ou une autre métaphore diégétique pour limiter le champ de vision plutôt que des barres noires :

Vue 3D à la première personne d'un labyrinthe depuis l'intérieur d'un cockpit sphérique en forme de boule de hamster, avec une mini-carte en haut et des commandes tactiles en bas.
Figure 13. Cockpit sphérique diégétique limitant le champ de vision tout en ancrant l'affichage tête haute et les commandes sur les bords de l'écran.

Ressources supplémentaires