Partager via


Recommandations en matière de performances pour Unity

Cet article s’appuie sur les recommandations en matière de performances pour la réalité mixte, mais se concentre sur les améliorations spécifiques à Unity.

Nous avons récemment publié une application appelée Principes de base de la qualité qui couvre les problèmes courants de performances, de conception et d’environnement et les solutions pour les applications HoloLens 2. Cette application est une excellente démonstration visuelle pour le contenu qui suit.

La première étape la plus importante lors de l’optimisation des performances des applications de réalité mixte dans Unity consiste à s’assurer que vous utilisez les paramètres d’environnement recommandés pour Unity. Cet article contient du contenu avec certaines des configurations de scène les plus importantes pour la création d’applications Mixed Reality performantes. La section suivante met en évidence certains de ces paramètres recommandés.

Comment profiler avec Unity

Unity fournit le profileur unity intégré, qui est une excellente ressource pour collecter des informations précieuses sur les performances pour votre application particulière. Bien que vous puissiez exécuter le profileur dans l’éditeur, ces métriques ne représentent pas le véritable environnement d’exécution. Les résultats doivent donc être utilisés avec précaution. Profilez à distance votre application lors de l’exécution sur l’appareil pour obtenir les insights les plus précis et exploitables.

Unity fournit une documentation exceptionnelle pour :

  1. Comment connecter le profileur Unity aux applications UWP à distance
  2. Comment diagnostiquer efficacement les problèmes de performances avec Unity Profiler

Profilage GPU

Profileur Unity

Une fois unity Profiler connecté et après avoir ajouté le profileur GPU (voir Ajouter un profileur en haut à droite), vous pouvez voir combien de temps est passé sur le processeur & GPU respectivement au milieu du profileur. Cela permet au développeur d’obtenir une approximation rapide si son application est limitée par le processeur ou le GPU.

Processeur Unity et GPU

Remarque

Pour utiliser le profilage GPU, vous devez désactiver les travaux graphiques dans les paramètres du lecteur Unity. Pour plus d’informations, consultez le module GPU Usage Profiler d’Unity.

Débogueur d’images Unity

Le débogueur frame d’Unity est également un outil puissant et perspicace à utiliser. Il vous donne une bonne vue d’ensemble de ce que le GPU fait chaque frame. Les éléments à rechercher sont d’autres cibles de rendu et des commandes blit à copier entre elles, car elles sont coûteuses sur HoloLens. Dans l’idéal, aucune cible de rendu hors écran ne doit être utilisée sur HoloLens. Celles-ci sont ajoutées lors de l’activation de fonctionnalités de rendu coûteuses (par exemple, MSAA, HDR ou effets plein écran comme bloom) qui doivent être évitées.

Superposition de fréquence d’images HoloLens

La page Performances du système du portail d’appareil présente un bon résumé des performances du processeur et du GPU de l’appareil. Vous pouvez activer Afficher le compteur de fréquence d’images dans le casque et Afficher le graphique de fréquence d’images dans le casque. Ces options activent respectivement un compteur FPS et un graphe qui vous donnent des commentaires immédiats dans toute application en cours d’exécution sur votre appareil.

PIX

PIX peut également être utilisé pour profiler des applications Unity. Vous trouverez également des instructions détaillées sur l’utilisation et l’installation de PIX pour HoloLens 2. Dans une build de développement, les mêmes étendues que celles que vous voyez dans le débogueur de frame d’Unity sont également affichées dans PIX et peuvent être inspectées et profilées plus en détail.

Remarque

Unity permet de modifier facilement la résolution de la cible de rendu de votre application au moment de l’exécution via la propriété XRSettings.renderViewportScale . L’image finale présentée sur l’appareil a une résolution fixe. La plateforme échantillonne la sortie de résolution inférieure pour créer une image de résolution supérieure pour le rendu sur les écrans.

UnityEngine.XR.XRSettings.renderViewportScale = 0.7f;

Recommandations sur les performances du processeur

Le contenu ci-dessous couvre des pratiques de performances plus approfondies, particulièrement destinées au développement Unity & C#.

Références de cache

Nous vous recommandons de mettre en cache les références à tous les composants et GameObjects pertinents lors de l’initialisation, car les appels de fonction répétitifs tels que GetComponent<T>() et Camera.main sont plus coûteux par rapport au coût de mémoire pour stocker un pointeur. . Camera.main utilise simplement FindGameObjectsWithTag() en dessous, qui recherche dans votre graphique de scène un objet caméra avec la balise « MainCamera ».

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    private Camera cam;
    private CustomComponent comp;

    void Start() 
    {
        cam = Camera.main;
        comp = GetComponent<CustomComponent>();
    }

    void Update()
    {
        // Good
        this.transform.position = cam.transform.position + cam.transform.forward * 10.0f;

        // Bad
        this.transform.position = Camera.main.transform.position + Camera.main.transform.forward * 10.0f;

        // Good
        comp.DoSomethingAwesome();

        // Bad
        GetComponent<CustomComponent>().DoSomethingAwesome();
    }
}

Remarque

Éviter GetComponent(string)
Lorsque vous utilisez GetComponent(), il existe une poignée de surcharges différentes. Il est important de toujours utiliser les implémentations basées sur les types et jamais la surcharge de recherche basée sur les chaînes. La recherche par chaîne dans votre scène est plus coûteuse que la recherche par type.
(Bon) Component GetComponent(Type type)
(Bon) T GetComponent<T>()
(Mauvais) Component GetComponent(string)>

Éviter les opérations coûteuses

  1. Éviter l’utilisation de LINQ

    Bien que LINQ puisse être propre et facile à lire et à écrire, il nécessite généralement plus de calcul et de mémoire que si vous écriviez l’algorithme manuellement.

    // Example Code
    using System.Linq;
    
    List<int> data = new List<int>();
    data.Any(x => x > 10);
    
    var result = from x in data
                 where x > 10
                 select x;
    
  2. API Unity courantes

    Certaines API Unity, bien qu’utiles, peuvent être coûteuses à exécuter. La plupart d’entre eux impliquent la recherche d’une liste correspondante de GameObjects dans l’ensemble de votre graphique de scène. Ces opérations peuvent généralement être évitées en mettant en cache les références ou en implémentant un composant de gestionnaire pour les GameObjects afin de suivre les références au moment de l’exécution.

        GameObject.SendMessage()
        GameObject.BroadcastMessage()
        UnityEngine.Object.Find()
        UnityEngine.Object.FindWithTag()
        UnityEngine.Object.FindObjectOfType()
        UnityEngine.Object.FindObjectsOfType()
        UnityEngine.Object.FindGameObjectsWithTag()
        UnityEngine.Object.FindGameObjectsWithTag()
    

Remarque

SendMessage() et BroadcastMessage() doivent être éliminés à tout prix. Ces fonctions peuvent être de l’ordre de 1000x plus lents que les appels de fonction directs.

  1. Attention à la boxe

    La boxe est un concept de base du langage et du runtime C#. Il s’agit du processus d’encapsulation de variables de type valeur telles que char, int, bool, etc. dans des variables de type référence. Lorsqu’une variable de type valeur est « boxed », elle est encapsulée dans un System.Object, qui est stocké sur le tas managé. La mémoire est allouée et, éventuellement, lorsqu’elle est supprimée, doit être traitée par le garbage collector. Ces allocations et désallocations entraînent un coût de performances et, dans de nombreux scénarios, sont inutiles ou peuvent être facilement remplacées par une alternative moins coûteuse.

    Pour éviter le boxing, assurez-vous que les variables, les champs et les propriétés dans lesquels vous stockez les types numériques et les structs (y compris Nullable<T>) sont typés en tant que types spécifiques tels que int, float? ou MyStruct, au lieu d’utiliser un objet. Si vous placez ces objets dans une liste, veillez à utiliser une liste fortement typée telle que plutôt que List<int>List<object> ou ArrayList.

    Exemple de boxe en C#

    // boolean value type is boxed into object boxedMyVar on the heap
    bool myVar = true;
    object boxedMyVar = myVar;
    

Chemins de code répétitifs

Toutes les fonctions de rappel Unity répétées (par exemple, update) exécutées plusieurs fois par seconde et/ou frame doivent être écrites avec soin. Toutes les opérations coûteuses ici ont un impact énorme et cohérent sur les performances.

  1. Fonctions de rappel vides

    Bien que le code ci-dessous puisse sembler innocent à laisser dans votre application, d’autant plus que chaque script Unity s’initialise automatiquement avec une méthode Update, ces rappels vides peuvent devenir coûteux. Unity opère entre une limite de code managé et non managée, entre le code UnityEngine et votre code d’application. Le basculement de contexte sur ce pont est assez coûteux, même s’il n’y a rien à exécuter. Cela devient particulièrement problématique si votre application a des 100 gameobjects avec des composants qui ont des rappels Unity répétitifs vides.

    void Update()
    {
    }
    

Remarque

Update() est la manifestation la plus courante de ce problème de performances, mais d’autres rappels Unity répétés, tels que les suivants, peuvent être tout aussi mauvais, sinon pire : FixedUpdate(), LateUpdate(), OnPostRender", OnPreRender(), OnRenderImage(), etc.

  1. Opérations pour favoriser l’exécution une fois par image

    Les API Unity suivantes sont des opérations courantes pour de nombreuses applications holographiques. Bien que ce ne soit pas toujours possible, les résultats de ces fonctions peuvent généralement être calculés une seule fois et les résultats réutilisés dans l’application pour une trame donnée.

    a) Il est recommandé de disposer d’une classe ou d’un service Singleton dédié pour gérer votre regard Raycast dans la scène, puis de réutiliser ce résultat dans tous les autres composants de scène, au lieu d’effectuer des opérations Raycast répétées et identiques par chaque composant. Certaines applications peuvent nécessiter des raycasts d’origines différentes ou par rapport à des masque de couche différents.

        UnityEngine.Physics.Raycast()
        UnityEngine.Physics.RaycastAll()
    

    b) Évitez les opérations GetComponent() dans les rappels Unity répétés tels que Update() en mettant en cache les références dans Start() ou Awake()

        UnityEngine.Object.GetComponent()
    

    c) Il est recommandé d’instancier tous les objets, si possible, lors de l’initialisation et d’utiliser le regroupement d’objets pour recycler et réutiliser les GameObjects tout au long de l’exécution de votre application

        UnityEngine.Object.Instantiate()
    
  2. Éviter les interfaces et les constructions virtuelles

    Appeler des appels de fonction via des interfaces ou des objets directs ou appeler des fonctions virtuelles peut souvent être beaucoup plus coûteux que l’utilisation de constructions directes ou d’appels de fonction directs. Si la fonction ou l’interface virtuelle n’est pas nécessaire, elle doit être supprimée. Toutefois, la performance de ces approches vaut la peine d’être un compromis si leur utilisation simplifie la collaboration de développement, la lisibilité du code et la facilité de maintenance du code.

    En règle générale, il est recommandé de ne pas marquer les champs et les fonctions comme étant virtuels, sauf si l’on s’attend clairement à ce que ce membre ait besoin d’être remplacé. Il convient d’être particulièrement prudent pour les chemins de code à haute fréquence qui sont appelés plusieurs fois par image ou même une fois par image, comme une UpdateUI() méthode.

  3. Éviter de passer des structs par valeur

    Contrairement aux classes, les structs sont des types valeur et, lorsqu’ils sont passés directement à une fonction, leur contenu est copié dans un instance nouvellement créé. Cette copie ajoute le coût du processeur, ainsi que davantage de mémoire sur la pile. Pour les petits structs, l’effet est minime et donc acceptable. Toutefois, pour les fonctions appelées à plusieurs reprises chaque frame et fonctions prenant des structs volumineux, si possible modifiez la définition de fonction pour passer par référence. En savoir plus ici

Divers

  1. Physique

    a) En règle générale, le moyen le plus simple d’améliorer la physique consiste à limiter le temps consacré à la physique ou le nombre d’itérations par seconde. Cela réduit la précision de la simulation. Voir TimeManager dans Unity

    b) Les types de collisionneurs dans Unity ont des caractéristiques de performances très différentes. L’ordre ci-dessous répertorie les collisionneurs les plus performants et les moins performants de gauche à droite. Il est important d’éviter les colliders de maillage, qui sont beaucoup plus chers que les collisionneurs primitifs.

    Sphere < Capsule < Box <<< Mesh (Convex) < Mesh (non convexe)

  2. Animations

    Désactivez les animations inactives en désactivant le composant Animator (la désactivation de l’objet de jeu n’aura pas le même effet). Évitez les modèles de conception où un animateur se trouve dans une boucle définissant une valeur sur la même chose. Il y a une surcharge considérable pour cette technique, sans effet sur l’application. En savoir plus ici.

  3. Algorithmes complexes

    Si votre application utilise des algorithmes complexes tels que la cinématique inverse, la recherche de chemin, etc., recherchez une approche plus simple ou ajustez les paramètres pertinents pour leurs performances

Recommandations en matière de performances uc-à-GPU

En règle générale, les performances processeur-gpu se résument aux appels de dessin envoyés aux carte graphiques. Pour améliorer les performances, les appels de tirage doivent être stratégiquement a) réduits ou b) restructurés pour obtenir des résultats optimaux. Étant donné que les appels de dessin eux-mêmes sont gourmands en ressources, les réduire réduira le travail global nécessaire. En outre, les changements d’état entre les appels de dessin nécessitent des étapes de validation et de traduction coûteuses dans le pilote graphique et, par conséquent, la restructuration des appels de dessin de votre application pour limiter les changements d’état (par exemple, différents matériaux, etc.) peut améliorer les performances.

Unity propose un excellent article qui donne une vue d’ensemble et présente les appels de tirage par lot pour leur plateforme.

Rendu d’instance à passe unique

Le rendu d’instance à passe unique dans Unity permet de réduire les appels de dessin pour chaque œil à un appel de dessin instancené. En raison de la cohérence du cache entre deux appels de dessin, il y a également une amélioration des performances sur le GPU.

Pour activer cette fonctionnalité dans votre projet Unity

  1. Ouvrez Les paramètres OpenXR (accédez à Modifier>les paramètres> du projetGestion du> plug-in XROpenXR).
  2. Sélectionnez Single Pass Instanced dans le menu déroulant Mode de rendu .

Lisez les articles suivants d’Unity pour plus d’informations sur cette approche de rendu.

Remarque

Un problème courant avec le rendu d’instance à passe unique se produit si les développeurs ont déjà des nuanceurs personnalisés existants qui n’ont pas été écrits pour l’instanciation. Après avoir activé cette fonctionnalité, les développeurs peuvent remarquer que certains GameObjects ne s’affichent que dans un seul œil. Cela est dû au fait que les nuanceurs personnalisés associés n’ont pas les propriétés appropriées pour l’instanciation.

Traitement par lots statique

Unity est en mesure de traiter par lot de nombreux objets statiques pour réduire les appels de dessin au GPU. Le traitement par lots statique fonctionne pour la plupart des objets Renderer dans Unity qui 1) partagent le même matériau et 2) sont tous marqués comme statiques (sélectionnez un objet dans Unity et cochez la case en haut à droite de l’inspecteur). Les GameObjects marqués comme statiques ne peuvent pas être déplacés dans le runtime de votre application. Par conséquent, le traitement par lots statique peut être difficile à appliquer sur HoloLens, où pratiquement tous les objets doivent être placés, déplacés, mis à l’échelle, etc. Pour les casques immersifs, le traitement par lot statique peut réduire considérablement les appels de dessin et ainsi améliorer les performances.

Pour plus d’informations, consultez Traitement par lot statique sous Traitement par lot d’appels de dessin dans Unity .

Traitement par lots dynamique

Étant donné qu’il est problématique de marquer des objets comme statiques pour le développement HoloLens, le traitement par lot dynamique peut être un excellent outil pour compenser cette fonctionnalité insuffisante. Il peut également être utile sur les casques immersifs. Toutefois, le traitement par lot dynamique dans Unity peut être difficile à activer, car les GameObjects doivent a) partager le même matériau et b) répondre à une longue liste d’autres critères.

Pour obtenir la liste complète, consultez Traitement par lot dynamique sous Lot d’appels de dessin dans Unity . Le plus souvent, les GameObjects deviennent non valides pour être traités dynamiquement, car les données de maillage associées ne peuvent pas être supérieures à 300 sommets.

Autres techniques

Le traitement par lot ne peut se produire que si plusieurs GameObjects sont en mesure de partager le même matériau. En règle générale, cela est bloqué par la nécessité pour gameobjects d’avoir une texture unique pour leur matériau respectif. Il est courant de combiner des textures en une seule grande texture, une méthode connue sous le nom d’atlas de texture.

En outre, il est préférable de combiner des maillages en un Seul GameObject si possible et raisonnable. Chaque renderer dans Unity a son appel de dessin associé au lieu d’envoyer un maillage combiné sous un seul renderer.

Remarque

La modification des propriétés de Renderer.material au moment de l’exécution crée une copie de Material et peut donc interrompre le traitement par lot. Utilisez Renderer.sharedMaterial pour modifier les propriétés de matériau partagé dans GameObjects.

Recommandations en matière de performances GPU

Bande passante et taux de remplissage

Lors du rendu d’une trame sur le GPU, une application est liée par la bande passante mémoire ou la vitesse de remplissage.

  • La bande passante mémoire est le taux de lectures et d’écritures que le GPU peut effectuer à partir de la mémoire
    • Dans Unity, modifiezla qualité de texture dans Modifier >les paramètres>de qualité du projet.
  • Le taux de remplissage fait référence aux pixels qui peuvent être dessinés par seconde par le GPU.

Optimiser le partage de mémoire tampon de profondeur

Nous vous recommandons d’activer le partage de mémoire tampon de profondeur pour optimiser la stabilité de l’hologramme. Lorsque vous activez la reprojection en phase tardive basée sur la profondeur avec ce paramètre, nous vous recommandons de sélectionner le format de profondeur 16 bits au lieu du format de profondeur 24 bits . Les mémoires tampons de profondeur 16 bits réduisent considérablement la bande passante (et donc la puissance) associées au trafic de la mémoire tampon de profondeur. Il peut s’agir d’une grande amélioration de la réduction de la puissance et des performances. Toutefois, il existe deux résultats négatifs possibles en utilisant le format de profondeur 16 bits.

Z-Fighting

La fidélité de la plage de profondeur réduite rend la lutte z plus susceptible de se produire avec 16 bits que 24 bits. Pour éviter ces artefacts, modifiez les plans de découpage proches/lointains de la caméra Unity pour tenir compte de la précision inférieure. Pour les applications basées sur HoloLens, un plan de découpage lointain de 50 m au lieu de 1 000 m par défaut Unity peut généralement éliminer tout combat z.

Mémoire tampon de gabarit désactivée

Quand Unity crée une texture de rendu avec une profondeur de 16 bits, aucune mémoire tampon de gabarit n’est créée. La sélection du format de profondeur 24 bits, comme décrit dans la documentation Unity, crée une mémoire tampon z 24 bits et une mémoire tampon de gabarit 8 bits (si la 32 bits est applicable sur un appareil (par exemple, HoloLens), ce qui est généralement le cas).

Éviter les effets plein écran

Les techniques qui fonctionnent en plein écran peuvent être coûteuses, car leur ordre de grandeur est de millions d’opérations chaque image. Il est recommandé d’éviter les effets de post-traitement tels que l’anticrénelage, le bloom, etc.

Paramètres d’éclairage optimaux

L’illumination globale en temps réel dans Unity peut fournir des résultats visuels exceptionnels, mais implique des calculs d’éclairage coûteux. Nous vous recommandons de désactiver l’illumination globale en temps réel pour chaque fichier de scène Unity via Window>Rendering>Lighting Settings> Désélectionnez Real-time Global Illumination.

En outre, il est recommandé de désactiver tous les clichés instantanés, car ceux-ci ajoutent également des passes gpu coûteuses sur une scène Unity. Les ombres peuvent être désactivées par lumière, mais elles peuvent également être contrôlées de manière holistique via des paramètres de qualité.

Éditer>Paramètres du projet, puis sélectionnez la catégorie >Qualité Sélectionnez Faible qualité pour la plateforme UWP. Vous pouvez également définir la propriété Shadows sur Désactiver les ombres.

Nous vous recommandons d’utiliser un éclairage baked avec vos modèles dans Unity.

Réduire le nombre de poly

Le nombre de polygones est réduit de l’un ou l’autre

  1. Suppression d’objets d’une scène
  2. Décimation des ressources, qui réduit le nombre de polygones pour un maillage donné
  3. Implémentation d’un système de niveau de détail (LOD) dans votre application, qui restitue des objets éloignés avec une version de polygone inférieur de la même géométrie

Présentation des nuanceurs dans Unity

Une approximation simple pour comparer les nuanceurs dans les performances consiste à identifier le nombre moyen d’opérations exécutées par chacun au moment de l’exécution. Cela peut être fait facilement dans Unity.

  1. Sélectionnez votre élément de nuanceur ou un matériau, puis dans le coin supérieur droit de la fenêtre de l’inspecteur. Sélectionnez l’icône d’engrenage suivie de « Sélectionner un nuanceur »

    Sélectionner un nuanceur dans Unity

  2. Une fois la ressource de nuanceur sélectionnée, sélectionnez le bouton « Compiler et afficher le code » sous la fenêtre d’inspecteur

    Compiler le code du nuanceur dans Unity

  3. Après la compilation, recherchez la section statistiques dans les résultats avec le nombre d’opérations différentes pour le nuanceur de vertex et de pixels (Remarque : les nuanceurs de pixels sont souvent également appelés nuanceurs de fragments)

    Opérations du nuanceur unity Standard

Optimiser les nuanceurs de pixels

En examinant les résultats statistiques compilés à l’aide de la méthode ci-dessus, le nuanceur de fragments exécute généralement plus d’opérations que le nuanceur de vertex, en moyenne. Le nuanceur de fragments, également appelé nuanceur de pixels, est exécuté par pixel sur la sortie de l’écran, tandis que le nuanceur de vertex est exécuté uniquement par sommet de tous les maillages dessinés à l’écran.

Ainsi, non seulement les nuanceurs de fragments ont plus d’instructions que les nuanceurs de vertex en raison de tous les calculs d’éclairage, mais les nuanceurs de fragments sont presque toujours exécutés sur un jeu de données plus volumineux. Par exemple, si la sortie de l’écran est une image 2k par 2k, le nuanceur de fragments peut être exécuté 2 000 * 2 000 = 4 000 000 fois. Si vous affichez deux yeux, ce nombre double, car il y a deux écrans. Si une application de réalité mixte a plusieurs passes, des effets de post-traitement en plein écran ou le rendu de plusieurs maillages sur le même pixel, ce nombre augmente considérablement.

Par conséquent, la réduction du nombre d’opérations dans le nuanceur de fragments peut généralement donner des gains de performances bien plus importants que les optimisations dans le nuanceur de vertex.

Alternatives de nuanceur Unity Standard

Au lieu d’utiliser un rendu physique (PBR) ou un autre nuanceur de haute qualité, essayez d’utiliser un nuanceur plus performant et moins cher. Le kit de ressources Mixed Reality fournit le nuanceur standard MRTK qui a été optimisé pour les projets de réalité mixte.

Unity fournit également un nuanceur non éclairé, éclairé par vertex, diffus et d’autres options de nuanceur simplifiées qui sont plus rapides que le nuanceur Unity Standard. Pour plus d’informations, consultez Utilisation et performances des nuanceurs intégrés .

Préchargement du nuanceur

Utilisez le préchargement du nuanceur et d’autres astuces pour optimiser le temps de chargement du nuanceur. En particulier, le préchargement du nuanceur signifie que vous ne verrez aucun problème dû à la compilation du nuanceur d’exécution.

Limiter le dépassement

Dans Unity, vous pouvez afficher overdraw pour leur scène, en basculant le menu du mode dessin dans le coin supérieur gauche de l’affichage Scène et en sélectionnant Overdraw.

En règle générale, le surdraw peut être atténué en éliminant les objets à l’avance avant d’être envoyés au GPU. Unity fournit des détails sur l’implémentation de l’élimination de l’occlusion pour son moteur.

Recommandations relatives à la mémoire

Une allocation de mémoire excessive & des opérations de désallocation peut avoir des effets néfastes sur votre application holographique, entraînant des performances incohérentes, des images figées et d’autres comportements préjudiciables. Il est particulièrement important de comprendre les considérations relatives à la mémoire lors du développement dans Unity, car la gestion de la mémoire est contrôlée par le garbage collector.

Garbage collection

Les applications holographiques perdent le temps de traitement du garbage collector (GC) lorsque celui-ci est activé pour analyser les objets qui ne sont plus dans l’étendue pendant l’exécution et que leur mémoire doit être libérée, afin qu’elle puisse être réutilisée. Les allocations et les désallocations constantes nécessitent généralement que le garbage collector s’exécute plus fréquemment, ce qui nuit aux performances et à l’expérience utilisateur.

L’une des pratiques les plus courantes qui conduit à un nettoyage de la mémoire excessif est de ne pas mettre en cache les références aux composants et aux classes dans le développement Unity. Toutes les références doivent être capturées pendant Start() ou Awake() et réutilisées dans des fonctions ultérieures telles que Update() ou LateUpdate().

Autres conseils rapides :

  • Utiliser la classe C# StringBuilder pour générer dynamiquement des chaînes complexes au moment de l’exécution
  • Supprimer les appels à Debug.Log() quand ils ne sont plus nécessaires, car ils s’exécutent toujours dans toutes les versions de build d’une application
  • Si votre application holographique nécessite généralement beaucoup de mémoire, envisagez d’appeler System.GC.Collect() pendant les phases de chargement, par exemple lors de la présentation d’un écran de chargement ou de transition

Regroupement d’objets

Le regroupement d’objets est une technique couramment utilisée pour réduire le coût de l’allocation continue d’objets et des désallocations. Pour ce faire, allouez un grand pool d’objets identiques et réutilisez les instances inactives disponibles à partir de ce pool au lieu de générer et de détruire constamment des objets au fil du temps. Les pools d’objets sont parfaits pour les composants réutilisables dont la durée de vie est variable au cours d’une application.

Performance au démarrage

Envisagez de démarrer votre application avec une scène plus petite, puis d’utiliser SceneManager.LoadSceneAsync pour charger le reste de la scène. Cela permet à votre application d’accéder à un état interactif aussi rapidement que possible. Il peut y avoir un pic de processeur important pendant l’activation de la nouvelle scène et que tout contenu rendu peut bégayer ou se heurter. Une façon de contourner ce problème consiste à définir la propriété AsyncOperation.allowSceneActivation sur « false » sur la scène en cours de chargement, à attendre que la scène se charge, à effacer l’écran sur noir, puis à la remettre sur « true » pour terminer l’activation de la scène.

N’oubliez pas que pendant le chargement de la scène de démarrage, l’écran de démarrage holographique s’affiche à l’utilisateur.