Mejore el rendimiento

*Este contenido se traduce usando la IA (Beta) y puede contener errores. Para ver esta página en inglés, haz clic en aquí.

Esta página describe los problemas comunes de rendimiento y las mejores prácticas para mitigarlos.

Compilación de scripts

Las operaciones costosas en el código Luau tardan más en procesarse y pueden así afectar la tasa de marco.A menos que se ejecute en paralelo, el código de Luau se ejecuta de forma sincronizada y bloquea el hilo principal hasta que encuentre una función que devuelva el hilo.

Problemas comunes

  • Operaciones intensivas en estructuras de tabla - Las operaciones complejas como la serialización, la deserialización y la clonación profunda incurren en un alto costo de rendimiento, especialmente en estructuras de tabla grandes.Esto es particularmente cierto si estas operaciones son recursivas o implican iterar sobre estructuras de datos muy grandes.

  • Eventos de alta frecuencia - Vincular operaciones costosas a eventos basados en marcos de RunService sin limitar la frecuencia significa que estas operaciones se repiten en cada marco, lo que a menudo resulta en un aumento innecesario del tiempo de cálculoEstos eventos incluyen:

Mitigación

  • Invoca código en eventos RunService esporádicamente, limitando el uso a casos en los que la invocación de alta frecuencia es esencial (por ejemplo, actualizar la cámara).Puedes ejecutar la mayor parte del código restante en otros eventos o con menos frecuencia en un bucle.
  • Divide tareas grandes o costosas usando task.wait() para distribuir el trabajo en múltiples marcos.
  • Identifica y optimiza operaciones innecesariamente costosas y usa multihilos para tareas costosas de cómputo que no necesitan acceder al modelo de datos.
  • Ciertos scripts del lado del servidor pueden beneficiarse de generación de código nativo, una bandera simple que compila un script a código de máquina en lugar de código de bytes.

Alcances de perfiladoros micro

AlcanceComputación asociada
PreRender de servicio.RunServiceCódigo que se ejecuta en el evento PreRender
Ejecutar servicio.PreSimulaciónCódigo que se ejecuta en el evento Paso a paso
Ejecutar servicio.PostsimulaciónCódigo que se ejecuta en el evento de latido
Corazón de servicio. latidoCódigo que se ejecuta en el evento de latido

Para obtener más información sobre la depuración de scripts con el MicroProfiler, consulte la biblioteca debug, que incluye funciones para etiquetar código específico y aumentar aún más la especificidad, como debug.profilebegin y debug.profileend.Muchos métodos de API de Roblox llamados por scripts también tienen sus propias etiquetas de MicroProfiler asociadas que pueden proporcionar una señal útil.

Uso de la memoria de script

Los fallos de memoria pueden ocurrir cuando escribes scripts que consumen memoria que el recolector de basura no puede liberar correctamente cuando ya no está en uso.Las fugas son específicamente persistentes en el servidor, porque pueden estar en línea continuamente durante muchos días, mientras que una sesión de cliente es mucho más corta.

Los siguientes valores de memoria en la Consola del desarrollador pueden indicar un problema que necesita una investigación adicional:

  • LuaHeap - Un consumo alto o creciente sugiere una fuga de memoria.
  • Número de instancias - Consistente en aumentar constantemente el número de instancias sugiere que las referencias a algunas instancias en tu código no se están recolectando de forma consistente.
  • Memoria de script de lugar - Proporciona un script por desglose de uso de memoria.

Problemas comunes

  • Dejar conexiones conectadas - El motor nunca recoge eventos de basura conectados a una instancia y cualquier valor referenciado dentro del llamado conectado.Por lo tanto, las conexiones activas de eventos y código dentro de las instancias conectadas, las funciones conectadas y los valores referenciados están fuera de alcance para el recolector de basura de memoria, incluso después de que se activen los eventos.

    Aunque los eventos se desconectan cuando la instancia a la que pertenecen se destruye, un error común es asumir que esto se aplica a los objetos Player .Después de que un usuario abandone una experiencia, el motor no destruye automáticamente el objeto y el modelo de personaje representativo Player del usuario, por lo que las conexiones al objeto Player y las instancias bajo el modelo de personaje, como Player.CharacterAdded, siguen consumiendo memoria si no los desconectas en tus guiones.Esto puede resultar en fugas de memoria muy significativas con el tiempo en el servidor a medida que cientos de usuarios se unan y abandonen la experiencia.

  • Tablas -Insertar objetos en tablas pero no eliminarlos cuando ya no se necesitan causa un consumo innecesario de memoria, especialmente para las tablas que rastrean los datos del usuario cuando se unen.Por ejemplo, el siguiente ejemplo de código crea una tabla que agrega información de usuario cada vez que se une un usuario:

    Ejemplo

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

    Si no elimina estas entradas cuando ya no se necesitan, la tabla continúa creciendo en tamaño y consume más memoria a medida que más usuarios se unen a la sesión.Cualquier código que itera sobre esta tabla también se vuelve más costoso de computar a medida que la tabla crece en tamaño.

Mitigación

Para limpiar todos los valores utilizados para evitar fugas de memoria:

  • Desconectar todas las conexiones - Revise su base de código para asegurarse de que cada conexión se limpie a través de uno de los siguientes caminos:

    • Desconectar manualmente usando la función Disconnect().
    • Destruyendo la instancia a la que pertenece el evento con la función Destroy().
    • Destruir el objeto de guión al que se remontan las conexiones.
  • Eliminar objetos y personajes del jugador después de salir - Implementar código para garantizar que no persistan conexiones después de que un usuario se vaya, como en el siguiente ejemplo:

    Ejemplo

    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)

Computación de física

La simulación de física excesiva puede ser una causa clave del aumento del tiempo de cálculo por marco en el servidor y en el cliente.

Problemas comunes

  • Frecuencia de paso de física excesiva - Por defecto, el comportamiento de paso está en modo adaptativo , donde los pasos de física se realizan a 60 Hz, 120 Hz o 240 Hz, dependiendo de la complejidad del mecanismo de física.

    También está disponible un modo fijo con una mayor precisión de la física, que obliga a todas las asambleas de física a pasar a 240 Hz (cuatro veces por marco).Esto resulta en una cantidad significativamente mayor de cálculo por marco.

  • Número excesivo de complejidad de objetos simulados - Cuantas más 3D se ensamblan, más tiempo toman las computaciones de física en cada marco.A menudo, las experiencias tendrán objetos que se simulan que no necesitan ser o tendrán mecanismos que tengan más restricciones y articulaciones de las que necesitan.

  • Detector de colisión demasiado preciso - Las piezas de malla tienen una propiedad CollisionFidelity para detectar colisiones que ofrece una variedad de modos con diferentes niveles de impacto de rendimiento.El modo de detección de colisión preciso para piezas de malla tiene el costo de rendimiento más alto y tarda más en ejecutarse al motor.

Mitigación

  • Ancla partes que no requieren simulación - Ancla todas las partes que no necesitan ser impulsadas por la física, como para NPC estáticos.

  • Utilice el paso de física adaptativa - El paso adaptativo ajusta dinámicamente la tasa de cálculos de física para mecanismos de física, permitiendo que las actualizaciones de física se realicen con menos frecuencia en algunos casos.

  • Reduzca la complejidad del mecanismo * Si es posible, minimice el número de restricciones o juntas de física en una ensamblación.

    • Reducir la cantidad de colisión entre sí dentro de un mecanismo, como aplicando límites o restricciones de no colisión a las extremidades de ragdoll para evitar que se choquen entre sí.
  • Reduzca el uso de precisa fidelidad de colisión para mallas * Para objetos pequeños o no interactuables en los que los usuarios rara vez notarían la diferencia, use la fidelidad de la caja

    • Para objetos de tamaño pequeño a mediano, utilice la fidelidad de caja o casco, dependiendo de la forma.

    • Para objetos grandes y muy complejos, construye colisiones personalizadas usando piezas invisibles cuando sea posible.

    • Para objetos que no requieren colisiones, desactiva las colisiones y usa la fidelidad de la caja o del casco, ya que la geometría de colisión aún se almacena en la memoria.

    • Puedes renderizar la geometría de colisión con fines de depuración en Studio activando fidelidad de colisión desde el widget Opciones de visualización en la esquina superior derecha del visor 3D.

      Alternativamente, puedes aplicar el filtro CollisionFidelity = Precise a Explorer que muestra un recuento de todas las piezas de malla con la precisión exacta y te permite seleccionarlas fácilmente.

    • Para una explicación detallada de cómo elegir una opción de fidelidad de colisión que equilibre sus requisitos de precisión y rendimiento, consulte Establecer parámetros de física y renderizado.

Alcances de perfiladoros micro

AlcanceComputación asociada
physicsSteppedComputación de física general
paso mundialPasos de física discreta tomados en cada marco

Uso de la memoria de física

El movimiento físico y la detección de colisiones consume memoria.Las piezas de malla tienen una propiedad CollisionFidelity que determina el enfoque que se usa para evaluar los límites de colisión de la malla.

Problema común

Los modos de detección de colisiones predeterminados y precisos consumen significativamente más memoria que los otros dos modos con formas de colisión de menor fidelidad

Si ves altos niveles de consumo de memoria bajo PhysicsParts , es posible que debas explorar reducir la fidelidad de colisión de los objetos en tu experiencia.

Cómo mitigar

Para reducir la memoria utilizada para la fidelidad a la colisión:

  • Para las partes que no necesitan colisiones, deshabilita sus colisiones al establecer BasePart.CanCollide , BasePart.CanTouch y BasePart.CanQuery a false .
  • Reduce la fidelidad de las colisiones usando la configuración CollisionFidelity.Box tiene la menor sobrecarga de memoria, y Default y Precise son generalmente más caras.
    • Generalmente es seguro establecer la fidelidad de colisión de cualquier pequeña parte anclada a Box .
    • Para mallas grandes muy complejas, es posible que desees crear tu propia malla de colisión a partir de objetos más pequeños con fidelidad de colisión de caja.

Humanoideos

Humanoid es una clase que proporciona una amplia gama de funcionalidades para personajes jugadores y no jugadores (NPCs).Aunque potente, un Humanoid viene con un costo de cálculo significativo.

Problemas comunes

  • Dejar todos los tipos de estado humanoide activados en los NPCs - Hay un costo de rendimiento al dejar activado cierto HumanoidStateTypes.Deshabilita cualquiera que no sea necesario para tus NPCs.Por ejemplo, a menos que tu NPC vaya a escalar escaleras, es seguro desactivar el estado Climbing.
  • Instanciando, modificando y reapareciendo modelos con Humanoids con frecuencia * Esto puede ser intenso para que el motor lo procese, particularmente si estos modelos usan ropa en capas .Esto también puede ser particularmente problemático en experiencias en las que los avatares reaparecen a menudo
    • En el MicroProfiler , las etiquetas de actualización largas updateInvalidatedFastClusters (más de 4 ms) a menudo son una señal de que la instanciación/modificación del avatar está desencadenando invalidaciones excesivas.
  • Usando humanoides en casos en que no se requieren - Los NPC estáticos que no se mueven generalmente no tienen necesidad de la clase Humanoid.
  • Reproducir animaciones en un gran número de NPCs desde el servidor - Las animaciones de NPC que se ejecutan en el servidor deben simularse en el servidor y replicarse al cliente.Esto puede ser una sobrecarga innecesaria.

Mitigación

  • Reproduce animaciones de NPC en el cliente - En experiencias con un gran número de NPC, considera crear el Animator en el cliente y ejecutar las animaciones localmente.Esto reduce la carga en el servidor y la necesidad de replicación innecesaria.También hace posibles optimizaciones adicionales (como solo reproducir animaciones para NPCs que estén cerca del personaje).
  • Utilice alternativas amigables con el rendimiento a los Humanoides - Los modelos de NPC no necesariamente deben contener un objeto humanoide.
    • Para los NPC estáticos, utilice un simple AnimationController , porque no necesitan moverse pero solo necesitan reproducir animaciones.
    • Para mover NPC, considere implementar su propio controlador de movimiento y utilizar un AnimationController para las animaciones, dependiendo de la complejidad de sus NPC.
  • Desactivar estados humanoides no utilizados - Utilice Humanoid:SetStateEnabled() para habilitar solo los estados necesarios para cada humanoide.
  • Modelos NPC de piscina con reaparición frecuente - En lugar de destruir un NPC completamente, envíe el NPC a una piscina de NPC inactivos.De esta manera, cuando se requiere un nuevo NPC para reaparecer, puedes simplemente reactivar uno de los NPCs de la piscina.Este proceso se llama agrupación, que minimiza la cantidad de veces que los personajes deben ser instanciados.
  • Solo engendra NPCs cuando los usuarios están cerca - No engendre NPCs cuando los usuarios no estén en rango, y elimínelos cuando los usuarios salgan de su rango.
  • Evite realizar cambios en la jerarquía de avatares después de que se instancie - Ciertas modificaciones a una jerarquía de avatares tienen implicaciones de rendimiento significativas.Hay algunas optimizaciones disponibles:
    • Para las animaciones procedurales personalizadas, no actualice las propiedades JointInstance.C0 y JointInstance.C1. En cambio, actualice la propiedad Motor6D.Transform.
    • Si necesitas adjuntar cualquier objeto BasePart a tu avatar, hazlo fuera de la jerarquía del avatar Model .

Alcances de perfiladoros micro

AlcanceComputación asociada
pasoHumanoidoControl y física de humanoides
paso de animaciónAnimación humanoide y de animador
actualizar clústeres rápidos inválidosAsociado con la instantaneización o modificación de un avatar

Rendimiento

Una porción significativa del tiempo que el cliente pasa en cada marco es en la renderización de la escena en el marco actual.El servidor no hace ningún renderizado, por lo que esta sección es exclusiva para el cliente

Realizar llamadas

Una llamada de dibujo es un conjunto de instrucciones desde el motor a la GPU para renderizar algo.Las llamadas de dibujo tienen un sobrecosto importante.En general, cuantas menos llamadas de dibujo por marco, menos tiempo de cálculo se gasta al renderizar un marco.

Puedes ver cuántas llamadas de dibujo están ocurriendo actualmente con el elemento Estadísticas de renderizado > Tiempo en Studio.Puedes ver Estadísticas de renderizado en el cliente presionando ShiftF2.

Cuantos más objetos deben dibujarse en tu escena en un marco dado, más llamadas de dibujo se hacen a la GPU.Sin embargo, el motor de Roblox utiliza un proceso llamado instanciación para reducir mallas idénticas con las mismas características de textura a una sola llamada de dibujo.En concreto, múltiples mallas con el mismo MeshId se manejan en una sola llamada de dibujo cuando:

Otros problemas comunes

  • Densidad de objetos excesiva - Si un gran número de objetos se concentran con una alta densidad, entonces renderizar esta área de la escena requiere más llamadas de dibujo.Si está encontrando que su velocidad de fotogramas disminuye al mirar una cierta parte del mapa, esto puede ser una buena señal de que la densidad de objetos en esta área es demasiado alta.

    Objetos como calcomanías, texturas y partículas no se batch bien y introducen llamadas de dibujo adicionales.Presta especial atención a estos tipos de objetos en una escena.En particular, los cambios de propiedad a ParticleEmitters pueden tener un impacto dramático en el rendimiento.

  • Oportunidades de instanciación perdidas - A menudo, una escena incluirá la misma malla duplicada varias veces, pero cada copia de la malla tiene diferentes ID de atributos de malla o textura.Esto impide la instanciación y puede conducir a llamadas de dibujo innecesarias.

    Una causa común de este problema es cuando se importa una escena completa de una vez, en lugar de importar activos individuales a Roblox y luego duplicarlos después de la importación para montar la escena.

  • Complejidad de objeto excesiva - Aunque no es tan importante como el número de llamadas de dibujo, el número de triángulos en una escena influye en cuánto tiempo tarda en renderizarse una imagen.Las escenas con un número muy grande de mallas muy complejas son un problema común, al igual que las escenas con el conjunto de propiedades MeshPart.RenderFidelity configurado en Enum.RenderFidelity.Precise en demasiadas mallas.

  • Proyección de sombras excesiva - La manipulación de las sombras es un proceso costoso, y los mapas que contienen un alto número y densidad de objetos que proyectan sombras (o un alto número y densidad de pequeñas partes influenciadas por las sombras) es probable que tengan problemas de rendimiento.

  • Sobrecarga de transparencia alta - Colocar objetos con transparencia parcial cerca el uno del otro obliga al motor a renderizar los píxeles superpuestos múltiples veces, lo que puede dañar el rendimientoPara obtener más información sobre la identificación y solución de este problema, vea Eliminar transparencias en capas.

Mitigación

  • Instanciando mallas idénticas y reduciendo la cantidad de mallas únicas - Si garantizas que todas las mallas idénticas tengan los mismos ID de activo subyacentes, el motor puede reconocerlas y renderizarlas en una sola llamada de dibujo.Asegúrese de subir solo cada malla en un mapa una vez y luego duplicarlas en Studio para reutilizarlas en lugar de importar grandes mapas en su conjunto, lo que podría causar que las mallas idénticas tengan ID de contenido separados y sean reconocidas como activos únicos por el motor.Los paquetes son un mecanismo útil para la reutilización de objetos.
  • Selección - La selección describe el proceso de eliminar llamadas de dibujo para objetos que no factorizan en el marco renderizado final.Por defecto, el motor omite las llamadas de dibujo para objetos fuera del campo de visión de la cámara (recorte de frustum), pero no omite las llamadas de dibujo para objetos ocultos de la vista por otros objetos (recorte de occlusión).Si tu escena tiene un gran número de llamadas de dibujo, considera implementar una selección adicional propia en tiempo de ejecución de forma dinámica para cada marco, como aplicar las siguientes estrategias comunes:
    • Ocultar MeshPart y BasePart que están lejos de la cámara o la configuración.
    • Para los entornos interiores, implementa un sistema de habitación o portal que esconda objetos que no estén actualmente ocupados por ningún usuario.
  • Reduciendo la fidelidad del renderizado - Establece la fidelidad del renderizado en Automático o Rendimiento .Esto permite que las mallas vuelvan a las alternativas menos complejas, lo que puede reducir el número de polígonos que deben dibujarse.
  • Desactivar el lanzamiento de sombras en las partes y los objetos ligeros apropiados - La complejidad de las sombras en una escena se puede reducir desactivando selectivamente las propiedades de lanzamiento de sombras en objetos ligeros y partes.Esto se puede hacer en el momento de editar o dinámicamente en tiempo de ejecución.Algunos ejemplos son:
    • Usa la propiedad BasePart.CastShadow para deshabilitar el lanzamiento de sombras en pequeñas partes donde es poco probable que las sombras sean visibles.Esto puede ser particularmente efectivo cuando solo se aplica a partes que están lejos de la cámara del usuario.

    • Desabilita las sombras en los objetos en movimiento cuando sea posible.

    • Deshabilita Light.Shadows en instancias ligeras donde el objeto no necesita lanzar sombras.

    • Límite el alcance y el ángulo de las instancias de luz.

    • Usa menos instancias ligeras.

Alcances de perfiladoros micro

AlcanceComputación asociada
Preparar y ejecutarRendimiento general
Ejecutar/Escena/ computeLightingPerformActualizaciones de cuadrícula ligera y sombra
Procesador de cuadrícula ligeraActualizaciones de la cuadrícula de luz de vóxel
Sistema de mapa de sombrasMapa de sombras
Ejecutar/Escena/Actualizar vistaPreparación para la renderización y actualizaciones de partículas
Ejecutar/Escena/RenderViewRenderizado y postprocesamiento

Redes y replicación

La red y la replicación describen el proceso mediante el cual se envían los datos entre el servidor y los clientes conectadosLa información se envía entre el cliente y el servidor en cada marco, pero mayores cantidades de información requieren más tiempo de cómpute.

Problemas comunes

  • Tráfico remoto excesivo - Enviar una gran cantidad de datos a través de RemoteEvent o RemoteFunction objetos o invocarlos con mucha frecuencia puede conducir a que se gaste mucho tiempo de CPU procesando paquetes entrantes en cada marco.Los errores comunes incluyen:

    • Replicando datos cada marco que no necesita ser replicado.
    • Replicando datos en la entrada del usuario sin ningún mecanismo para limitarlo.
    • Enviando más datos de los que se requiere.Por ejemplo, enviar el inventario completo del jugador cuando compran un artículo en lugar de solo detalles del artículo comprado
  • Creación o eliminación de árboles de instancia complejos - Cuando se realiza un cambio en el modelo de datos en el servidor, se replica a los clientes conectados.Esto significa que la creación y destrucción de grandes jerarquías de instancias como mapas en tiempo de ejecución puede ser muy intensiva en red.

    Un culpable común aquí es los datos de animación complejos guardados por los plugins del editor de animación en rigs.Si estas no se eliminan antes de que se publique el juego y el modelo animado se clonee regularmente, se replicará una gran cantidad de datos innecesarios.

  • Servicio de transición del lado del servidor - Si TweenService se usa para transicionar un objeto del lado del servidor, la propiedad transicionada se replica a cada cliente en cada marco.No solo esto resulta en que el preadolescente esté inquieto a medida que fluctúa la latencia de los clientes, sino que también causa mucho tráfico de red innecesario.

Mitigación

Puedes emplear las siguientes tácticas para reducir la duplicación innecesaria:

  • Evite enviar grandes cantidades de datos de una vez a través de eventos remotos .En cambio, envíe solo los datos necesarios con una menor frecuencia.Por ejemplo, para el estado de un personaje, replicarlo cuando cambie en lugar de cada marco.
  • Agrupar árboles de instancias complejos como mapas y cargarlos en piezas para distribuir el trabajo que replica esto en múltiples marcos.
  • Limpie los metadatos de animación , especialmente la dirección de animación de los modelos, después de importar.
  • Limitar la replicación de instancias innecesarias , especialmente en casos en que el servidor no necesita tener conocimiento de las instancias que se están creando.Esto incluye:
    • Efectos visuales como una explosión o una explosión de hechizo mágico.El servidor solo necesita saber la ubicación para determinar el resultado, mientras que los clientes pueden crear visualizaciones de forma local
    • Modelos de vista de artículos de primera persona.
    • Objetos de intermedio en el cliente en lugar del servidor.

Alcances de perfiladoros micro

AlcanceComputación asociada
Paquetes de procesosProcesamiento de paquetes de red entrantes, como invocaciones de eventos y cambios de propiedad
Asignar ancho de banda y ejecutar enviadoresEventos de salida relevantes en los servidores

Uso de memoria de activos

El mecanismo de mayor impacto disponible para los creadores para mejorar el uso de la memoria del cliente es habilitar streaming de instancias.

Transmisión de instancias

La transmisión de instancias carga selectivamente partes del modelo de datos que no son necesarias, lo que puede reducir considerablemente el tiempo de carga y aumentar la capacidad del cliente para evitar colapsos cuando entra en presión de memoria.

Si está experimentando problemas de memoria y tiene deshabilitado el streaming de instancias, considere actualizar su experiencia para admitirlo, particularmente si su mundo 3D es grande.La transmisión de instancias se basa en la distancia en el espacio 3D, por lo que los mundos más grandes se benefician naturalmente más de ella.

Si el streaming de instancias está habilitado, puedes aumentar la agresividad. Por ejemplo, considera:

  • Reduciendo el uso del persistente StreamingIntegrity .
  • Reduciendo el radio de transmisión .

Para obtener más información sobre las opciones de transmisión y sus beneficios, consulte Propiedades de transmisión.

Otros problemas comunes

  • Duplicación de recursos - Un error común es subir el mismo recurso varias veces resultando en diferentes ID de recursos.Esto puede llevar a que el mismo contenido se cargue en la memoria varias veces.
  • Volumen de activos excesivo - Incluso cuando los activos no son idénticos, hay casos en que se pierden oportunidades para reutilizar el mismo activo y ahorrar memoria.
  • Archivos de audio - Los archivos de audio pueden ser un contribuyente sorprendente al uso de la memoria, particularmente si los carga todos a la vez en el cliente en lugar de cargar solo lo que necesita para una parte de la experiencia.Para estrategias, consulte Tiempos de carga.
  • Texturas de alta resolución - El consumo de memoria gráfica para una textura no está relacionado con el tamaño de la textura en el disco, sino con el número de píxeles en la textura.
    • Por ejemplo, una textura de píxeles 1024x1024 consume cuatro veces la memoria gráfica de una textura 512x512.
    • Las imágenes subidas a Roblox se transcodifican a un formato fijo, por lo que no hay beneficio de memoria al subir imágenes en un modelo de color asociado con menos bytes por píxel.Del mismo modo, comprimir imágenes antes de subirlas o eliminar el canal alfa de las imágenes que no lo necesitan puede reducir el tamaño de las imágenes en el disco, pero ni mejora ni mejora mínimamente el uso de la memoria.Aunque el motor reduce automáticamente la resolución de textura en algunos dispositivos, el alcance de la reducción depende de las características del dispositivo, y la resolución de textura excesiva aún puede causar problemas.
    • Puedes identificar el consumo de memoria gráfica para una determinada textura expandiendo la categoría Textura gráfica en la consola del desarrollador .

Mitigación

  • Solo cargue recursos una vez - Reutilice el mismo ID de recurso entre objetos y asegúrese de que los mismos recursos, especialmente mallas y imágenes, no se carguen separadamente varias veces
  • Encuentra y corrige los recursos duplicados - Busca partes de malla y texturas idénticas que se suben varias veces con diferentes ID.
    • Aunque no hay API para detectar la similitud de los activos de forma automática, puedes recopilar todas las ID de activos de imagen en tu lugar (ya sea manualmente o con un script), descargarlas y compararlas usando herramientas de comparación externas.
    • Para las piezas de malla, la mejor estrategia es tomar IDs de malla únicos y organizarlos por tamaño para identificar manualmente duplicados.
    • En lugar de usar texturas separadas para diferentes colores, carga una sola textura y usa la propiedad SurfaceAppearance.Color para aplicar varios tonos a ella.
  • Importar recursos en el mapa por separado - En lugar de importar un mapa entero a la vez, importa y reconstruye los recursos en el mapa individualmente y reconstruyelos.El importador 3D no hace ninguna duplicación de mallas, por lo que si importas un mapa grande con muchas baldosas separadas, cada una de esas baldosas se importaría como un activo separado (incluso si son duplicadas).Esto puede conducir a problemas de rendimiento y memoria a lo largo de la línea, ya que cada malla se trata como individual y ocupa memoria y llamadas de dibujo.
  • Límite los píxeles de las imágenes a no más de la cantidad necesaria .A menos que una imagen esté ocupando una gran cantidad de espacio físico en la pantalla, por lo general necesita un máximo de 512x512 píxelesLa mayoría de las imágenes más pequeñas deberían ser más pequeñas que 256x256 píxeles
  • Utilice hojas de recorte para garantizar el máximo reutilización de texturas en mapas 3D.Para pasos y ejemplos de cómo crear hojas de recorte, consulte Creación de hojas de recorte.

Tiempo de carga

Muchas experiencias implementan pantallas de carga personalizadas y usan el método ContentProvider:PreloadAsync() para solicitar recursos para que las imágenes, los sonidos y las mallas se descarguen en el fondo.

La ventaja de este enfoque es que te permite asegurarte de que las partes importantes de tu experiencia estén completamente cargadas sin interrupciones.Sin embargo, un error común es sobreutilizar este método para precargar más recursos de los que son realmente necesarios.

Un ejemplo de una mala práctica es cargar el completoWorkspace .Si bien esto podría evitar que la textura aparezca, aumenta significativamente el tiempo de carga.

En cambio, solo use ContentProvider:PreloadAsync() en situaciones necesarias, que incluyen:

  • Imágenes en la pantalla de carga.
  • Imágenes importantes en el menú de experiencia, como fondos de botones y iconos.
  • Recursos importantes en la zona de inicio o generación.

Si debe cargar un gran número de recursos, le recomendamos que proporcione un botón Saltar carga .