Amélioration des performances

*Ce contenu est traduit en utilisant l'IA (Beta) et peut contenir des erreurs. Pour consulter cette page en anglais, clique ici.

Cette page décrit les problèmes de performance communs et les meilleures pratiques pour les mitiger.

Calcul du script

Les opérations coûteuses dans le code Lua prennent plus de temps à traiter et peuvent donc avoir un impact sur le taux de cadence d'exécution. À moins qu'il ne soit exécuté en parallèle, le code Lua s'exécute de manière synchrone et bloque le fil principal jusqu'à ce qu'il rencontre une fonction qui génère le fil.

Problèmes communs

  • Des opérations intenses sur les structures de table - Des opérations complexes telles que la serialisation, la désynchronisation et la clonage profondes coûtent un coût de performance élevé, surtout sur les grandes structures de table. Ceci est particulièrement vrai si ces opérations sont récurrentes ou impliquent une itération sur des structures de données très grandes.

  • Événements de haute fréquence - Relier des opérations coûteuses aux événements basés sur le cadre de RunService sans limiter la fréquence à laquelle ces opérations sont répétées à chaque cadre, ce qui entraîne souvent une augmentation inutile du temps de calcul. Ces événements incluent :

Mitigation

  • Invokez le code sur RunService événements, en économisant l'utilisation dans des cas où l'invocation de haute fréquence est essentielle (par exemple, la mise à jour de la caméra). Vous pouvez exécuter la plupart du code dans d'autres événements ou moins souvent dans un boucle.
  • Décomposez de grandes tâches coûteuses en utilisant task.wait() pour répartir le travail sur plusieurs cadres.
  • Identifyez et optimisez inutilement des opérations coûteuses et utilisez multithreading pour des tâches coûteuses qui ne nécessitent pas d'accès au modèlisationde données.
  • Certains scripts côté serveur peuvent bénéficier de génération de code natif, un simple drapeau qui génère un script en code machine plutôt que en code binaire.

MicroProfiler Scopes

LunetteCalcul associé
RunService.PréRenderCode s'exécutant sur l'événement PreRender
RunService.PréSimulationCode s'exécutant sur l'événement Stepped
RunService.PostSimulationCode s'exécutant sur l'événement Heartbeat
RunService.HeartbeatCode s'exécutant sur l'événement Heartbeat

Pour plus d'informations sur le débogage des scripts à l'aide du MicroProfiler, voir la bibliothèque debug, qui inclut des fonctions pour la balise de code et l'amélioration de la spécificité, telles que debug.profilebegin et debug.profileend. Beaucoup de méthodes d'API Roblox appelées par les scripts ont également leurs propres tags de MicroPro

Utilisation de la mémoire du script

Les fuites de mémoire peuvent se produire lorsque vous écrivez des scripts qui consomment de la mémoire que le collecteur de déchets ne peut pas libérer correctement lorsqu'il n'est plus en cours d'utilisation. Les fuites sont spécifiquement omniprésentes sur le serveur, car elles peuvent être en ligne de manière continue pendant de nombreux jours, tandis que une session client est beaucoup plus courte.

Les valeurs de mémoire suivantes dans la Console du développeur peuvent indiquer un problème qui nécessite une enquête plus approfondie :

  • LuaHeap - Un consommation élevée ou croissante suggère une fuite de mémoire.
  • InstanceCount - Croissance cohérente du nombre d'instances - Certains références dans votre code ne sont pas collectées.
  • PlaceScriptMemory - Fournit un script par décomposition du usage de la mémoire.

Problèmes communs

  • Quitter les connexions connectées - Le moteur ne collecte jamais les événements connectés à une instance et n'importe quelle valeur référencée à l'intérieur du rappel connecté. Par conséquent, les connexions actives des événements et du code à l'intérieur des instances connectées, les fonctions connectées et les valeurs référencées à l'intérieur du rappel mémoire, sont hors de portée pour le collecteur de mémoire, même après le déclenchement des événements.

    Bien que les événements soient désconnectés lorsque l'instance à laquelle ils appartiennent est détruite, une erreur commune est d'assumer que cela s'applique à Player objets. Après qu'un utilisateur quitte une expérience,

  • Tables - Insérer des objets dans les tables, mais ne les supprimer pas lorsqu'ils ne sont plus nécessaires cause une consommation de mémoire inutile, surtout pour les tables qui suivent les données de l'utilisateur lorsqu'il rejoint. Par exemple, l'exemple de code suivant crée une table qui ajoute des informations de l'utilisateur à chaque fois qu'un utilisateur rejoint :

    Exemple

    local playerInfo = {}
    Players.PlayerAdded:Connect(function(player)
    playerInfo[player] = {} -- quelques infos
    end)

    Si vous ne supprimez pas ces entrées lorsqu'elles ne sont plus nécessaires, la table continue de grandir en taille et consomme plus de mémoire à mesure que plus d'utilisateurs rejoignent la session. Tout le code qui itère sur cette table devient également plus coûteux en termes de consommation de mémoire au fur et à mesure que la table grandit en taille.

Mitigation

Pour nettoyer toutes les valeurs utilisées pour empêcher les fuites de mémoire :

  • Désconnectez toutes les connexions - Allez dans votre base de code pour vous assurer que chaque connexion est nettoyée via l'un des chemins suivants :

    • Déconnecte manuellement à l'aide de la fonction Disconnect().
    • Destruction de l'instance auquel l'événement appartient avec la fonction Destroy().
    • Destruction de l'objet de script auquel la connexion fait référence.
  • Supprimer les objets et les personnages des joueurs après avoir quitté - Implémenter le code pour assurer que les connexions ne persistent pas après qu'un utilisateur quitte, comme dans l'exemple suivant :

    Exemple

    Players.PlayerAdded:Connect(function(player)
    player.CharacterRemoving:Connect(function(character)
    task.defer(character.Destroy, character)
    end)
    end)
    Players.PlayerRemoving:Connect(function(player)
    task.defer(player.Destroy, player)
    end)

Calcul de la physique

La simulation de physique excessive peut être une cause clé du délai de calcul augmenté par cadre sur le serveur et le client.

Problèmes communs

  • Excessive frequency de saut de physique - Par défaut, la fréquence d'oscillation du comportement est dans mode adaptatif, où les étapes de physique at either 60 Hz, 120 Hz, or 240 Hz, depending on the complexity of the mécanisme de physique.

    Un mode fixe avec une meilleure précision des physiques est également disponible, ce qui oblige toutes les assemblées de physiques à se déplacer à 240 Hz (quatre fois par frame). Cela donne lieu à un calcul plus important à chaque frame.

  • Nombre excessif de complexité des objets simulés - Plus il y a d'assemblages 3D simulés, plus longues sont les calculs physiques à chaque cadre. Généralement, les expériences auront des objets simulés qui ne nécessitent pas d'être ou auront des mécanismes qui ont plus de contraintes et de jointures qu'ils ne le nécessitent.

  • Detection de collision sur mesure précise - Les pièces de maillage ont une propriété CollisionFidelity pour détecter la collision qui offre une variété de modèles avec différents niveaux d'impact de performance. Mode de détection de collision de maillage précis pour les pièces avec le coût de performance le plus élevé et prend plus de temps à calculer.

Mitigation

  • Ancrez les parties qui ne nécessitent pas de simulateur - Ancrez toutes les parties qui ne nécessitent pas d'être conduites par la physique, telles que pour les NPC statiques.

  • Utiliser adaptive physics stepping. - Adaptive stepping dynamique ajuste dynamiquement le taux de calculs physiques pour les mécanismes physiques, ce qui permet aux mises à jour physiques d'être effectuées moins souvent dans certains cas.

  • Réduisez la complexité du mécanisme * Dans la mesure du possible, minimisez le nombre de contraintes ou de jointures physiques dans une assemblage.

    • Réduisez le nombre de collisions d'auto-destruction dans un mécanisme, telles que les limites ou les contraintes de non-collision pour les membres de ragdoll pour les empêcher de se collider entre eux.
  • Réduisez l'utilisation de la fidélité de collision précise pour les maillages * Pour les objets petits ou non interactables où les utilisateurs remarqueront rarement la différence, utilisez la fidélité de la boîte.

    • Pour les objets de taille small-medium, utilisez les fidélités de boîte ou de coque, en fonction de la forme.

    • Pour les objets de grande taille et très complexes, construisez des collisions personnalisées en utilisant des parties invisibles lorsque possible.

    • Pour les objets qui ne nécessitent pas de collisions, désactivez les collisions et utilisez la fidélité de la boîte ou du hull, car la géométrie de collision est toujours stockée en mémoire.

    • Vous pouvez rendre la géométrie de collision pour les besoins de débogage dans Studio en basculant sur la fidélité de la collision dans le widget Options de visualisation dans le coin supérieur droit de la fenêtre de jeu3D.

      Alternativement, vous pouvez appliquer le filtre CollisionFidelity = Precise à l' Explorateur qui montre le nombre de toutes les parties de maillage avec la précision fidelity et vous permet de les sélectionner facilement.

    • Pour une explication détaillée sur la façon de choisir une option de fidélité de collision qui équilibre vos exigences de précision et de performance, voir Définir les paramètres physiques et de rendu.

MicroProfiler Scopes

LunetteCalcul associé
physiqueCalcul de la physique globale
étape de mondePas de mesures physiques prises pour chaque cadre

Utilisation de la mémoire physique

La physique de déplacement et de détection de collision consomme de la mémoire. Les parties maillées ont une propriété CollisionFidelity qui détermine l'approche utilisée pour évaluer les limites de collision du maillage.

Problème commun

Les modes de détection de collision par défaut et précis consomment beaucoup plus de mémoire que les deux autres modes avec des formes de collision de faible fidélité.

Si vous voyez des niveaux élevés de consommation de mémoire sous PhysicsParts , vous devrez peut-être explorer la réduction de la fidélité des collisions des objets dans votre expérience.

Comment mitiger

Pour réduire la mémoire utilisée pour la fidélité de la collision :

  • Pour les parties qui ne nécessitent pas de collisions, désactivez leurs collisions en définissant BasePart.CanCollide, BasePart.CanTouch et BasePart.CanQuery à 1> false1> .
  • Réduisez la fidélité des collisions en utilisant la valeur de CollisionFidelity. Box a le plus faible paramètrede mémoire et Default et 1> Enum.CollisionFidel
    • Il est généralement sûr de définir la fidélité de collision de n'importe quelle petite partie ancrée à Box .
    • Pour les mailles de grande taille très complexes, vous voudrez peut-être construire votre propre maillage de collision à partir d'objets plus petits avec une fidélité de collision de boîte.

Humanoïdes

Humanoid est une classe qui fournit une gamme de fonctionnalités pour les personnages joueur et non joueur (NPC). Bien que puissant, un Humanoid vient avec un coût de calcul important.

Problèmes communs

  • Quitter tous les types d'état humanoïde activés sur les NPCs - Il y a un coût de performance à quitter certains types d'état HumanoidStateTypes activés. Désactivez n'importe lequel qui n'est pas nécessaire pour vos NPCs. Par exemple, sauf que votre NPC n'ira pas escalader les écheiers, il est sûr de désactiver l'état
  • Instantiation, modification et réapparition de modèles avec des humanoïdes fréquemment * Ceci peut être inténsif pour le moteur de traiter, en particulier si ces modèles utilisent Vêtements à plusieurs niveaux . Cela peut également être particulièrement problématique dans les expériences où les avatars réapparaissent souvent.
    • Dans le MicroProfiler , les tags de longueur updateInvalidatedFastClusters (plus de 4 ms) sont souvent un signal que l'instantiation d'avatar/de modification déclenche des invalidations excessives.
  • Utiliser les humanoides dans les cas où ils ne sont pas requis - Les NPC statiques qui ne se déplacent pas généralement n'ont pas besoin de la classe Humanoid.
  • Jouer des animations sur un grand nombre de PNJ sur le serveur - Les animations PNJ qui s'exécutent sur le serveur doivent être simulées sur le serveur et répliquées au client. Cela peut être inutile.

Mitigation

  • Jouez des animations NPC sur le client - Dans les expériences avec un grand nombre de NPCs, considérez la création du Animator sur le client et l'exécution des animations localement. Cela réduit le chargement sur le serveur et le besoin d'une réplication inutile. Il rend également des optimisations supplémentaires possibles (telles que la seule lecture des animations pour les NPCs qui sont près du personnage).
  • Utiliser des alternatives performantes aux humanoïdes - Les modèles NPC n'ont pas nécessairement besoin de contenir un objet humanoïde.
    • Pour les NPC statiques, utilisez un simple AnimationController, car ils n'ont pas besoin de se déplacer mais ils doivent simplement jouer des animations.
    • Pour déplacer des NPCs, considérez l'ajout d'un contrôleur de déplacement personnalisé et l'utilisation d'un AnimationController pour les animations, en fonction de la complexité de vos NPCs.
  • Désactiver les états humanoïdes inutilisés - Utilisez Humanoid:SetStateEnabled() pour activer uniquement les états nécessaires pour chaque humanoïde.
  • Modèles de PNJ de piscine avec réapparition fréquente - Au lieu de détruire un PNJ entier, envoyez le PNJ dans une piscine de NPC inactifs. De cette façon, lorsqu'un nouveau PNJ est nécessaire pour réapparaître, vous pouvez simplement réactiver l'un des PNJ de la piscine. Ce processus est appelé le pooling, ce qui minimise le nombre de fois que les personnages doivent être instantanés.
  • Ne générer des PNJ que lorsque les utilisateurs sont à proximité - Ne générer pas de PNJ lorsque les utilisateurs ne sont pas dans la portée, et les supprimer lorsque les utilisateurs quittent leur portée.
  • Évitez de faire des modifications à la hiérarchie de l'avatar après qu'il soit initialisé - Certaines modifications à une hiérarchie d'avatar ont des implications de performance importantes. Certaines optimisations sont disponibles :
    • Pour les animations procédurales personnalisées, ne mettez pas à jour les propriétés JointInstance.C0 et JointInstance.C1. Au lieu de cela, mettez à jour la propriété Motor6D.Transform.
    • Si vous devez attacher des objets BasePart à l'avatar, faites-le en dehors de la hiérarchie de l'avatar Model.

MicroProfiler Scopes

LunetteCalcul associé
stepHumanoïdeContrôle et physique humanoïde
stepAnimationanimationsd'humanoïde et d'animation
mettre à jour les Clusters rapides non validesassocié à l'instantiation ou à la modification d'un avatar

Rendu

Une partie significative du temps que le client dépense chaque cadre est sur la rendu du scène dans le cadre actuel. Le serveur ne fait aucun rendu, donc cette section est exclusive au client.

Calls de dessin

Un appel de dessin est un ensemble d'instructions du moteur au GPU pour rendre quelque chose. Les appels de dessin ont une charge de travail importante. Généralement, plus le nombre d'appels de dessin par frame est bas, moins le temps de calcul est dépensé pour rendre un frame.

Vous pouvez voir combien de demandes de dessin sont actuellement en cours avec l'élément Statistiques de rendu > Timing dans Studio. Vous pouvez afficher Statistiques de rendu dans le client en appuyant sur 1> Maj1> 3> F23>.

Plus il y a d'objets à dessiner dans votre scène dans un cadre donné, plus il y a de demandes de dessin faites au niveau du processeur. Cependant, le moteur Roblox utilise un processus appelé instancing pour collapsuler des mailles identiques avec les mêmes caractéristiques de texture dans un seul appel de dessin. Spécifiquement, plusieurs mailles avec le même MeshId sont gérées dans un seul appel de dessin lorsque :

D'autres problèmes communs

  • une trop grande densité d'objets - Si un grand nombre d'objets sont concentrés avec une forte densité, le rendu de cette zone de la scène nécessite plus d'appels de dessin. Si vous trouvez que votre cadence de cadre tombe lorsque vous regardez une certaine partie de la carte, cela peut être un bon signal que la densité d'objets dans cette zone est trop élevée.

    Les objets comme les autocollants, les textures et les particules ne se battent pas bien et introduisent des appels de dessin supplémentaires. Accordez une attention supplémentaire à ces types d'objets dans une scène. En particulier, les modifications de propriété à ParticleEmitters peuvent avoir un impact dramatique sur les performances.

  • Opportunités d'initialisation manquées - souvent, une scène inclura le même maillage dupliqué plusieurs fois, mais chaque copie du maillage a des ID de maillage ou de texture différents. Cela empêche l'initialisation et peut entraîner des appels de dessin inutiles.

    Une cause commune de ce problème est lorsque une scène entière est importée à la fois, plutôt que des ressources individuelles importées dans Roblox et ensuite dupliquées post-importation pour assembler la scène.

  • Excessive object complexity - Bien que ce ne soit pas aussi important que le nombre de calles de dessin, le nombre de triangles dans une scène affecte la durée de rendu d'un cadre. Les scènes avec un très grand nombre de meshes très complexes sont un problème commun, comme les scènes avec la propriété MeshPart.RenderFidelity définie sur trop de meshes.

  • Casting d'ombre excessif - Gérer les ombres est un processus coûteux, et les cartes qui contiennent un grand nombre et une densité élevée d'objets d'ombre qui castent des ombres (ou un grand nombre et une densité élevée de petites parties affectées par les ombres) ont probablement des problèmes de performance.

  • Haut de la transparence surdimensionnée - Placer des objets avec une transparence partielle l'un près de l'autre force l'Engine à rendre les pixels voisins plusieurs fois, ce qui peut nuire aux performances. Pour plus d'informations sur l'identification et la résolution de ce problème, voir Supprimer les transparences imbriquées .

Mitigation

  • Instancing identical meshes and reducing the amount of unique meshes - If you ensure all identical meshes to have the same underlying asset IDs, the engine can recognize and render them in a single draw call. Make sure to only upload each mesh in a map once and then duplicate them in Studio for reuse rather than importing large maps as a whole, which might cause identical meshes to have separate content IDs and be recognized as unique assets by the engine. Packages
  • Élimination. - L'élimination décrit le processus d'élimination des appels de dessin pour les objets qui ne facturent pas partie dans le cadre final rendu. Par défaut, le moteur saute les appels de dessin pour les objets en dehors du champ de vision de la caméra (frustum culling), mais ne saute pas les appels de dessin pour les objets occlus par d'autres
    • Masquer MeshPart et BasePart qui sont loin de la caméra ou du paramètre.
    • Pour les environnements intérieurs, implémentez un système de salle ou de portail qui masque les objets non actuellement occupés par les utilisateurs.
  • Réduction de la fidélité du rendu - Définir la fidélité du rendu sur Automatique ou Performance . Cela permet aux mailles de revenir à des alternatives plus complexes, ce qui peut réduire le nombre de polygones qui doivent être dessinés.
  • Désactivation de la restauration d'ombres sur les parties et objets d' lumière appropriés - La complexité des ombres dans une scène peut être réduite en désactivant sélectivement les propriétés de restauration d'ombres sur les parties et les objets. Cela peut être fait au moment de l'édition ou dynamiquement au moment de l'exécution. Certains exemples sont :
    • Utilisez la propriété BasePart.CastShadow pour désactiver le castage d'ombre sur les petites parties où les ombres ne sont probablement pas visibles. Cela peut être particulièrement efficace lorsque s'applique uniquement aux parties qui sont loin de la caméra de l'utilisateur.

    • Désactivez les ombres sur les objets en mouvement si possible.

    • Désactiver Light.Shadows sur les instances de lumière où l'objet n'a pas besoin de lancer d'ombres.

    • Limitez la portée et l'angle des instances de lumière.

    • Utilisez moins d'instances de lumière.

MicroProfiler Scopes

LunetteCalcul associé
Préparer et exécuterRendu global
Perform/Événement/計算光源PerformMises à jour grille légère et ombre
LightGridCPUMises à jour de la grille de lumière Voxel
Système de cartes d'ombreMise en lumière
Perform/Événement/Mise à jour de la vuePréparation des mises à jour rendu et particules
Perform/Scène/RenderViewRendu et post- traitement

Réseau et réplication

La mise en réseau et la réplication décrivent le processus par lequel les données sont envoyées entre le serveur et les clients connectés. Les informations sont envoyées entre le client et le serveur chaque cadre, mais de plus grandes quantités d'informations nécessitent plus de temps de calcul.

Problèmes communs

  • Excédentiel trafic distant - L'envoi d'une grande quantité de données via RemoteEvent ou RemoteFunction objets ou en les invoquant très souvent peut entraîner une grande quantité de temps de traitement des paquets entrants à chaque cadre. Les erreurs courantes incluent :

    • Répliquer les données chaque cadre qui n'a pas besoin d'être répliqué.
    • Réplication des données sur l'entrée de l'utilisateur sans mécanisme pour les ralentir.
    • Déivery plus de données que ce qui est requis. Par exemple, envoyer l'inventaire entier du joueur lorsqu'il achète un article plutôt que les détails de l'article acheté.
  • Création ou suppression d'arbres d'instance complexes - Lorsqu'une modification est apportée au modèle de données sur le serveur, il est répliqué aux clients connectés. Cela signifie que la création et la destruction de grandes hiérarchies d'instance comme des cartes au moment de l'exécution peut être très intensive.

    Un coupable ordinaire ici est les données d'animation complexes sauvegardées par les plugins de l'éditeur d'animation dans les scripts. Si ces données ne sont pas supprimées avant la publication du jeu et que le modèle animé est cloné régulièrement, une grande quantité de données sera répliquée inutilement.

  • TweenService côté serveur - Si Class.TweenService est utilisé pour tweener un serveur côté objet, la propriété tweenée est répliquée à chaque client chaque cadre. Non seulement cela résulte en un tweening jittery comme le client latence varie, mais il cause beaucoup de trafic réseau inutile.

Mitigation

Vous pouvez utiliser les tactiques suivantes pour réduire la réplication inutile :

  • Évitez d'envoyer de grandes quantités de données à la fois via des événements à distance . Au lieu de cela, ne envoyez que les données nécessaires à une fréquence plus basse. Par exemple, pour l'état d'un personnage, répliquez-le lorsqu'il change plutôt que chaque cadre.
  • Élémenter les arbres d'instance complexes comme les cartes et les charger en pièces pour distribuer le travail de réplication de ces éléments sur plusieurs cadres.
  • Nettoyer les métadonnées d'animation , en particulier le dossier d'animation des bateaux, après l'importation.
  • Limite la réplication d'instance inutile , surtout dans les cas où le serveur n'a pas besoin d'avoir connaissance des instances créées. Cela inclut :
    • Les effets visuels tels qu'une explosion ou un sort magique. Le serveur ne doit connaître que le lieu pour déterminer le résultat, tandis que les clients peuvent créer des visuels localement.
    • Modèles de vue d'objet en première personne.
    • Tweetez des objets sur le client plutôt que le serveur.

MicroProfiler Scopes

LunetteCalcul associé
Packets de processusTraitement des paquets réseau entrants, tels que les invocations d'événements et les modifications de propriété
Allouer de la bande et exécuter des envoyeursÉvénements sortants pertinents sur les serveurs

Utilisation de la mémoire des ressources

Le mécanisme d'impact le plus élevé disponible pour les créateurs pour améliorer l'utilisation de la mémoire du client est d'activer streaming d'instance.

Diffusion en continu

La sélection de chargement des instances charge partiellement des parties du modèle de données qui ne sont pas requises, ce qui peut entraîner un temps de chargement nettement réduit et augmenter la capacité du client à empêcher les crashes lorsqu'il sous-tire la pression de la mémoire.

Si vous rencontrez des problèmes de mémoire et que la mise à jour de votre expérience est désactivée, considérez de mettre à jour votre expérience pour la soutenir, surtout si votre monde 3D est grand. La mise à jour de votre expérience est basée sur la distance dans l'espace 3D, donc les mondes plus grands bénéficient naturellement plus en y étant.

Si la diffusion en continu est activée, vous pouvez augmenter l'agressivité. Par exemple, considérez :

  • Réduction de l'utilisation de la persistance StreamingIntegrity .
  • Réduction du rayon de diffusion en continu .

Pour plus d'informations sur les options de diffusion en continu et leurs avantages, voir propriétés de diffusion en continu.

D'autres problèmes communs

  • Duplication des ressources - Un erreur commun est de télécharger le même contenu plusieurs fois ce qui donne différents ID de ressources. Cela peut entraîner le même contenu chargé dans la mémoire plusieurs fois.
  • Volume de ressources excessif - Même lorsque les ressources ne sont pas identiques, il y a des cas où les opportunités de réutiliser la même ressource et d'économiser de la mémoire sont manquées.
  • Fichiers audio - Les fichiers audio peuvent être un contributeur surprenant à l'utilisation de la mémoire, en particulier si vous les chargez tous dans le client à la fois plutôt que de charger seulement ce dont vous avez besoin pour une partie de l'expérience. Pour les stratégies, voir Temps de chargement.
  • Haute résolution des textures - La consommation de mémoire des graphiques pour une texture n'est pas liée à la taille de la texture sur le disque, mais plutôt au nombre de pixels dans la texture.
    • Par exemple, une texture de pixel 1024x1024 consomme 4 fois la mémoire graphique d'une texture 512x512.
    • Les images téléchargées sur Roblox sont transcodées en un format fixe, il n'y a donc pas d'avantage de mémoire à télécharger des images dans un modèle de couleurs associé à moins de octets par pixel. De même, le comprimage des images avant le téléchargement ou la suppression du canal alpha des images qui ne le nécessitent pas peut réduire la taille des images sur le disque, mais il n'améliore pas ou n'améliore
    • Vous pouvez identifier la consommation de mémoire graphique pour une texture donnée en élargissant la catégorie GraphicsTexture dans la Console de développeur.

Mitigation

  • Ne téléchargez des ressources que une fois - Réutilisez le même ID de ressource sur les objets et assurez-vous que les mêmes ressources, telles que les maillages et les images, ne sont pas téléchargées séparément plusieurs fois.
  • Trouver et réparer les ressources en double - Recherchez des parties de maillage identiques et des textures qui sont téléchargées plusieurs fois avec différents ID.
    • Bien qu'il n'y ait pas d'API pour détecter la similitude des ressources automatiquement, vous pouvez collecter tous les ID des ressources d'image dans votre lieu (manuellement ou avec un script), les télécharger et les comparer en utilisant des outils de comparaison externes.
    • Pour les parties de maillage, la meilleure stratégie est d'utiliser des ID de maillage uniques et de les organiser par taille pour les identifier manuellement dupliquées.
    • Au lieu d'utiliser des textures séparées pour différentes couleurs, téléchargez une seule texture et utilisez la propriété SurfaceAppearance.Color pour appliquer différents tons à elle.
  • Importer des ressources dans la carte séparément. - Au lieu d'importer une carte entière à la fois, importer et reconnaître les ressources dans la carte individuellement et les reconnaître. Le 3D importer ne fait aucun dupliqué de maillages, donc si vous importiez une grande carte avec beaucoup de séparés carreaux de sol, chacun d'eux serait import
  • Limitez les pixels des images à un maximum de 512x512 pixels. À moins qu'une image ne couvre une grande partie de l'espace physique sur l'écran, il est généralement nécessaire. Si une image est inférieure à 256x256 pixels, elle doit généralement être plus petite.
  • Utiliser des feuilles de découpe pour garantir une réutilisation maximale des textures dans les cartes 3D. Pour les étapes et les exemples sur la façon de créer des feuilles de découpe, voir Créer des feuilles de découpe .

Charges de temps

De nombreuses expériences implémentent des écrans de chargement personnalisés et utilisent la méthode ContentProvider:PreloadAsync() pour demander des ressources afin que les images, les sons et les maillages soient téléchargés dans le background.

L'avantage de cette approche est que vous pouvez vous assurer que des parties importantes de votre expérience sont chargées entièrement sans pop-in. Cependant, une erreur courante est d'utiliser trop d'actifs pour prédéfinir plus de ressources que ne sont pas réellement requises.

Un exemple de mauvaise pratique est de charger le tout entierWorkspace . Bien que cela puisse empêcher l'affichage de la texture pop-in, il augmente également le temps de chargement de manière significative.

Au lieu de cela, utilisez seulement ContentProvider:PreloadAsync() dans les situations nécessaires, qui incluent :

  • Images dans l'écran de chargement.
  • Importez des images dans votre menu d'expérience, telles que les arrière-plans de boutons et les icônes.
  • Ressources importantes dans la zone de démarrage ou d'apparition.

Si vous devez charger un grand nombre de ressources, nous vous recommandons de fournir un bouton Ignorer le chargement .