Mejorando 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 problemas comunes de rendimiento y mejores prácticas para mitigarlo.

Cálculo de Script

Las operaciones costosas en el código Lua tardan más en procesarse y, por lo tanto, pueden afectar la puntuarde fotogramas. A menos que se ejecute en paralelo, el código Lua se ejecuta de forma síncrona y bloquea el hilo principal hasta que encuentra una función que genera el subproceso.

Problemas comunes

  • Operaciones intenso en estructuras de tablas - Operaciones complejas como serialización, deserialización y clon profundo concurren un alto costo de rendimiento, especialmente en estructuras de tablas grandes. Esto es particularmente cierto si estas operaciones son recursivas o implican itener por encima de estructuras de datos muy grandes.

  • Eventos de alta frecuencia - Vincular operaciones costosas a eventos basados en marcos de RunService sin limitar la frecuencia de estos eventos que se repiten cada marco, lo que a menudo resulta en un aumento innecesario del tiempo de computación. Estos eventos incluyen:

Mitigación

  • Invoca código en RunService eventos con el menor costo posible, limitando el uso a casos donde se necesita la invocación de alta frecuencia (por ejemplo, actualizar la cámara). Puedes ejecutar la mayoría del código en otros eventos o con menos frecuencia en un bucle.
  • Rompe grandes o costosas tareas usando task.wait() para distribuir el trabajo en múltiples marcos.
  • Identifica y optimiza operaciones no necesariamente caras y usa multithreading para tareas computacionalmente costosas que no necesitan acceder al aplicación de modeladode datos.
  • Algunos scripts del lado del servidor pueden beneficiarse de Generación de código nativo, una simple bandera que compila un script en código de máquina en lugar de código de bytes.

MicroProfiler Escopos

MiraCálculo Asociado
RunService.PreRenderCódigo que se ejecuta en el evento PreRender
RunService.PreSimulationCódigo que se ejecuta en el evento Paso
RunService.PostSimulationCódigo que se ejecuta en el evento Heartbeat
RunService.Latido del corazónCódigo que se ejecuta en el evento Heartbeat

Para obtener más información sobre el diagnóstico de scripts con el MicroProfiler, consulte la biblioteca debug, que incluye funciones para etiquetar código específico y aumentar la especificidad, como debug.profilebegin y debug.profileend . Muchos métodos de API de Roblox que se invocan por scripts también tienen sus propias etiquetas de MicroProfiler asoci

Uso de memoria del script

Las fugas 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 pervasivas en el servidor, ya que 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 más profunda:

  • LuaHeap - Alto o creciente consumo sugiere una fuga de memoria.
  • InstanciaCount - Crear números de instancias coherentes sugiere que se están recolectando algunas instancias en tu código no son basura.
  • PlaceScriptMemory - Proporciona un script por descompostura de uso de memoria.

Problemas comunes

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

    Aunque los eventos se desconectan cuando la instancia a la que pertenecen se destruye, un error común es asumir que esto aplica a los objetos Player que son. Después de que un usuario abandone una experiencia, el motor no destru

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

    Ejemplo

    local playerInfo = {}
    Players.PlayerAdded:Connect(function(player)
    playerInfo[player] = {} -- algo de información
    end)

    Si no elimina estas entradas cuando ya no son necesarias, la tabla sigue 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 itere sobre esta tabla también se vuelve más costoso computacionalmente a medida que la tabla crece en tamaño.

Mitigación

Para limpiar todos los valores usados para prevenir fugas de memoria:

  • Desconectar todas las conexiones - Ve a través de tu base de código para asegurarte de que cada conexión esté limpia a través de uno de los siguientes caminos:

    • Desconectarse manualmente usando la función Disconnect().
    • Destruyendo la instancia a la que pertenece el evento con la función Destroy() .
    • Destruir el objeto de script que la conexión rastrea de vuelta.
  • Elimina los objetos y personajes del jugador después de salir - Implantar el código para asegurarse de que no hay conexiones que persisten 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)

Cálculo de física

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

Problemas comunes

  • Frecuencia de tiempo de física excesiva - Por defecto, la frecuencia de los pasos de la física está en modo adaptivo, donde los pasos de la física se realizan en cualquier momento entre 60 Hz, 120 Hz o 240 Hz, dependiendo de la complejidad del mecanismo de física.

    También se ofrece un modo fijo con una precisión mejorada de la física, lo que obliga a todas las asociaciones de física a pasar a 240 Hz (cuatro veces por marco). Esto resulta en una cantidad significativamente mayor de cálculos por marco.

  • Número excesivo de la complejidad de los objetos simulados - Cuantos más conjuntos de 3D estén simulados, más tiempo tomarán las cálculos de física por cada marco. A menudo, las experiencias tendrán objetos que simular que no necesitan ser o tendrán mecanismos que tienen más limitaciones y conexiones que no son necesarias.

  • Detección de colisión demasiado precisa - Las partes de malla tienen una propiedad CollisionFidelity para detectar la colisión que ofrece una variedad de modos con diferentes niveles de rendimiento. El modo de detección de colisión precisa para las partes de malla tiene el costo de rendimiento más caro y toma más tiempo para calcular.

Mitigación

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

  • Usa el paso de física adaptiva - El paso de física dinámicamente ajusta la tasa de cálculos de física para los mecanismos de física, lo que permite que las actualizaciones de física se realicen con menos frecuencia en algunos casos.

  • Reducir la complejidad del mecanismo * En la medida de lo posible, minimice el número de limitaciones o juntas físicas en una montura.

    • Reduce la cantidad de colisión de autos dentro de un mecanismo, como aplicando límites o restricciones de colisión a los limbos de ragdoll para evitar que se colisionen entre sí.
  • Reducir el uso de la precisión de colisión para las mallas * Para objetos pequeños o no interactuables donde los usuarios rara vez notarían la diferencia, usa la fidelidad de la caja.

    • Para objetos de pequeña a mediana escala, usa fidelidades de caja o cascarones, dependiendo de la forma.

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

    • Para los objetos que no requieren colisiones, desactivar colisiones y usar la fidelidad de la caja o el casco, ya que la geometría de colisión se almacena en la memoria.

    • Puedes renderizar geometría de colisión para propósitos de diagnóstico en Studio activando fidelidad de colisión desde el widget Opciones de visualización en la esquina superior derecha de la ventana de vista 3D.

      Alternativamente, puede aplicar el filtro CollisionFidelity = Precise a la Explorer que muestra un recuento de todas las partes de malla con la precisión precisa y le permite seleccionarlas fácilmente.

    • Para obtener una guía de caminata en profundidad sobre cómo elegir una opción de fidelidad de colisión que equilibra sus requisitos de rendimiento y precisión, consulte Establecer parámetros de física y renderizado .

MicroProfiler Escopos

MiraCálculo Asociado
físicaCálculo de física general
Paso de MundoPasos de física des discretos para cada marco

Uso de memoria de física

El movimiento y la detección de colisión de fisicas consume memoria. Las partes de malla tienen una propiedad CollisionFidelity que determina el enfoque que se utiliza para evaluar los límites de colisión de la malla.

Problema común

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

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

Cómo mitigar

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

  • Para las partes que no necesitan colisiones, desactiven sus colisiones estableciendo BasePart.CanCollide, BasePart.CanTouch y BasePart.CanQuery a 1> false1> .
  • Reduce la fidelidad de las colisiones usando la configuración CollisionFidelity. Box tiene el menor sobrecarga de memoria y Default y 1>
    • Generalmente es seguro establecer la fidelidad de colisión de cualquier parte anclada pequeña a Box .
    • Para mallas grandes y muy complejas, puede que quieras construir tu propia malla de colisión con menor fidelidad de colisión de caja.

Humanoides

Humanoid es una clase que proporciona una gran variedad de funcionalidades para los personajes jugador y no jugador (NPC). Aunque es poderosa, un Humanoid viene con un costo de cálculo significativo.

Problemas comunes

  • Dejar todo el estado de tipo humanoide activado en los NPCs - Hay un costo de rendimiento por dejar activado el estado de tipo humanoide enum.HumanoidStateType|HumanoidStateTypes. Desabilita cualquier que no sea necesario para tus NPCs. Por ejemplo, a menos que tu NPC esté escalando escaleras, es seguro desactivar el estado de Climbing.
  • Instantiando, modificando y reapareciendo modelos con Humanoides con frecuencia * Esto puede ser intenso para que el motor procese, particularmente si estos modelos usan Ropa en capas . Esto también puede ser particularmente problemático en experiencias donde los avatares reaparecen con frecuencia.
    • En el MicroProfiler , las largas etiquetas de actualización de updateInvalidatedFastClusters (más de 4 ms) a menudo son una señal de que la instantánea/modificación de avatar está activando actualizaciones excesivas.
  • Usando Humanoids en casos en los que no se requieren - NPC estáticos que 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 ser simuladas en el servidor y replicadas al cliente. Esto puede ser un desperdicio de rendimiento.

Mitigación

  • Reproducir animaciones de NPC en el cliente - En las experiencias con un gran número de NPC, considere crear el Animator en el cliente y ejecutar las animaciones localmente. Esto reduce la carga en el servidor y la necesidad de una replicación innecesaria. También hace posibles optimizaciones adicionales (como solo jugar animaciones para NPCs que están cerca del personaje).
  • Usa alternativas amigables con el rendimiento a los humanoides - Los modelos de NPC no necesitan necesariamente contener un objeto de humanoides.
    • Para los NPC estáticos, usa un simple AnimationController, porque no necesitan moverse pero solo necesitan jugar animaciones.
    • Para mover NPCs, considere implementar su propio controlador de movimiento y usar un AnimationController para las animaciones, dependiendo de la complejidad de sus NPCs.
  • Desactivar estados no utilizados de humanoides - Usa Humanoid:SetStateEnabled() para solo habilitar estados necesarios para cada humanoide.
  • Modelos de NPC de piscina con frecuente reaparición. - En lugar de destruir un NPC completamente, envía el NPC a una piscina de NPC inactivos. De esta manera, cuando se requiere un nuevo NPC para reaparecer, puede simplemente reactivar uno de los NPC de la piscina. Este proceso se llama piscina, que minimiza la cantidad de veces que los personajes deben ser instantiados.
  • Solo se generan NPC cuando los usuarios están cerca - No se generan NPC cuando los usuarios no están en rango, y elimínalos cuando los usuarios salgan de su rango.
  • Evite hacer cambios en la jerarquía del avatar después de que se instantiado - Algunos cambios en la jerarquía del avatar tienen implicaciones de rendimiento importantes. Algunas optimizaciones están disponibles:
    • Para animaciones procedurales personalizadas, no actualice las propiedades JointInstance.C0 y JointInstance.C1 sino que actualice la propiedad Motor6D.Transform.
    • Si necesitas unir cualquier objeto de BasePart a tu avatar, hazlo fuera de la jerarquía del avatar Model .

MicroProfiler Escopos

MiraCálculo Asociado
stepHumanoideControl y física humanoide
Animación de pasoanimacionesde humanoides y animador
actualizarInválidoFastClustersAsociado con la instauración o modificación de un avatar

Renderizado

Una cantidad significativa del tiempo que el cliente gasta 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.

Solicitudes para dibujar

Una llamada de dibujo es un conjunto de instrucciones del motor alGPU para renderizar algo. Las llamadas de dibujo tienen un gran rendimiento. Por lo general, cuantas menos llamadas de dibujo por cada marco, menos tiempo de rendimiento se gasta para renderizar un marco.

Puedes ver cuántas llamadas de render están ocurriendo con el Estadísticas de renderizado > Tiempo de renderizado elemento en Studio. Puedes ver Estadísticas de renderizado en el cliente presionando 1> Shift1> 3> F2 3> .

Cuantos más objetos necesiten ser dibujados en tu escena en un marco específico, más llamadas de dibujo se hacen al núcleo. Sin embargo, el motor de Roblox utiliza un proceso llamado instancia para colapsar mallas idénticas con las mismas características de textura en una sola llamada de dibujo. Por ejemplo, múltiples mallas con la misma MeshId se manejan en una sola llamada de dib

Otros problemas comunes

  • Densidad de objetos excesiva - Si un gran número de objetos se concentra con una alta densidad, entonces la renderización de esta área de la escena requiere más llamadas de dibujo. Si estás encontrando que tu tasa 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 sincronizan bien y introducen llamadas de dibujo adicionales. Presta especial atención a estos tipos de objetos en una escena. En particular, las propiedades cambiantes a ParticleEmitters pueden tener un impacto dramático en el ejecución.

  • Fallos al instalar oportunidades - A menudo, una escena incluirá la misma malla duplicada varias veces, pero cada copia de la malla tiene diferentes ID de malla o textura. Esto evita que se instale y puede conducir a llamadas de dibujo innecesarias.

    Una causa común de este problema es cuando se importa una escena entera a la vez, en lugar de que se importen individualmente las fuentes para luego duplicarlas post-importar para montar la escena.

  • Complejidad de objetos excesiva - Aunque no es tan importante como el número de llamadas de dibujo, el número de triángulos en una escena afecta la duración de un marco para Renderizar. Las escenas con un conjunto de propiedades de malla muy grande y compleja están comunes, como las escenas con el MeshPart.RenderFidelity propiedad de conjunto de propiedades de malla establec

  • Excesivo castado de sombras - El manejo de sombras es un proceso costoso, y los mapas que contienen una gran cantidad y densidad de objetos de luz que castan sombras (o una gran cantidad y densidad de pequeñas partes afectadas por las sombras) probablemente tienen problemas de rendimiento.

  • Retirar transparencia alta sobre objetos con transparencia parcial cerca de uno another forcea el motor a renderizar los píxelesOverlapping varias veces, lo que puede dañar el ejecución. Para obtener más información sobre cómo identificar y corregir este problema, see Eliminar capas de transparencia sobrepuestas .

Mitigación

  • Instancia mallas idénticas y reduce la cantidad de mallas únicas para que el motor pueda reconocer y renderizarlas en un solo llamado de dibujo. Asegúrese de actualizar cada malla en un mapa una vez y luego duplicarlas en Studio para reutilizarlas en lugar de importar mapas grandes como un todo, lo que puede causar que las mallas idénticas tengan ID de contenido
  • Selección de Curlos - La selección de curlos describe el proceso de eliminación de las llamadas de dibujo para objetos que no se factran en el marco de renderizado final. Por defecto, el motor omitirá las llamadas de curlos para objetos fuera del campo de visión de la cámara (culling frustum), pero no omitirá las llamadas de curlos para objetos
    • Ocultar MeshPart y BasePart que están muy lejos de la cámara o la configuración.
    • Para ambientes interiores, implementa un sistema de habitación o portal que oculta los objetos no actualmente ocupados por ningún usuario.
  • Reducir la fidelidad de renderizado - Establece la fidelidad de renderizado en Automático o Rendimiento . Esto permite que las máximas se vuelvan a los alternativos más simples, lo que puede reducir el número de polígonos que se deben dibujar.
  • Desactivar el rayado de sombras en las partes y los objetos de luz adecuados - La complejidad de las sombras en una escena se puede reducir seleccionando propiedades de rayado de sombras en las partes y los objetos de luz. Esto se puede hacer en el tiempo de edición o dinámicamente en el tiempo de ejecución. Algunos ejemplos son:
    • Usa la propiedad BasePart.CastShadow para desactivar el enfoque de sombras en las pequeñas partes donde las sombras no son visibles. Esto puede ser particularmente efectivo cuando se aplica sólo a las partes que están lejos de la cámara del usuario.

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

    • Desactivar Light.Shadows en instancias de luz donde el objeto no necesita lanzar sombras.

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

    • Usa menos instancias de luz.

MicroProfiler Escopos

MiraCálculo Asociado
Preparar y RealizarRenderizado general
Ejecutar/Escena/computadoraLightingPerformActualizaciones de la cuadrícula y las sombras
Cálculo de la cuadrícula de la luzActualizaciones de la cuadrícula de luz Voxel
Sistema de mapas de sombrasMapa de sombras
Realizar/Escena/UpdateViewPreparación para actualizaciones de rendimiento y partículas
Actuar/Escena/RenderViewRenderizado y postprocesado

Redes y Replicación

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

Problemas comunes

  • Tráfico remoto excesivo - Enviar una gran cantidad de datos a través de objetos RemoteEvent o RemoteFunction o invocarlos con mucha frecuencia puede resultar en una gran cantidad de tiempo de procesamiento de los paquetes entrantes en cada marco. Los errores comunes incluyen:

    • Replicando datos cada marco que no necesita ser replicado.
    • Replicar los datos de la entrada del usuario sin ningún mecanismo para acelerarlo.
    • Despachando más datos de los que son requeridos. Por ejemplo, enviar el inventario entero del jugador cuando ellos 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 del servidor, se replica a los clientes conectados. Esto significa que la creación y destrucción de grandes árboles de instancia como mapas en tiempo de ejecución puede ser muy intenso en red.

    Un culpable común aquí es el complejo dato de animación guardado por los plugins del Editor de Animación en las máquinas. Si estos no se eliminan antes de que se publique el juego y el modelo animado se clone con regularidad, se replicará una gran cantidad de datos.

  • Servicio de TweenSide del lado del servidor - Si se usa TweenService para tener un objeto del lado del servidor, la propiedad tweened se replica a cada cliente cada marco. No solo esto resulta en que el tween sea jittery a medida que la latencia de los clientes cambia, sino que causa mucho tráfico de red innecesario.

Mitigación

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

  • Evite enviar grandes cantidades de datos a la vez a través de eventos remotos. En cambio, solo envíe los datos necesarios con una frecuencia más baja. Por ejemplo, para el estado de un personaje, replica cuando cambia en lugar de cada marco.
  • Chunk up árboles de instancia complejos como mapas y cargarlos en piezas para distribuir el trabajo replicando estos en múltiples marcos.
  • Limpiar el metadato de la animación , especialmente la carpeta de animación de los modelos, después de importar.
  • Límite de replicación de instancia no necesario , especialmente en casos en los 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 maldición de hechizo. El servidor solo necesita saber la ubicación para determinar el resultado, mientras que los clientes pueden crear visuales localmente.
    • Modelos de vista de artículos de primera persona.
    • Tweener objetos en el cliente en lugar que en el servidor.

MicroProfiler Escopos

MiraCálculo Asociado
Paquetes de ProcesosProcesar paquetes de red entrantes, como invocaciones de eventos y cambios de propiedad
Distribuir ancho de banda y ejecutar SendersEventos salientes 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 Instancia

La sincronización de instancia carga seleccionadamente partes del modelo de datos que no son requeridas, lo que puede reducir el tiempo de carga significativamente y aumentar la capacidad del cliente para evitar los errores cuando se pone presión de memoria.

Si estás experimentando problemas de memoria y tienes la transmisión de instancias desactivada, considera actualizar tu experiencia para apoyarla, especialmente si tu 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 naturalmente se benefician más de esto.

Si se habilita la sincronización de instancias, puede aumentar la agresividad. Por ejemplo, considere:

  • Reducir el uso del persistente StreamingIntegrity .
  • Reducir el alcance de transmisión .

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

Otros problemas comunes

  • Duplicación de activos - Un error común es subir el mismo activo varias veces lo que resulta en diferentes ID de activos. Esto puede causar el mismo contenido que se carga en el memoria varias veces.
  • Volumen de activos excesivo - Incluso cuando los activos no son idénticos, hay casos en que se pierden las oportunidades de reutilizar el mismo activo y ahorrar memoria.
  • Archivos de audio - Los archivos de audio pueden ser un contribuyente sorpresivo al uso de memoria, particularmente si los carga en el cliente al mismo tiempo que no carga lo que necesita para una parte de la experiencia. Para estrategias, véase Tiempos de carga.
  • Texturas de alta resolución - El consumo de memoria de gráficos para una textura no está relacionado con el tamaño de la textura en el disco, sino más bien con el número de píxeles en la textura.
    • Por ejemplo, una textura de 1024x1024 consume el 40% de la memoria gráfica de una textura de 512x512.
    • Las imágenes subidas a Roblox se transcodifican a un formato fijo, por lo que no hay beneficio de memoria para subir imágenes en un modelo de color asociado con menos bytes por píxel. De manera similar, la compresión de imágenes antes de subir o eliminar el canal alfa de las imágenes que no lo necesitan puede reducir el tamaño de la imágen en el disco, pero no mejora o solo me
    • Puede identificar el consumo de memoria de gráficos para una determinada textura al expandir la categoría Graficos en la Consola del desarrollador.

Mitigación

  • Solo se pueden subir los recursos una vez. - Reutiliza el mismo ID de recurso en los objetos y asegúrate de que los mismos recursos, especialmente las rejillas y las imágenes, no se suban varias veces.
  • Encuentra y soluciona problemas de duplicados de assets. - Busca partes y texturas de malla idénticas que se hayan subido múltiples veces con diferentes ID.
    • Aunque no hay API para detectar la similitud de los recursos automáticamente, puede recopilar todos los ID de los recursos de imagen en su lugar (ya sea manualmente o con un script), descargarlos y compararlos usando herramientas de comparación externas.
    • Para las partes de malla, la mejor estrategia es tomar ID de malla únicos y organizarlos por tamaño para identificar manualmente los duplicados.
    • En lugar de usar texturas separadas para diferentes colores, sube una sola textura y usa la propiedad SurfaceAppearance.Color para aplicar varios tonos a ella.
  • Importando activos en el mapa en separado - En lugar de importar un mapa entero en una sola vez, importa y reconstruye activos en el mapa individualmente y reconstruye. El importador 3D no hace ninguna duplicación de mallas, por lo que si importa un gran mapa con muchas capas de piso separadas, cada una de esas capas se importará como una activa separ
  • Límite el tamaño de 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, generalmente necesita al menos 512x512 píxeles. La mayoría de las imágenes menores deben ser más pequeñas que 256x256 píxeles.
  • Usa hojas de corte para asegurar el máximo uso de reutilización de textura en mapas 3D. Para obtener pasos y ejemplos sobre cómo crear hojas de corte, véase Creando hojas de corte .

Cargar veces

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

La ventaja de este enfoque es que te permite asegurarte de que las partes importantes de tu experiencia se carguen completamente sin pop-in. Sin embargo, un error común es sobreutilizar este método para precargar más recursos de los que son realmente requeridos.

Un ejemplo de una mala práctica es cargar el todoWorkspace . Mientras esto puede prevenir que se cargue la textura, aumenta significativamente el tiempo de carga.

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

  • Imágenes en la pantalla de carga.
  • Importantes imágenes en tu menú de experiencia, como fondos de botón y iconos.
  • Importante de los activos en la zona de inicio o aparición.

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