Profilage et optimisation d'une construction Unity Web
Cet article fournit des conseils sur la manière d'optimiser vos projets Unity Web.
Précédemment appelée "WebGL", la prise en charge de la plateforme Unity Web comprend des avancées clés qui réduisent les frictions pour un plus grand nombre d'appareils et tirent parti des dernières API graphiques pour garantir des fréquences d'images fluides et des performances exceptionnelles, même pour les jeux Web les plus ambitieux.
Il s'agit notamment de la prise en charge de WebGL, une API JavaScript qui rend les graphiques 2D et 3D à grande vitesse sur les navigateurs. Google Chrome, Mozilla Firefox, Safari et Microsoft Edge prennent tous en charge le contenu WebGL 2. WebGL 2 est basé sur OpenGL ES 3.0
Quelle que soit votre API graphique, vous devez faire en sorte qu'un jeu Web Unity soit de petite taille afin qu'il soit efficace pour la distribution et l'intégration sur les sites Web et les médias sociaux. Vous pouvez également utiliser une version Web pour le prototypage et les sessions de jeux où la facilité de distribution est essentielle, ainsi que pour les tests, même si vous visez une autre plateforme.
Les jeux en ligne ne peuvent pas accéder aux fichiers locaux ou au matériel et ont généralement des performances légèrement inférieures à celles des jeux compilés nativement.
remarque Une nouvelle API, WebGPU, est disponible en accès anticipé dans la version bêta de Unity 6 (2023.3.0b1 bêta). WebGPU est encore en cours de développement et son utilisation n'est pas recommandée pour les cas d'utilisation en production.
WebGPU a été conçu dans le but d'exploiter et d'exposer les capacités modernes des GPU sur le web. Cette nouvelle API web fournit une interface d'accélération graphique moderne qui est mise en œuvre en interne via des API GPU natives, telles que DirectX12, Vulkan et Metal. L'implémentation native spécifique dépendra de la plate-forme du navigateur et des pilotes graphiques disponibles. Des détails sur la façon de commencer, ainsi que des démonstrations supplémentaires de WebGPU, peuvent être trouvés dans le forum graphique.
Pour déployer sur la plateforme Unity Web, vous devez d'abord ajouter le module Web à l'éditeur Unity pour créer une version Web. Trouvez l'installation dans le Hub Unity, cliquez sur l'icône Paramètres et choisissez Ajouter des modules.
Dans la nouvelle boîte de dialogue, faites défiler vers le bas pour trouver Web Build Support, sélectionnez-le et cliquez sur Done.
Rouvrez votre projet et changez de plateforme cible sous Fichier > Paramètres de construction. Utilisez l'option Development Build pendant le développement de votre jeu. Il fournit des informations de débogage supplémentaires, telles que des traces de pile, des messages d'erreur détaillés et des informations de journalisation qui peuvent vous aider à dépanner et à apporter des modifications à votre jeu. Vous pouvez apporter de petites modifications au code, aux ressources ou aux paramètres de votre jeu, puis reconstruire et tester rapidement ces modifications dans le navigateur, sans avoir besoin d'un processus de construction complet.
Veillez simplement à décocher l'option Development Build dans Build Settings pour votre version finale publiée.
Sélectionnez Construire et exécuter pour créer une version de votre jeu qui s'exécute dans un navigateur à des fins de test. Google Chrome est un bon choix pour les tests de jeu, car il fournit un certain nombre d'outils de développement.
Vous serez invité à choisir un emplacement pour la construction. Les fichiers de la compilation comprennent un fichier index.html qui ajoute un élément HTML5 Canvas au modèle d'objet du document (DOM), qui est la représentation des données des objets qui constituent la structure et le contenu d'un document sur le web. Le jeu est rendu sur ce canevas. Les fichiers de construction comprennent également un dossier TemplateData et un dossier Build. Le dossier TemplateData contient les ressources HTML utilisées sur la page, telles que le favicon utilisé dans la barre d'adresse du navigateur et les images utilisées dans le balisage HTML de la page.
Vous pouvez également mettre en place des constructions automatisées, avec Unity Build Automation comme option.
Vous pouvez utiliser le pipeline de rendu intégré ou le pipeline de rendu universel (URP) pour un jeu Web. Cependant, nous recommandons l'URP parce qu'il permet une personnalisation et une mise à l'échelle efficaces du contenu pour plusieurs dispositifs matériels.
Obtenez des instructions approfondies sur la migration de vos projets du Built-in Render Pipeline vers l'URP avec l'e-book Introduction à l'Universal Render Pipeline pour les créateurs Unity avancés.
Lorsque vous visez une console, vous disposez de spécifications exactes pour la mémoire et l'utilisation du CPU et du GPU. Le web est une toute autre chose. Pour que votre jeu soit accessible au plus grand nombre, vous devez vous assurer qu'il fonctionne bien dans un environnement à mémoire restreinte.
Voici quelques conseils tirés de l'e-book sur la manière de faire fonctionner votre jeu en douceur sur du matériel bas de gamme Optimisez les performances de vos jeux mobiles.
1. Optimisez les ressources de votre jeu
Optimisez les ressources telles que les textures et les modèles pour le web, par exemple en utilisant des textures compressées et en réduisant le nombre de polygones dans vos modèles, le cas échéant. Bien qu'il n'y ait pas de règles immuables, convenez de quelques lignes directrices générales au sein de votre équipe afin de garantir la cohérence des performances.
2. Utiliser la mise en commun d'objets
La mise en commun d'objets est une technique qui peut vous aider à améliorer les performances en réutilisant des objets au lieu d'en créer et d'en détruire de nouveaux. Cela peut s'avérer utile pour les jeux comportant de nombreux départs et arrivées. D'autres modèles de programmation, comme le volant d'inertie, peuvent également s'avérer utiles. Voir l'e-book Améliorez votre code avec des modèles de programmation de jeuxpour des conseils avancés sur la façon d'implémenter des modèles de conception dans les projets Unity.
3. Utiliser le pipeline de rendu universel et le batteur SRP
Améliorez les performances grâce au système de mise en lots SRP Batcher d'Unity, qui accélère le rendu par le processeur, en fonction de la scène. Il fonctionne en regroupant les appels de dessin sur la base de propriétés matérielles partagées, telles que les ombres et les textures, ce qui permet de réduire le nombre de changements d'état nécessaires pendant le rendu.
4. Utiliser l'élimination des occlusions
Le système d'occultation d' Unity permet d'améliorer les performances en ne rendant que les objets visibles par le joueur. L'élimination des occlusions fonctionne mieux dans les scènes où de petites zones bien définies sont séparées les unes des autres par des objets de jeu solides, comme des pièces reliées par des couloirs.
5. Utiliser le système LOD (Level of Detail) intégré
Le système LOD intégré à Unity améliore les performances en réduisant la complexité des objets éloignés du joueur. À mesure que la distance entre la caméra et un objet augmente, le système LOD remplace automatiquement la version très détaillée de l'objet par des versions moins détaillées, ce qui réduit la charge de travail liée au rendu tout en conservant une apparence cohérente.
6. Réduisez votre éclairage dans la mesure du possible
Améliorez les performances en calculant à l'avance les informations relatives à l'éclairage de vos scènes à l'aide de cartes lumineuses et de sondes lumineuses.
7. Réduire la création ou la manipulation inutile de chaînes de caractères
En C#, les chaînes sont des types de référence et non des types de valeur. Évitez d'analyser des fichiers de données à base de chaînes, tels que JSON et XML ; stockez plutôt les données dans des objets scriptables ou des formats tels que MessagePack ou Protobuf. Vous pouvez également envisager les formats binaires pour des cas tels que l'enregistrement de données de jeu persistantes (sauvegardes de jeux). Utilisez la classe StringBuilder si vous avez besoin de construire des chaînes de caractères au moment de l'exécution.
8. Testez le système de ressources adressables
Le système d'actifs adressables offre un moyen simplifié de gérer votre contenu en chargeant les AssetBundles par "adresse" ou alias. Ce système unifié se charge de manière asynchrone à partir d'un chemin d'accès local ou d'un réseau de diffusion de contenu (CDN) distant.
9. Limiter les effets de post-traitement
Les effets de post-traitement en plein écran peuvent ralentir les performances, il faut donc les utiliser avec parcimonie dans votre jeu.
Lorsque vous créez une compilation Unity Web, Unity utilise un modèle pour générer la page web qui affichera votre jeu.
Les modèles par défaut sont les suivants
- Par défaut : Une page blanche avec une barre de chargement sur une toile grise
- Minimal : Le modèle minimum nécessaire pour faire fonctionner votre jeu
- Progressive Web App (PWA) : Il s'agit d'un fichier manifeste web et d'un agent de service. Dans un navigateur de bureau approprié, un bouton d'installation s'affiche dans la barre d'adresse pour ajouter le jeu aux applications pouvant être lancées par le joueur.
La manière la plus simple de créer votre propre page HTML personnalisée est de commencer par l'un des trois modèles, que vous pouvez trouver via <UnityInstallation>/PlaybackEngines/ WebGLSupport/ BuildTools/ WebGLTemplates/. Sur Mac, vous trouverez le dossier Unity Installation dans le dossier Applications.
Copiez un modèle, placez-le dans votre propre dossier Project/Assets/WebGLTemplates et renommez-le afin de pouvoir l'identifier ultérieurement. Vous pouvez désormais le personnaliser en fonction du contenu du jeu, du site de déploiement et de la plateforme cible.
Les modèles du dossier WebGLTemplates de votre projet apparaissent dans le panneau Édition > Paramètres du projet... > Lecteur > Résolution et présentation. Le nom du modèle est le même que celui de son dossier. Pour doter cette option d'une vignette, ajoutez une image de 128 x 128 pixels au dossier du modèle et nommez-la thumbnail.png.
Au cours du processus de construction, Unity pré-traite les fichiers modèles et évalue toutes les macros et directives conditionnelles incluses dans ces fichiers. Il trouve et remplace toutes les déclarations de macros par les valeurs fournies par l'éditeur et traite automatiquement tous les fichiers .html, .php, .css, .js et .json dans le dossier du modèle.
Par exemple, regardez cette ligne de code :
<canvas id="unity-canvas" width={{{ WIDTH }}} height={{{ HEIGHT }}} tabindex="-1"></canvas>
Si la largeur par défaut du canevasest fixée à 960 et la hauteur par défaut du canevas à 600 dans le panneau Résolution et présentation, le code se présentera comme suit après le prétraitement :
<canvas id="unity-canvas" width="960" height="600" tabindex="-1"></canvas>.
Les triples accolades indiquent au compilateur de trouver la valeur de la variable indiquée.
Vous trouverez également dans les modèles par défaut des exemples de directives conditionnelles utilisant #if, #else et #endif:
#if EXPRESSION
//Si l'EXPRESSION est évaluée à une valeur vraie
#else
//Si l'EXPRESSION n'est pas évaluée à une valeur vraie
#endif
Si vous souhaitez utiliser un modèle personnalisé, le magasin de ressources Unity propose un certain nombre d'options.
Si vous partagez votre jeu sur une plateforme de jeux par navigateur, vous devrez adapter la page index.html pour qu'elle corresponde à une spécification. Pour savoir comment procéder, consultez la documentation de certaines des plates-formes les plus populaires pour les jeux en ligne :
Vous souhaiterez souvent que votre jeu redimensionne une fenêtre de navigateur pour s'adapter à un design réactif, ce qui nécessite d'adapter le code de chargement. Pour ce faire, vous pouvez utiliser une "promesse" en JavaScript, qui représente une opération qui n'a pas encore été effectuée mais qui devrait l'être dans le futur.
Dans la page index.html de chaque modèle (voir l'exemple de code ci-dessous), recherchez script.onload. Le script.onload est un événement qui se déclenche lorsque le script du moteur Unity a fini de se charger. Juste avant que cela ne se produise, vous avez deux variables globales : myGameInstance, qui contient la référence à l'instance Unity, et myGameLoaded, qui indique si le jeu a fini de se charger ou non et dont la valeur par défaut est false. Ils sont déclarés en tant que var, de sorte qu'ils ont une portée globale et sont accessibles partout dans le script.
La fonction createUnityInstance() est appelée pour créer une nouvelle instance du jeu Unity. Cette fonction renvoie une promesse qui est résolue lorsque le jeu est complètement chargé et prêt à être rendu (le bloc de la promesse createUnityInstance).
Dans then(), myGameInstance se voit attribuer l'instance Unity et myGameLoaded prend la valeur true, ce qui indique que le jeu est maintenant prêt. La fonction resizePage() est ensuite appelée pour définir initialement la taille du jeu, et un récepteur d'événement est ajouté à l'événement de redimensionnement de la fenêtre afin que la taille du jeu puisse être mise à jour chaque fois que la fenêtre est redimensionnée. Voir l'extrait de code ci-dessous.
Nous avons ensuite la fonction resizePage en bas du script, comme le montre l'extrait de code suivant, qui est utilisée pour redimensionner le jeu afin qu'il corresponde à la taille de la fenêtre. Si le jeu est chargé, il définit les valeurs de style pour le canevas qui affiche le jeu afin qu'il corresponde à la taille de la fenêtre, de sorte qu'il remplisse la fenêtre :
function resizePage(){
if (myGameInstance !== undefined && myGameLoaded === true)
{
canvas.style.width = window.innerWidth + 'px' ;
canvas.style.height = window.innerHeight + 'px' ;
}
}
De nombreux jeux qui s'adressent à un navigateur devront interagir avec le code JavaScript pour vous permettre d'appeler des services web afin de prendre en charge les connexions des utilisateurs, les tableaux des meilleurs scores, etc. ou d'interagir avec le DOM du navigateur. Tout JavaScript que vous ajoutez directement, afin qu'il puisse être appelé à partir d'un script C#, doit avoir une extension .jslib et être placé dans le dossier Assets/Plugins . Elle doit être intégrée dans la méthode mergeInto. Deux paramètres sont nécessaires : LibraryManager.library et ensuite un objet JavaScript contenant une ou plusieurs fonctions. Les fonctions sont des fonctions JavaScript standard. GetExchangeRates montre comment utiliser un simple service web JSON ci-dessous.
Lorsque vous créez une version, ces fonctions sont ajoutées au fichier Build/<votre nom de jeu>.framework.js . Vous pouvez appeler ces fonctions à partir d'un script C# en déclarant la fonction en tant que DllImport, comme le montre cet exemple de code :
public class SphereController : MonoBehaviour
{
[DllImport("__Internal")]
private static extern void GetExchangeRates() ;
private void Start()
{
GetExchangeRates();
}
}
Plus d'infos
Outre le fait que C# appelle une fonction JavaScript, JavaScript peut appeler une méthode C#. Le mécanisme en question utilise un protocole de messagerie :
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’)
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’, 5)
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’, ‘A string’)
Pour utiliser SendMessage, vous avez besoin d'une référence à l'instance du jeu dans le champ d'application. La technique habituelle consiste à modifier le fichier index.html en ajoutant une variable globale et en l'assignant dans le bloc then de la promesse script.onload, comme nous l'avons vu précédemment. Cette fonction simple est ajoutée dans le cadre d'un composant MonoBehaviour attaché à un objet de jeu nommé Sphere.
public void SetHeight( float height )
{
Vector3 pos = transform.position ;
pos.y = hauteur ;
transform.position = pos ;
}
Vous pouvez ouvrir la console de Chrome à l'aide de la touche F12 et taper directement :
myGameInstance.SendMessage('Sphere', 'SetHeight', 3)
Appuyez sur Entrée pour appeler la fonction Déplacer la sphère. Le mouvement ne sera reflété dans le rendu que si l'option Exécuter en arrière-plan est activée ou si la valeur de Application.runInBackground est égale à true. En effet, par défaut, le rendu n'a lieu que lorsque la fenêtre du canevas est au premier plan.
Utilisez Debug.Log lors du débogage pour les plates-formes de navigation. Les messages éventuels sont envoyés à la console du navigateur. Pour Chrome, il suffit d'appuyer sur F12 et de passer à l'onglet Console. Mais la classe Debug offre plus d'options. En utilisant Debug.LogError, la console fournira une trace de la pile qui peut être utile.
Plus d'infos
Nous vous recommandons d'utiliser l'option Development Build pendant le développement, mais de décocher cette option lorsque vous déployez votre jeu sur un site réel. Dans le cas d'une version de construction, vous avez la possibilité de procéder à une compression. Il se peut que vous deviez ajuster les paramètres de votre serveur lors de l'utilisation de la compression ; voir le manuel pour des conseils sur la façon de procéder.
Il est important d'établir le profil de votre projet tout au long du cycle de développement afin de détecter à temps les problèmes de performance. Le profileur Unity est un bon outil pour identifier et corriger les goulets d'étranglement dans votre jeu. Il suit l'utilisation du processeur et de la mémoire, ce qui vous aide à identifier les zones de votre jeu qui ont besoin d'être optimisées. Vous pouvez également utiliser l'analyseur de profil, le profileur de mémoire et la superposition de diagnostics Web.
Télécharger l'e-book Guide ultime du profilage des jeux Unity pour en savoir plus sur le profilage dans Unity.
Voyons quelques conseils pour commencer à profiler une version Web d'Unity.
Activer le profileur d'Unity
Allez dans Fichier > Paramètres de construction dans l'éditeur et sélectionnez Construction de développement et Autoconnecter le profileur pour utiliser le profileur avec une construction Web.
Sélectionnez le module Utilisation de l'unité centrale
Utilisez ce module pour analyser les performances de votre code et identifier les zones qui posent des problèmes de performance. Analyser des éléments tels que les appels de fonction, l'exécution de scripts et le ramassage des ordures.
Sélectionnez le module Memory Profiler
Les versions Web d'Unity ont des ressources mémoire limitées par rapport à d'autres plateformes. Utilisez ce module pour analyser l'utilisation de la mémoire de votre application et identifier les domaines à optimiser.
Utiliser le panneau Performance de Chrome DevTools
Chrome DevTools comprend un panneau Performance qui vous aidera à identifier les goulets d'étranglement dans votre jeu. Il propose notamment un panneau Sources pour ajouter des points d'arrêt dans les fichiers JavaScript et un panneau Console pour afficher les messages de débogage et saisir du code JavaScript.
Mesurer les performances sur différents appareils
Cela vous aidera à identifier les problèmes de performance qui peuvent être spécifiques à un appareil ou à un navigateur particulier et à optimiser votre jeu en conséquence.
Réduire le nombre d'appels au tirage au sort
Les appels de dessin sont l'un des principaux goulets d'étranglement en matière de performances pour les constructions Web Unity. Utilisez le Unity Profiler pour identifier les zones présentant un nombre élevé d'appels de dessin et essayez de les réduire.
Analyser les performances sur les appareils bas de gamme
Testez sur des appareils bas de gamme pour vous assurer que votre application est optimisée pour une large gamme de matériel.
Activer l'option "Exécuter en arrière-plan" pendant le profilage
Si l'option Exécuter en arrière-plan est activée dans les paramètres du lecteur WebGL ou si vous activez Application.runInBackground, votre contenu continuera à s'exécuter lorsque le canevas ou la fenêtre du navigateur perd le focus, ce qui peut être utile lors du profilage.
Les versions Web d'Unity sont un excellent moyen de distribuer votre jeu à un large public. Au cours du développement, vous devez vous efforcer de limiter la géométrie et les textures à une taille modeste, de réduire les appels de dessin et d'effectuer des profils et des tests sur un large éventail d'appareils. Enfin, l'utilisation de l'URP permet de garantir des performances solides sur la plus large gamme de matériel.
Plus d'infos
Trucs et astuces pour utiliser le module WebGL d'Unity
Accès anticipé au nouveau backend WebGPU dans Unity 2023.3
Retrouvez tous les e-books et articles avancés d'Unity dans le hub des meilleures pratiques d'Unity.