Cette page est l'une des nombreuses pages fournissant des conseils détaillés sur la manière d'optimiser vos jeux sur PC et sur console. Vous trouverez la collection complète dans le livre électronique gratuit, Optimisez les performances de vos jeux sur console et PCqui contient plus de 80 conseils pratiques et meilleures pratiques pour l'optimisation des performances.
Problème : Lorsqu'un seul élément est modifié sur le canevas de l'interface utilisateur, il salit l'ensemble du canevas.
Le Canvas est le composant de base de l'interface utilisateur d'Unity. Il génère des maillages qui représentent les éléments de l'interface utilisateur placés sur lui, régénère les maillages lorsque les éléments de l'interface utilisateur changent et lance des appels de dessin au GPU pour que l'interface utilisateur soit réellement affichée.
La génération de ces maillages peut être coûteuse. Les éléments de l'interface utilisateur doivent être regroupés en lots afin d'être dessinés en un minimum de temps. La génération de lots étant coûteuse, nous ne voulons les régénérer qu'en cas de besoin. Le problème est que, lorsqu'un ou plusieurs éléments changent sur un canevas, l'ensemble du canevas doit être analysé une nouvelle fois pour déterminer comment dessiner ses éléments de manière optimale.
De nombreux utilisateurs construisent l'ensemble de l'interface utilisateur de leur jeu sur un seul canevas comportant des milliers d'éléments. Lorsqu'ils modifient un élément, ils peuvent subir un pic d'activité de l'unité centrale pendant plusieurs millisecondes. Pour en savoir plus sur les raisons pour lesquelles la reconstruction est si coûteuse, rendez-vous au point 24:55 de cette session Unite.
Solution : Répartissez vos toiles.
Chaque toile est une île qui isole ses éléments de ceux des autres toiles. Tirez parti de la capacité de l'UGUI à prendre en charge plusieurs canevas en découpant vos canevas pour résoudre les problèmes de mise en lots de l'interface utilisateur Unity.
Vous pouvez également imbriquer les toiles, ce qui permet aux concepteurs de créer de grandes interfaces utilisateur hiérarchiques, sans avoir à réfléchir à l'emplacement des différents éléments à l'écran dans les différentes toiles. Les toiles enfant isolent également le contenu de leurs toiles mère et sœur. Ils gèrent leur propre géométrie et effectuent leur propre mise en lots. Une façon de décider comment les répartir est de se baser sur la fréquence à laquelle ils doivent être rafraîchis. Les éléments statiques de l'interface utilisateur doivent être placés sur un canevas distinct et les éléments dynamiques qui sont mis à jour en même temps doivent être placés sur des sous-canevas plus petits. Veillez également à ce que tous les éléments de l'interface utilisateur de chaque canevas aient la même valeur Z, les mêmes matériaux et les mêmes textures.
Problème : Utilisation inadéquate de l'outil Graphic Raycaster
Le Graphic Raycaster est le composant qui traduit vos données en événements d'interface utilisateur. Plus précisément, il traduit les clics d'écran ou les entrées tactiles à l'écran en événements d'interface utilisateur, puis les envoie aux éléments d'interface utilisateur concernés. Vous avez besoin d'un rayonneur graphique sur chaque toile qui nécessite une saisie, y compris les sous-toiles. Cependant, il passe également en revue chaque point d'entrée à l'écran et vérifie s'il se trouve dans la RectTransform de l'interface utilisateur, ce qui peut entraîner une surcharge de travail.
Malgré son nom, le Graphic Raycaster n'est pas vraiment un raycaster. Par défaut, il ne teste que les graphiques de l'interface utilisateur. Il prend l'ensemble des éléments de l'interface utilisateur qui souhaitent recevoir des données sur un canevas donné et effectue des vérifications d'intersection. Par exemple, il vérifie si le point où l'événement d'entrée se produit par rapport à la RectTransform de chaque élément de l'interface utilisateur sur le canevas du rayonneur graphique est marqué comme étant interactif.
Le problème est que tous les éléments de l'interface utilisateur ne sont pas intéressés par les mises à jour.
Solution : Supprimez les diffuseurs de rayons graphiques des interfaces utilisateur non interactives et désactivez la cible de diffusion de rayons pour les éléments statiques ou non interactifs.
En particulier, le texte d'un bouton désactivant la cible de diffusion réduira directement le nombre de vérifications d'intersection que le diffuseur graphique doit effectuer à chaque image.
Problème : Parfois, le Graphic Raycaster agit comme un raycaster.
Si vous réglez le mode de rendu de votre canevas sur Worldspace Camera ou Screen Space Camera, vous pouvez ajouter un masque de blocage. Le masque de blocage détermine si le Raycaster lancera des rayons via la physique 2D ou 3D, afin de déterminer si un objet physique bloque la capacité de l'utilisateur à interagir avec l'interface utilisateur.
Solution : La projection de rayons via la physique 2D ou 3D peut s'avérer coûteuse, c'est pourquoi cette fonction doit être utilisée avec parcimonie.
Minimiser le nombre de diffuseurs graphiques en les excluant des toiles d'interface utilisateur non interactives, puisque, dans ce cas, il n'y a aucune raison de vérifier la présence d'événements d'interaction.
Pour en savoir plus sur le Graphic Raycaster, consultez cette documentation.
Problème : Les grandes listes, les grilles et les nombreux éléments superposés de l'interface utilisateur sont coûteux.
Les grandes listes et grilles sont coûteuses et la superposition de nombreux éléments d'interface utilisateur (par exemple, des cartes empilées dans un jeu de bataille de cartes) entraîne un surdimensionnement.
Solution : Éviter les nombreux éléments superposés de l'interface utilisateur.
Personnalisez votre code pour fusionner les éléments d'interface utilisateur en couches au moment de l'exécution en un nombre réduit d'éléments et de lots.
Si vous devez créer une liste ou une grille de grande taille, par exemple un écran d'inventaire comportant des centaines d'articles, envisagez de réutiliser un ensemble plus restreint d'éléments d'interface utilisateur plutôt qu'un seul élément d'interface utilisateur pour chaque article.
Consultez ce projet GitHub pour un exemple de liste déroulante optimisée.
Problème : Chaque élément d'interface utilisateur qui tente de salir sa présentation effectue au moins un appel à GetComponent.
Lorsqu'un ou plusieurs éléments d'interface utilisateur enfant changent dans un système de mise en page, la mise en page devient "sale". Le ou les éléments enfants modifiés invalident le système de mise en page qui leur appartient.
Un système de mise en page est un ensemble de groupes de mise en page contigus situés directement au-dessus d'un élément de mise en page. Un élément de mise en page n'est pas seulement le composant Élément de mise en page (images, textes et rectangles de défilement de l'interface utilisateur), il comprend également des éléments de mise en page - de même que les rectangles de défilement sont également des groupes de mise en page.
Maintenant, en ce qui concerne le problème qui nous occupe : Chaque élément d'interface utilisateur qui marque sa mise en page comme "sale" effectuera, au minimum, un appel à GetComponent. Cet appel recherche un groupe de présentation valide sur le parent de l'élément de présentation. S'il en trouve un, il continue à remonter la hiérarchie Transform jusqu'à ce qu'il arrête de chercher des groupes de présentation ou qu'il atteigne la racine de la hiérarchie, selon ce qui se produit en premier. Ainsi, chaque groupe de présentation ajoute un appel GetComponent au processus de nettoyage de chaque élément de présentation enfant, ce qui rend les groupes de présentation imbriqués extrêmement peu performants.
Solution : Évitez autant que possible les groupes de présentation.
Utiliser des ancres pour les mises en page proportionnelles. Dans le cas d'interfaces utilisateur chaudes comportant un nombre dynamique d'éléments d'interface utilisateur, envisagez d'écrire votre propre code pour calculer les mises en page. Veillez à l'utiliser à la demande, plutôt que pour chaque changement.
Pour en savoir plus sur les groupes de présentation, consultez notre documentation.
Problème : La mise en commun des objets de l'interface utilisateur dans le mauvais sens
Les gens mettent souvent en commun les objets de l'interface utilisateur en les répartissant puis en les désactivant, ce qui les salit inutilement.
Solution : Désactivez d'abord l'objet, puis réintégrez-le dans le pool.
Vous salirez l'ancienne hiérarchie une fois, mais une fois que vous l'aurez répartie, vous éviterez de la salir une deuxième fois - et vous ne salirez pas du tout la nouvelle hiérarchie. Si vous retirez un objet du pool, reparentez-le d'abord, mettez à jour vos données, puis activez-le.
En savoir plus sur les concepts de base de la mise en commun d'objets dans Unity.
Problème : Vous ne savez pas comment cacher un Canvas
Il est parfois utile de masquer les éléments d'interface utilisateur et les toiles. Mais comment le faire efficacement ?
Solution : Désactive le composant Canvas lui-même.
La désactivation du composant Canvas empêchera le Canvas d'envoyer des appels de dessin au GPU. De cette manière, le canevas ne sera plus visible. Cependant, le Canvas ne se débarrasse pas de son tampon de vertex, il conserve toutes ses mailles et tous ses vertices. Lorsque vous le réactiverez, il ne déclenchera pas de reconstruction - il recommencera simplement à les dessiner.
En outre, la désactivation du composant Canvas ne déclenche pas les coûteux rappels OnDisable/OnEnable via la hiérarchie Canvas. Veillez simplement à désactiver les composants enfants qui exécutent un code coûteux par image.
Pour en savoir plus sur le composant Canvas, cliquez ici.
Problème : Utiliser des animateurs dans l'interface utilisateur
Les animateurs saliront leurs éléments d'interface utilisateur à chaque image, même si la valeur de l'animation ne change pas.
Solution : Utiliser le code pour l'animation de l'interface utilisateur.
Ne placez des animateurs que sur les éléments dynamiques de l'interface utilisateur qui changent en permanence. Pour les éléments qui changent rarement ou qui changent temporairement en réponse à des événements, écrivez votre propre code ou utilisez un système de transition. Il existe un certain nombre d'excellentes solutions pour cela sur l'Asset Store.
Problème : Mauvaises performances avec l'interface plein écran
Si votre jeu affiche un écran de pause ou de démarrage qui couvre entièrement la scène, le reste du jeu est toujours en cours de rendu en arrière-plan, ce qui peut avoir un impact sur les performances.
Solution : Cachez tout le reste.
Si vous avez un écran qui couvre tout le reste de la scène, désactivez la caméra qui rend la scène 3D. De même, désactivez les éléments du canevas cachés derrière le canevas supérieur.
Envisagez de réduire l'Application.targetFrameRate lors d'une interface utilisateur plein écran, car vous ne devriez pas avoir besoin de mettre à jour à 60 images par seconde.
Offrez à vos joueurs la meilleure expérience de jeu possible. Avec plus de 80 conseils et meilleures pratiques des ingénieurs experts d'Unity, vous pouvez optimiser vos jeux sur PC et sur console.
Créées par les équipes d'ingénieurs Success et Accelerate Solutions d'Unity, ces pratiques détaillées, issues d'engagements réels avec les meilleurs studios, vous aideront à améliorer les performances globales de votre jeu.