Optimisez les performances de votre jeu mobile : Conseils d'experts sur les graphiques et les actifs

Notre équipe de réussite intégrée soutient les clients Unity avec leurs problèmes techniques complexes. Nous nous sommes assis avec cette équipe d'ingénieurs logiciels seniors et leur avons demandé de partager une partie de leur expertise sur l'optimisation des jeux mobiles.
Notre équipe Unity Studio Production connaît le code source sur le bout des doigts et travaille avec une pléthore de clients Unity pour les aider à tirer le meilleur parti du moteur. Dans leur travail, ils plongent profondément dans les projets des créateurs pour aider à identifier les points où les performances pourraient être optimisées pour une plus grande vitesse, stabilité et efficacité. Alors que nos ingénieurs commençaient à partager leurs idées sur l'optimisation des jeux mobiles, nous avons rapidement réalisé qu'il y avait beaucoup trop d'excellentes informations pour le seul article de blog que nous avions prévu. Au lieu de cela, nous avons décidé de transformer leur montagne de connaissances en un e-book complet (que vous pouvez télécharger ici), ainsi qu'une série d'articles de blog qui mettent en lumière certains de ces 75+ conseils pratiques.
Dans le dernier volet de cette série d'optimisation, nous nous concentrons sur la façon d'améliorer les performances de vos actifs, de la configuration de votre projet et des graphiques. Au cas où vous les auriez manqués, consultez nos articles précédents sur le profilage, la mémoire et l'architecture du code, ainsi que la physique, l'interface utilisateur et l'audio, pour une image plus complète de la façon d'optimiser votre jeu - ou, téléchargez le e-book gratuit pour un aperçu de tous ces sujets.
Il existe quelques paramètres de projet qui peuvent avoir un impact sur vos performances mobiles.
Réduire ou désactiver la fréquence de l'accéléromètre
Unity interroge l'accéléromètre de votre mobile plusieurs fois par seconde. Désactivez cela s'il n'est pas utilisé dans votre application, ou réduisez sa fréquence pour de meilleures performances.

Désactiver les paramètres de Player ou de qualité inutiles
Dans les paramètres Player, désactivez l'API graphique automatique pour les plateformes non prises en charge afin d'éviter de générer des variantes de shader excessives. Désactivez les architectures cibles pour les anciens CPU si votre application ne les prend pas en charge.
Dans les paramètres Qualité, désactivez les niveaux de qualité inutiles.
Désactiver la physique inutile
Si votre jeu n'utilise pas la physique, décochez Auto Simulation et Auto Sync Transforms. Cela ralentira simplement votre application sans bénéfice discernable.
Choisir le bon taux de rafraîchissement
Les projets mobiles doivent équilibrer les taux de rafraîchissement avec la durée de vie de la batterie et le throttling thermique. Au lieu de pousser les limites de votre appareil à 60 fps, envisagez de fonctionner à 30 fps comme compromis. Unity par défaut à 30 fps pour mobile.
Vous pouvez également ajuster le taux de rafraîchissement dynamiquement pendant l'exécution avec Application.targetFrameRate. Par exemple, vous pourriez descendre en dessous de 30 fps pour des scènes lentes ou relativement statiques et réserver des réglages fps plus élevés pour le gameplay.
Éviter les grandes hiérarchies
Divisez vos hiérarchies. Si vos GameObjects n'ont pas besoin d'être imbriqués dans une hiérarchie, simplifiez le parentage. Des hiérarchies plus petites bénéficient du multithreading pour rafraîchir les Transforms dans votre scène. Des hiérarchies complexes entraînent des calculs de Transform inutiles et un coût plus élevé pour la collecte des ordures.
Voir Optimiser la hiérarchie et cette discussion Unite pour les meilleures pratiques avec les Transforms.
Transformer une fois, pas deux fois
De plus, lors du déplacement des Transforms, utilisez Transform.SetPositionAndRotation pour mettre à jour à la fois la position et la rotation en une seule fois. Cela évite le surcoût de modifier un transform deux fois.
Si vous devez Instancier un GameObject à l'exécution, une simple optimisation consiste à parenté et repositionner lors de l'instanciation :
GameObject.Instantiate(prefab, parent);
GameObject.Instantiate(prefab, parent, position, rotation);
Pour plus de détails sur Object.Instantiate, veuillez consulter la Scripting API.
Supposer que Vsync est activé
Les plateformes mobiles ne rendront pas de demi-images. Même si vous désactivez Vsync dans l'Éditeur (Project Settings > Quality), Vsync est activé au niveau matériel. Si le GPU ne peut pas se rafraîchir assez rapidement, le cadre actuel sera maintenu, réduisant effectivement votre fps.
Le pipeline d'actifs peut avoir un impact dramatique sur les performances de votre application. Un artiste technique expérimenté peut aider votre équipe à définir et à appliquer des formats d'actifs, des spécifications et des paramètres d'importation pour des processus fluides.
Ne comptez pas sur les paramètres par défaut. Utilisez l'onglet de remplacement spécifique à la plateforme pour optimiser les actifs tels que les textures et la géométrie des maillages. Des paramètres incorrects peuvent entraîner des tailles de build plus grandes, des temps de build plus longs et une mauvaise utilisation de la mémoire. Envisagez d'utiliser la fonction Presets pour aider à personnaliser les paramètres de base qui amélioreront un projet spécifique.
Voir ce guide sur les meilleures pratiques pour les actifs artistiques ou consultez ce cours sur l'optimisation de l'art 3D pour les applications mobiles via Unity Learn pour plus de détails.
Importer les textures correctement
La plupart de votre mémoire ira probablement aux textures, donc les paramètres d'importation ici sont critiques. En général, essayez de suivre ces directives :
- Réduisez la taille maximale : Utilisez les paramètres minimaux qui produisent des résultats visuellement acceptables. Ceci est non destructif et peut rapidement réduire votre mémoire de texture.
- Utilisez des puissances de deux (POT) : Unity nécessite des dimensions de texture POT pour les formats de compression de texture mobile (PVRCT ou ETC).
- Atlas vos textures : Placer plusieurs textures dans une seule texture peut réduire les appels de dessin et accélérer le rendu. Utilisez le Unity Sprite Atlas ou le TexturePacker tiers pour atlas vos textures.
- Désactivez l'option Lecture/Écriture activée : Lorsque cette option est activée, elle crée une copie dans la mémoire accessible par le CPU et le GPU, doublant l'empreinte mémoire de la texture. Dans la plupart des cas, gardez cela désactivé. Si vous générez des textures à l'exécution, appliquez cela via Texture2D.Apply, en passant makeNoLongerReadable défini sur true.
- Désactivez les Mip Maps inutiles : Les Mip Maps ne sont pas nécessaires pour les textures qui restent à une taille constante à l'écran, comme les sprites 2D et les graphiques UI (laissez les Mip Maps activées pour les modèles 3D qui varient leur distance par rapport à la caméra).

Compresser les textures
Considérez ces deux exemples utilisant le même modèle et la même texture. Les paramètres à gauche consomment presque huit fois plus de mémoire que ceux à droite, sans beaucoup d'avantage en qualité visuelle.

Utilisez la compression de texture évolutive adaptative (ATSC) pour iOS et Android. La grande majorité des jeux en développement ciblent des appareils min-spec qui prennent en charge la compression ATSC.
Les seules exceptions sont :
- les jeux iOS ciblant les appareils A7 ou inférieurs (par exemple, iPhone 5, 5S, etc.) – utilisez PVRTC
- les jeux Android ciblant des appareils antérieurs à 2016 – utilisez ETC2 (compression de texture Ericsson)
Si des formats compressés tels que PVRTC et ETC ne sont pas suffisamment de haute qualité, et si ASTC n'est pas entièrement pris en charge sur votre plateforme cible, essayez d'utiliser des textures de 16 bits au lieu de textures de 32 bits.
Consultez le manuel pour plus d'informations sur le format de compression de texture recommandé par plateforme.
Ajoutez les paramètres d'importation de maillage
Tout comme les textures, les maillages peuvent consommer une mémoire excessive s'ils ne sont pas importés avec soin. Pour minimiser la consommation de mémoire des maillages :
- Compressez le maillage : Une compression agressive peut réduire l'espace disque (la mémoire à l'exécution, cependant, n'est pas affectée). Notez que la quantification des maillages peut entraîner des inexactitudes, donc expérimentez avec les niveaux de compression pour voir ce qui fonctionne pour vos modèles.
- Désactivez la lecture/écriture : Activer cette option duplique le maillage en mémoire, ce qui garde une copie du maillage dans la mémoire système et une autre dans la mémoire GPU. Dans la plupart des cas, vous devriez le désactiver (dans Unity 2019.2 et antérieur, cette option est cochée par défaut).
- Désactivez les rigs et les BlendShapes : Si votre maillage n'a pas besoin d'animation squelettique ou de BlendShapes, désactivez ces options autant que possible.
- Désactivez les normales et les tangentes : Si vous êtes absolument certain que le matériau du maillage n'aura pas besoin de normales ou de tangentes, décochez ces options pour des économies supplémentaires.

Vérifiez vos comptes de polygones
Des modèles de résolution supérieure signifient une utilisation accrue de la mémoire et potentiellement des temps GPU plus longs. Votre géométrie de fond a-t-elle besoin de cinq cent mille polygones ? Envisagez de réduire les modèles dans votre package DCC de choix. Supprimez les polygones invisibles du point de vue de la caméra, et utilisez des textures et des cartes normales pour les détails fins au lieu de maillages à haute densité.
Automatisez vos paramètres d'importation en utilisant l'AssetPostprocessor
Le AssetPostprocessor vous permet d'exécuter des scripts lors de l'importation d'actifs. Cela vous invite à personnaliser les paramètres avant et/ou après l'importation de modèles, textures, audio, etc.
Utilisez le système d'actifs adressables
Le système d'actifs adressables fournit un moyen simplifié de gérer votre contenu. Ce système unifié charge les AssetBundles par "adresse" ou alias, de manière asynchrone à partir d'un chemin local ou d'un réseau de distribution de contenu (CDN) distant.

Si vous divisez vos actifs non codés (Modèles, Textures, Prefabs, Audio, et même des scènes entières) en un AssetBundle, vous pouvez les séparer en contenu téléchargeable (DLC).
Ensuite, utilisez les Addressables pour créer une version initiale plus petite pour votre application mobile. Cloud Content Delivery vous permet d'héberger et de livrer le contenu de votre jeu aux joueurs au fur et à mesure qu'ils progressent dans le jeu.

Cliquez ici pour voir comment le système d'actifs adressables peut simplifier la gestion des actifs.
À chaque image, Unity détermine les objets qui doivent être rendus puis crée des appels de dessin. Un appel de dessin est un appel à l'API graphique pour dessiner des objets (par exemple, un triangle), tandis qu'un lot est un groupe d'appels de dessin à exécuter ensemble.
À mesure que vos projets deviennent plus complexes, vous aurez besoin d'un pipeline qui optimise la charge de travail sur votre GPU. LePipeline de rendu universel (URP) utilise actuellement un moteur de rendu à passage unique pour offrir des graphismes de haute qualité sur votre plateforme mobile (le rendu différé sera disponible dans les futures versions). Le même éclairage et les mêmes matériaux basés sur la physique des consoles et des PC peuvent également s'adapter à votre téléphone ou tablette.
Les directives suivantes peuvent vous aider à accélérer vos graphiques.
Regroupez vos appels de dessin
Regrouper les objets à dessiner ensemble minimise les changements d'état nécessaires pour dessiner chaque objet dans un lot. Cela conduit à une performance améliorée en réduisant le coût CPU du rendu des objets. Unity peut combiner plusieurs objets en moins de lots en utilisant plusieurs techniques :
- Regroupement dynamique : Pour les petits maillages, Unity peut regrouper et transformer les sommets sur le CPU, puis les dessiner tous en une seule fois. Remarque : N'utilisez cela que si vous avez suffisamment de maillages à faible polygone (moins de 900 attributs de sommet et pas plus de 300 sommets). Le regroupeur dynamique ne regroupera pas les maillages plus grands que cela, donc l'activer gaspillerait du temps CPU à chercher de petits maillages à regrouper à chaque image.
- Regroupement statique : Pour la géométrie non mobile, Unity peut réduire les appels de dessin pour les maillages qui partagent le même matériau. Bien qu'il soit plus efficace que le regroupement dynamique, il utilise plus de mémoire.
- Instanciation GPU : Si vous avez un grand nombre d'objets identiques, cette technique les regroupe plus efficacement grâce à l'utilisation du matériel graphique.
- Regroupement SRP : Activez le Regroupeur SRP dans votre Actif de pipeline de rendu universel sous Avancé. Cela peut accélérer considérablement vos temps de rendu CPU, selon la scène.

Utilisez le Débogueur de cadre
Le Débogueur de cadre montre comment chaque cadre est construit à partir d'appels de dessin individuels. C'est un outil inestimable pour résoudre les problèmes de vos propriétés de shader qui peut vous aider à analyser comment le jeu est rendu.

Nouveau dans le Débogueur de cadre ? Consultez ce tutoriel d'introduction ici.
Évitez trop de lumières dynamiques
Il est crucial d'éviter d'ajouter trop de lumières dynamiques à votre application mobile. Envisagez des alternatives comme des effets de shader personnalisés et des sondes de lumière pour les maillages dynamiques, ainsi que l'éclairage cuit pour les maillages statiques.
Voir ce tableau de comparaison des fonctionnalités pour les limites spécifiques des lumières en temps réel URP et pipeline intégré.
Désactiver les ombres
La projection d'ombres peut être désactivée par MeshRenderer et lumière. Désactivez les ombres chaque fois que possible pour réduire les appels de dessin.
Vous pouvez également créer de fausses ombres en utilisant une texture floue appliquée à un maillage simple ou un quad sous vos personnages. Sinon, vous pouvez créer des ombres en forme de blob avec des shaders personnalisés.

Cuisez votre éclairage dans des Lightmaps
Ajoutez un éclairage dramatique à votre géométrie statique en utilisant l'illumination globale (GI). Marquez les objets avec Contribuer à GI afin que vous puissiez stocker un éclairage de haute qualité sous forme de Lightmaps.
Les ombres et l'éclairage cuits peuvent alors être rendus sans impact sur les performances à l'exécution. Le Lightmapper CPU et GPU Progressif peut accélérer la cuisson de l'illumination globale.

Suivez le manual guide et cet article sur l'optimisation de l'éclairage pour vous aider à commencer avec Lightmapping dans Unity.
Utilisez les couches de lumière
Pour des scènes complexes avec plusieurs lumières, séparez vos objets en utilisant des couches, puis confinez l'influence de chaque lumière à un masque de culling spécifique.

Utilisez des sondes de lumière pour les objets en mouvement
Les sondes de lumière stockent des informations d'éclairage préalablement cuites sur l'espace vide de votre scène, tout en fournissant un éclairage de haute qualité (direct et indirect). Elles utilisent des harmoniques sphériques, qui se calculent très rapidement par rapport aux lumières dynamiques.

Utilisez le niveau de détail (LOD)
À mesure que les objets s'éloignent, le niveau de détail peut les ajuster ou les faire passer à des maillages plus simples avec des matériaux et des shaders plus simples, pour aider les performances du GPU.


Utilisez le culling d'occlusion pour supprimer les objets cachés
Les objets cachés derrière d'autres objets peuvent encore être rendus et coûter des ressources. Utilisez le culling d'occlusion pour les écarter.
Bien que le culling de frustum en dehors de la vue de la caméra soit automatique, le culling d'occlusion est un processus cuit. Il suffit de marquer vos objets comme Occludeurs statiques ou Occlus, puis de cuire à travers le dialogue Fenêtre > Rendu > Culling d'occlusion. Bien que ce ne soit pas nécessaire pour chaque scène, le culling peut améliorer les performances dans de nombreux cas.
Consultez le tutoriel sur le travail avec le culling d'occlusion pour plus d'informations.
Évitez la résolution native mobile
Avec les téléphones et les tablettes devenant de plus en plus avancés, les nouveaux appareils ont tendance à avoir des résolutions très élevées.
Utilisez Screen.SetResolution(width, height, false) pour réduire la résolution de sortie et regagner un peu de performance. Profilez plusieurs résolutions pour trouver le meilleur équilibre entre qualité et vitesse.
Limitez l'utilisation des caméras
Chaque caméra entraîne un certain coût, qu'elle effectue un travail significatif ou non. Utilisez uniquement les composants Camera nécessaires pour le rendu. Sur les plateformes mobiles de bas de gamme, chaque caméra peut utiliser jusqu'à 1 ms de temps CPU.
Gardez les shaders simples
Le pipeline de rendu universel comprend plusieurs shaders légers Lit et Unlit qui sont déjà optimisés pour les plateformes mobiles. Essayez de garder vos variations de shader aussi faibles que possible, car elles peuvent avoir un effet dramatique sur l'utilisation de la mémoire à l'exécution. Si les shaders URP par défaut ne répondent pas à vos besoins, vous pouvez personnaliser l'apparence de vos matériaux en utilisant Shader Graph. Découvrez comment construire vos shaders visuellement en utilisant Shader Graph ici.

Minimisez le surdessin et le mélange alpha
Évitez de dessiner des images transparentes ou semi-transparentes inutiles. Les plateformes mobiles sont fortement impactées par le surdessin et le mélange alpha résultants. Ne superposez pas d'images ou d'effets à peine visibles. Vous pouvez vérifier le surdessin en utilisant le débogueur graphique RenderDoc.
Limitez les effets de post-traitement
Les effets de post-traitement Post-processing en plein écran, comme les lueurs, peuvent ralentir considérablement les performances. Utilisez-les avec prudence dans la direction artistique de votre titre.

Faites attention avec Renderer.material
Accéder à Renderer.material dans les scripts duplique le matériau et renvoie une référence à la nouvelle copie. Cela casse tout lot existant qui inclut déjà le matériau. Si vous souhaitez accéder au matériau de l'objet groupé, utilisez Renderer.sharedMaterial à la place.
Optimisez les SkinnedMeshRenderers
Le rendu des maillages animés est coûteux. Assurez-vous que chaque objet utilisant un SkinnedMeshRenderer en a besoin. Si un GameObject n'a besoin d'animation que parfois, utilisez la fonction BakeMesh pour figer le maillage animé dans une pose statique, puis passez à un MeshRenderer plus simple à l'exécution.
Minimisez les Probes de Réflexion
Un Reflection Probe peut créer des réflexions réalistes, mais peut être très coûteux en termes de lots. Utilisez des cubemaps basse résolution, des masques de culling et de la compression de texture pour améliorer les performances à l'exécution.
C'était le dernier article de blog de la série sur l'optimisation des performances mobiles. Cependant, si vous souhaitez accéder à la liste complète des conseils et astuces de l'équipe, nous avons également publié un e-book de 52 pages disponible ici.

Si vous êtes intéressé à en savoir plus sur les services de support intégré et souhaitez donner à votre équipe un accès direct aux ingénieurs, des conseils d'experts et des orientations sur les meilleures pratiques pour vos projets, consultez les plans de succès de Unity ici.
Vous n'avez pas trouvé ce que vous cherchiez ?
Nous voulons vous aider à rendre vos applications Unity aussi performantes que possible. S'il y a un sujet d'optimisation que vous aimeriez connaître davantage, veuillez nous le faire savoir dans les commentaires.
