Optimiza el rendimiento de tu juego para dispositivos móviles: Obtén consejos de expertos sobre física, UI y configuraciones de audio

Nuestro equipo de Éxito Integrado apoya a los clientes de Unity con sus complejos problemas técnicos. Nos sentamos con este equipo de ingenieros de software senior y les pedimos que compartieran parte de su experiencia en la optimización de juegos móviles.
Nuestro equipo de Producciones de Unity Studio conoce el código fuente a la perfección y trabaja con una multitud de clientes de Unity para ayudarles a aprovechar al máximo el motor. En su trabajo, profundizan en los proyectos de los creadores para ayudar a identificar puntos donde se podría optimizar el rendimiento para una mayor velocidad, estabilidad y eficiencia.
A medida que nuestros ingenieros comenzaron a compartir su perspectiva sobre la optimización de juegos móviles, nos dimos cuenta rápidamente de que había demasiada información valiosa para el único artículo de blog que habíamos planeado. En su lugar, decidimos convertir su montaña de conocimiento en un e-book completo (que puedes descargar aquí), así como en una serie de publicaciones de blog que destacan algunos de estos más de 75 consejos prácticos.
En esta segunda entrega de la serie, nos estamos enfocando en cómo mejorar el rendimiento con la interfaz de usuario, la física y la configuración de audio. En caso de que te lo hayas perdido, consulta nuestra publicación anterior sobre perfilado, memoria y arquitectura de código, y mantente atento a la siguiente, dedicada a activos, configuración de proyectos y gráficos.
¿Lo quieres todo ahora? Descarga el e-book gratuito.
¡Vamos directo al grano!
La Física integrada de Unity (Nvidia PhysX) puede ser costosa en móviles, pero los siguientes consejos pueden ayudarte a obtener más fotogramas por segundo.
En PlayerSettings, verifica Prebake Collision Meshes siempre que sea posible.

Asegúrate de editar tus configuraciones de física (Configuración del Proyecto > Física) y simplificar tu matriz de colisión de capas siempre que sea posible.
Desactiva Auto Sync Transforms y habilita Reuse Collision Callbacks.


Los colisionadores de malla pueden ser costosos. Sustituye colisionadores de malla más complejos por colisionadores de malla primitivos o simplificados para aproximar la forma original.

Usa métodos de clase como MovePosition o AddForce para mover tus objetos Rigidbody. Traducir sus componentes Transform directamente puede llevar a recalculaciones del mundo físico, que son costosas en escenas complejas. Mueve cuerpos físicos en FixedUpdate en lugar de Update.
El Fixed Timestep predeterminado en la Configuración del Proyecto es 0.02 (50 Hz). Cambia esto para que coincida con tu tasa de fotogramas objetivo (por ejemplo, 0.03 para 30 fps).
Sin embargo, si tu tasa de fotogramas cae en tiempo de ejecución, esto significa que Unity llamaría a FixedUpdate múltiples veces por fotograma y potencialmente crearía un problema de rendimiento de CPU con contenido pesado en física.
El Maximum Allowed Timestep limita cuánto tiempo pueden usar los cálculos de física y los eventos de FixedUpdate en caso de que la tasa de fotogramas caiga. Bajar este valor significa que durante un parón de rendimiento, la física y la animación podrían ralentizarse, mientras que también se reduce su impacto en la tasa de fotogramas.

Utiliza la ventana de depuración de física (Ventana > Análisis > Depurador de física) para ayudar a solucionar cualquier problema con los colliders o discrepancias. Esto muestra un indicador codificado por colores de los GameObjects que pueden colisionar entre sí.

Para más información, consulta Visualización de depuración de física en la documentación de Unity.
Unity UI (UGUI) puede ser a menudo una fuente de problemas de rendimiento. El componente Canvas genera y actualiza mallas para los elementos de la interfaz de usuario y emite llamadas de dibujo a la GPU. Su funcionamiento puede ser costoso, así que ten en cuenta los siguientes factores al trabajar con UGUI.
Si tienes un Canvas grande con miles de elementos, actualizar un solo elemento de la interfaz de usuario obliga a todo el Canvas a actualizarse, lo que puede generar un pico en la CPU.
Aprovecha la capacidad de UGUI para soportar múltiples Canvases. Divide los elementos de la interfaz de usuario según la frecuencia con la que necesitan ser actualizados. Mantén los elementos de la interfaz de usuario estáticos en un Canvas separado, y los elementos dinámicos que se actualizan al mismo tiempo en sub-canvases más pequeños.
Asegúrate de que todos los elementos de la interfaz de usuario dentro de cada Canvas tengan el mismo valor Z, materiales y texturas.
Es posible que tengas elementos de la interfaz de usuario que solo aparecen esporádicamente en el juego (por ejemplo, una barra de salud que aparece cuando un personaje recibe daño). Si tu elemento de la interfaz de usuario invisible está activo, podría seguir utilizando llamadas de dibujo. Desactiva explícitamente cualquier componente de la interfaz de usuario invisible y vuelve a habilitarlos según sea necesario.
Si solo necesitas desactivar la visibilidad del Canvas, desactiva el componente Canvas en lugar del GameObject. Esto puede ahorrar la reconstrucción de mallas y vértices.
Los eventos de entrada como toques o clics en pantalla requieren el componente GraphicRaycaster. Esto simplemente recorre cada punto de entrada en la pantalla y verifica si está dentro del RectTransform de una UI.
Elimina el GraphicRaycaster predeterminado del Canvas superior en la jerarquía. En su lugar, agrega el GraphicRaycaster exclusivamente a los elementos individuales que necesitan interactuar (botones, scrollrects, etc.).

Además, desactiva Raycast Target en todo el texto e imágenes de la UI que no lo necesiten. Si la UI es compleja con muchos elementos, todos estos pequeños cambios pueden reducir el cálculo innecesario.

Los Grupos de Diseño se actualizan de manera ineficiente, así que úsalos con moderación. Evítalos por completo si tu contenido no es dinámico, y usa anclajes para diseños proporcionales en su lugar. De lo contrario, crea código personalizado para desactivar los componentes Layout Group después de que configuren la UI.
Si necesitas usar Grupos de Diseño (Horizontal, Vertical, Cuadrícula) para tus elementos dinámicos, evita anidarlos para mejorar el rendimiento.

Las vistas grandes de Lista y Cuadrícula son costosas. Si necesitas crear una gran vista de Lista o Cuadrícula (por ejemplo, una pantalla de inventario con cientos de elementos), considera reutilizar un grupo más pequeño de elementos de UI en lugar de crear un elemento de UI para cada elemento. Consulta este proyecto de GitHub para ver esto en acción.
Superponer muchos elementos de UI (por ejemplo, cartas apiladas en un juego de cartas) crea sobrecarga. Personaliza tu código para fusionar elementos superpuestos en tiempo de ejecución en menos elementos y lotes.
Con los dispositivos móviles utilizando ahora resoluciones y tamaños de pantalla muy diferentes, crea versiones alternas de la UI para proporcionar la mejor experiencia en cada dispositivo.
Usa el Simulador de Dispositivos para previsualizar la UI en una amplia gama de dispositivos compatibles. También puedes crear dispositivos virtuales en XCode y Android Studio.

Si tu pantalla de pausa o inicio cubre todo lo demás en la escena, desactiva la cámara que está renderizando la escena 3D. Del mismo modo, desactiva cualquier elemento de Canvas de fondo oculto detrás del Canvas superior.
Considera reducir el Application.targetFrameRate durante una UI de pantalla completa, ya que no deberías necesitar actualizar a 60 fps.
Dejar el campo Event o Render Camera en blanco obliga a Unity a llenar Camera.main, lo cual es innecesariamente costoso.
Considera usar Screen Space – Overlay para tu Canvas RenderMode si es posible, ya que eso no requiere una cámara.

Aunque el audio no suele ser un cuello de botella en el rendimiento, aún puedes optimizar para ahorrar memoria.

Si usas algún formato comprimido (como MP3 o Vorbis), Unity lo descomprimirá y luego lo recomprimirá durante el tiempo de construcción. Esto resulta en dos pasadas con pérdida, degradando la calidad final.
Reduce el tamaño de tus clips y el uso de memoria con compresión:
- Usa Vorbis para la mayoría de los sonidos (o MP3 para sonidos que no están destinados a repetirse).
- Usa ADPCM para sonidos cortos y utilizados con frecuencia (por ejemplo, pasos, disparos). Esto reduce el tamaño de los archivos en comparación con PCM sin comprimir, pero es rápido de decodificar durante la reproducción.
Los efectos de sonido en dispositivos móviles deben ser de 22,050 Hz como máximo. Usar configuraciones más bajas generalmente tiene un impacto mínimo en la calidad final; usa tus propios oídos para juzgar.
La configuración varía según el tamaño del clip.
- Clips pequeños (< 200 kb) deben descomprimirse al cargar. Esto incurre en un costo de CPU y memoria al descomprimir un sonido en datos de audio PCM sin procesar de 16 bits, por lo que solo es deseable para sonidos cortos.
- Los clips medianos (>= 200 kb) deben permanecer Comprimidos en memoria.
- Los archivos grandes (música de fondo) deben configurarse a Streaming, de lo contrario, todo el recurso se cargará en memoria de una vez.
Al implementar un botón de silencio, no simplemente establezcas el volumen en 0. Puedes Destruir el componente AudioSource para descargarlo de la memoria, siempre que el jugador no necesite alternar esto con frecuencia.
En la próxima publicación del blog, nos adentraremos en gráficos y activos. Pero si deseas acceso a la lista completa de consejos y trucos del equipo hoy, nuestro e-book completo está disponible aquí.

Si estás interesado en aprender más sobre los servicios de Soporte Integrado y deseas dar a tu equipo acceso directo a ingenieros, asesoramiento experto y orientación sobre mejores prácticas para tus proyectos, entonces consulta los planes de éxito de Unity aquí.
Queremos ayudarte a hacer que tus aplicaciones de Unity sean lo más eficientes posible, así que si hay algún tema de optimización sobre el que te gustaría saber más, por favor mantennos informados en los comentarios.
