Este artículo proporciona consejos sobre cómo optimizar sus proyectos web de Unity.
Anteriormente denominada "WebGL", la compatibilidad con la plataforma web Unity incluye avances clave que reducen la fricción para más dispositivos y aprovechan las API de gráficos más recientes para garantizar velocidades de fotogramas fluidas y un rendimiento excepcional incluso para los juegos web más ambiciosos.
Esto incluye soporte para WebGL, una API de JavaScript que representa gráficos 2D y 3D en navegadores a alta velocidad. Google Chrome, Mozilla Firefox, Safari y Microsoft Edge admiten contenido WebGL 2. WebGL 2 está basado en OpenGL ES 3.0
Independientemente de su API de gráficos, debe intentar crear un juego Unity Web de tamaño pequeño para que sea eficiente para distribuirlo e insertarlo en sitios web y redes sociales. También puede utilizar una compilación web para la creación de prototipos y juegos donde la fácil distribución es clave, así como para realizar pruebas, incluso cuando esté apuntando a otra plataforma.
Los juegos web no pueden acceder a archivos o hardware locales y, por lo general, tienen un rendimiento ligeramente inferior al de los juegos compilados de forma nativa.
*NOTA*: Una nueva API, WebGPU, está disponible en acceso temprano en la versión beta de Unity 6 (2023.3.0b1 beta). WebGPU aún está en desarrollo y no se recomienda su uso en casos de uso de producción.
WebGPU fue diseñado con el objetivo de aprovechar y exponer las capacidades modernas de GPU a la web. Esta nueva API web proporciona una interfaz de aceleración de gráficos moderna que se implementa internamente a través de API de GPU nativas, como DirectX12, Vulkan y Metal. La implementación nativa específica dependerá de la plataforma del navegador y de los controladores de gráficos disponibles. Los detalles sobre cómo comenzar, así como demostraciones adicionales de WebGPU, se pueden encontrar en el foro de gráficos.
Para implementar en la plataforma web de Unity, primero debe agregar el módulo web al editor de Unity para crear una compilación web. Busque la instalación en Unity Hub, haga clic en el ícono Configuración y elija Agregar módulos.
En el nuevo cuadro de diálogo, desplácese hacia abajo para encontrar Web Build Support, selecciónelo y haga clic en Listo.
Vuelva a abrir su proyecto y cambie la plataforma de destino en Archivo > Configuración de compilación. Utilice la opción Desarrollo de compilación mientras desarrolla su juego. Proporciona información de depuración adicional, como seguimientos de pila, mensajes de error detallados e información de registro que pueden ayudarte a solucionar problemas y realizar cambios en tu juego. Puedes realizar pequeños cambios en el código, los recursos o la configuración del juego y luego reconstruir y probar rápidamente esos cambios en el navegador sin la necesidad de un proceso de compilación completo.
Solo asegúrese de desmarcar la opción Compilación de desarrollo en Configuración de compilación para su compilación final publicada.
Selecciona Construir y ejecutar para crear una versión de tu juego que se ejecute en un navegador para realizar pruebas. Google Chrome es una buena opción para realizar pruebas porque proporciona una serie de herramientas para desarrolladores.
Se le pedirá que elija una ubicación para la construcción. Los archivos de la compilación incluyen un archivo index.html que agrega un elemento Canvas HTML5 al Modelo de objetos de documento (DOM), que es la representación de datos de los objetos que componen la estructura y el contenido de un documento en la web. El juego se representa en este lienzo. Los archivos de compilación también incluyen una carpeta TemplateData y una carpeta de compilación. La carpeta TemplateData contiene recursos HTML utilizados en la página, como el favicon utilizado en la barra de direcciones del navegador y las imágenes utilizadas en el marcado HTML de la página.
También puede configurar compilaciones automatizadas, siendo Unity Build Automation una opción para esto.
Puedes utilizar el canal de renderizado integrado o el canal de renderizado universal (URP) para un juego web. Sin embargo, recomendamos URP porque proporciona una personalización y escalamiento eficiente del contenido a múltiples dispositivos de hardware.
Obtenga instrucciones detalladas sobre cómo mover sus proyectos del canal de renderizado integrado a URP con el libro electrónico Introducción al canal de renderizado universal para creadores avanzados de Unity.
Cuando apunta a una consola, tiene especificaciones exactas para la memoria y el uso de CPU y GPU. La web es una bestia completamente diferente. Para que tu juego esté disponible para una audiencia más amplia, debes asegurarte de que funcione bien en un entorno de memoria restringida.
A continuación se ofrecen algunos consejos sobre cómo hacer que su juego funcione sin problemas en hardware de gama baja, extraídos del libro electrónico Optimice el rendimiento de su juego móvil.
1. Optimice los recursos de su juego
Optimice activos como texturas y modelos para la web, por ejemplo, utilice texturas comprimidas y reduzca la cantidad de polígonos en sus modelos, cuando corresponda. Si bien no existen reglas fijas, acuerde algunas pautas generales en su equipo para garantizar la coherencia en el desempeño.
2. Usar agrupación de objetos
La agrupación de objetos es una técnica que puede ayudarle a mejorar el rendimiento al reutilizar objetos en lugar de crear y destruir otros nuevos. Esto puede resultar útil para juegos con mucha aparición y desaparición. Otros patrones de diseño de programación, como el volante, también pueden resultar útiles. Consulte el libro electrónico Suba de nivel su código con patrones de programación de juegospara obtener consejos avanzados sobre cómo implementar patrones de diseño en proyectos de Unity.
3. Utilice Universal Render Pipeline y SRP Batcher
Mejore el rendimiento con el sistema de procesamiento por lotes SRP Batcher de Unity, que acelera el procesamiento de la CPU, según la escena. Funciona agrupando llamadas de dibujo en función de propiedades de materiales compartidas, como sombreadores y texturas, reduciendo así la cantidad de cambios de estado necesarios durante el renderizado.
4. Utilice el sacrificio de oclusión
El sistema de selección de oclusión en Unity puede ayudar a mejorar el rendimiento al representar solo los objetos que son visibles para el jugador. La selección de oclusión funciona mejor en escenas donde áreas pequeñas y bien definidas están separadas entre sí por GameObjects sólidos, como habitaciones conectadas por pasillos.
5. Utilice el sistema LOD (Nivel de detalle) incorporado
El sistema LOD integrado de Unity mejora el rendimiento al reducir la complejidad de los objetos que están más lejos del jugador. A medida que aumenta la distancia entre la cámara y un objeto, el sistema LOD intercambia automáticamente la versión con mayor detalle del objeto con versiones con menor detalle, lo que reduce la carga de trabajo de renderizado y mantiene una apariencia coherente.
6. Hornea tu iluminación siempre que sea posible
Mejore el rendimiento precalculando la información de iluminación para sus escenas con Lightmaps y Light Probes.
7. Reducir la creación o manipulación innecesaria de cadenas
En C#, las cadenas son tipos de referencia, no tipos de valores. Evite analizar archivos de datos basados en cadenas como JSON y XML; almacene datos en ScriptableObjects o formatos como MessagePack o Protobuf. También puedes considerar los formatos binarios para casos como guardar datos persistentes del juego (guardar juegos). Utilice la clase StringBuilder si necesita crear cadenas en tiempo de ejecución.
8. Prueba el sistema Addressable Asset
El sistema de activos direccionables proporciona una forma simplificada de administrar su contenido cargando AssetBundles por “dirección” o alias. Este sistema unificado se carga de forma asíncrona desde una ruta local o una red de entrega de contenido remota (CDN).
9. Limitar los efectos del posprocesamiento
Los efectos de posprocesamiento de pantalla completa pueden ralentizar el rendimiento, así que úsalos con moderación en tu juego.
Cuando creas una compilación web de Unity, Unity utiliza una plantilla para generar la página web para mostrar tu juego.
Las plantillas predeterminadas son:
- Por defecto: Una página blanca con una barra de carga sobre un lienzo gris.
- Mínimo: El texto estándar mínimo necesario para ejecutar tu juego
- Aplicación web progresiva (PWA): Esto incluye un archivo de manifiesto web y un trabajador de servicio. En un navegador de escritorio adecuado, se mostrará un botón de instalación en la barra de direcciones para agregar el juego a las aplicaciones ejecutables del jugador.
La forma más sencilla de crear su propia página HTML personalizada es comenzar con una de las tres plantillas, que puede encontrar en <UnityInstallation>/PlaybackEngines/ WebGLSupport/ BuildTools/ WebGLTemplates/. En Mac, puede ubicar la carpeta de instalación de Unity en la carpeta Aplicaciones.
Copie una plantilla, colóquela en su propia carpeta Proyecto/Activos/WebGLTemplates y cámbiele el nombre para poder identificarla más tarde. Ahora puedes personalizarlo para adaptarlo al contenido del juego, al sitio de implementación y a la plataforma de destino.
Las plantillas en la carpeta WebGLTemplates de su proyecto aparecen en el panel Editar > Configuración del proyecto… > Reproductor > Resolución y presentación . El nombre de la plantilla es el mismo que su carpeta. Para darle a esta opción una imagen en miniatura para una fácil referencia, agregue una imagen de 128 x 128 píxeles a la carpeta de la plantilla y asígnele el nombre miniatura.png.
Durante el proceso de compilación, Unity preprocesa los archivos de plantilla y evalúa todas las macros y directivas condicionales incluidas en esos archivos. Encuentra y reemplaza todas las declaraciones de macro con los valores que proporciona el Editor y preprocesa automáticamente todos los archivos .html, .php, .css, .js y .json en la carpeta de plantillas.
Por ejemplo, eche un vistazo a esta línea de código:
<canvas id="unity-canvas" ancho={{{ WIDTH }}} altura ={{{ HEIGHT }}} tabindex="-1"></canvas>
Si el Ancho predeterminado del lienzose establece en 960 y el Alto predeterminado del lienzo en 600 en el panel Resolución y presentación, el código se verá así después del preprocesamiento:
<canvas id="unity-canvas" width="960" height="600" tabindex="-1"></canvas>.
Las llaves triples indican al compilador que encuentre el valor de la variable indicada.
También encontrará ejemplos en las plantillas predeterminadas de directivas condicionales usando #if, #else y #endif:
#if EXPRESSION
//Si la EXPRESIÓN se evalúa como un valor verdadero
#else
//Si la EXPRESIÓN no se evalúa como un valor verdadero
#endif
Si desea utilizar una plantilla personalizada, Unity Asset Store ofrece varias opciones.
Si comparte su juego en una plataforma para juegos basados en navegador, deberá adaptar la página index.html para que coincida con una especificación. Consulte la documentación de algunas de las plataformas más populares para juegos web para aprender cómo hacer esto:
A menudo querrás que tu juego cambie el tamaño de una ventana del navegador para adaptarse a un diseño responsivo, lo que requiere que adaptes el código de carga. Puede utilizar una "Promesa" en JavaScript para lograr esto, que representa una operación que aún no se ha completado pero que se espera que lo haga en el futuro.
En la página index.html de cada plantilla (consulte el ejemplo de código a continuación), busque script.onload. script.onload es un evento que se activa cuando el script del motor de Unity termina de cargarse. Justo antes de que eso ocurra, tienes dos variables globales: myGameInstance, que contiene la referencia a la instancia de Unity, y myGameLoaded, que indica si el juego ha terminado de cargarse o no y el valor predeterminado es falso. Se declaran como var para que tengan un alcance global y se pueda acceder a ellos desde cualquier parte del script.
Se llama a la función createUnityInstance() para crear una nueva instancia del juego Unity. Esta función devuelve una Promesa que se resuelve cuando el juego está completamente cargado y listo para renderizar (el bloque then de la Promesa createUnityInstance).
Dentro de then(), a myGameInstance se le asigna la instancia de Unity y myGameLoaded se establece en verdadero, lo que indica que el juego ya está listo. Luego se llama a la función resizePage() para establecer inicialmente el tamaño del juego, y se agrega un detector de eventos al evento de cambio de tamaño de la ventana para que el tamaño del juego pueda actualizarse cada vez que se cambia el tamaño de la ventana. Vea el fragmento de código a continuación.
Luego tenemos la función resizePage en la parte inferior del script, como se muestra en el siguiente fragmento de código, que se utiliza para cambiar el tamaño del juego para que coincida con el tamaño de la ventana. Si el juego está cargado, establece los valores de estilo para el lienzo que muestra el juego para que coincida con el tamaño de la ventana, haciendo que llene la ventana:
función cambiar tamaño de página(){
if (myGameInstance! == indefinido && myGameLoaded === verdadero)
{
canvas.style.width = window.innerWidth + 'px';
canvas.style.height = window.innerHeight + 'px';
}
}
Muchos juegos dirigidos a un navegador necesitarán interactuar con código JavaScript para permitirle llamar a servicios web para admitir inicios de sesión de usuarios, tablas de puntuación alta, etc., o para interactuar con el DOM del navegador. Cualquier JavaScript que agregue directamente, para que pueda llamarse desde un script C#, debe tener una extensión .jslib y colocarse en la carpeta Activos/Complementos . Debe estar envuelto en el método mergeInto. Esto requiere dos parámetros: LibraryManager.library y luego un objeto JavaScript que contiene una o más funciones. Las funciones son JavaScript estándar. GetExchangeRates muestra cómo utilizar un servicio web de entrega JSON simple a continuación.
Cuando creas una compilación, estas funciones se agregarán al archivo Build/<tu nombre del juego>.framework.js . Puede llamar a estas funciones desde un script de C# declarando la función como DllImport, como se muestra en este ejemplo de código:
Clase pública SphereController: MonoBehaviour
{
[DllImport("__Internal")]
private static extern void GetExchangeRates();
Inicio vacío privado()
{
GetExchangeRates();
}
}
Más información
Además de que C# llame a una función de JavaScript, JavaScript puede llamar a un método de C#. El mecanismo involucrado utiliza un protocolo de mensajería:
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’)
myGameInstance.SendMessage(‘MyGameObject’, ‘MyFunction’, 5)
myGameInstance.SendMessage('MyGameObject', 'MyFunction', 'Una cadena')
Para usar SendMessage, necesitas una referencia a la instancia del juego dentro del alcance. La técnica habitual es editar index.html agregando una variable global y asignándola en el bloque then de la promesa script.onload como se vio anteriormente. Esta función simple se agrega como parte de un componente MonoBehaviour adjunto a un GameObject llamado Sphere.
vacío público SetHeight (altura flotante)
{
Vector3 pos = transformar.posición;
pos.y = height;
transform.position = pos;
}
Puedes abrir la consola de Chrome usando F12 y escribir directamente:
myGameInstance.SendMessage('Sphere', 'SetHeight', 3)
Presione Enter para llamar a la función Moviendo la esfera. El movimiento solo se reflejará en el renderizado si tiene configurado Ejecutar en segundo plano o si configura Application.runInBackground en verdadero. Esto se debe a que, de forma predeterminada, el renderizado solo ocurre cuando la ventana del lienzo tiene el foco.
Utilice Debug.Log al depurar plataformas de navegador. Todos los mensajes se envían a la consola del navegador. Para Chrome, lo encontrará presionando F12 y cambiando a la pestaña Consola. Pero la clase Debug ofrece más opciones. Al utilizar Debug.LogError, la consola proporcionará un seguimiento de la pila que puede resultar útil.
Más información
Le recomendamos que utilice la opción Desarrollo de compilación durante el desarrollo, pero desmarque esta opción cuando implemente su juego en un sitio en vivo. Para una versión de lanzamiento, tiene la opción de compresión. Es posible que necesites ajustar la configuración de tu servidor cuando utilices la compresión; consulte el manual para obtener consejos sobre cómo hacer esto.
Es importante perfilar su proyecto durante todo el ciclo de desarrollo para detectar los problemas de rendimiento a tiempo. Unity Profiler es una buena herramienta para identificar y solucionar cuellos de botella en el rendimiento de tu juego. Realiza un seguimiento del uso de la CPU y la memoria, lo que te ayuda a identificar áreas de tu juego que necesitan optimización. También puede utilizar el Analizador de perfiles, el Analizador de memoriay la Superposición de diagnóstico web junto con él.
Descargue el libro electrónico Guía definitiva para crear perfiles de juegos de Unity para obtener información detallada sobre la creación de perfiles en Unity.
Veamos algunos consejos para comenzar a crear perfiles de una compilación web de Unity.
Habilitar el perfilador de Unity
Vaya a Archivo > Configuración de compilación en el Editor y seleccione Compilación de desarrollo y Autoconectar Profiler para usar Profiler con una compilación web.
Seleccione el módulo de uso de CPU
Utilice este módulo para analizar el rendimiento de su código e identificar áreas que están causando problemas de rendimiento. Analice elementos como llamadas a funciones, ejecución de scripts y recolección de basura.
Seleccione el módulo Memory Profiler
Las compilaciones de Unity Web tienen recursos de memoria limitados en comparación con otras plataformas. Utilice este módulo para analizar el uso de memoria de su aplicación e identificar áreas de optimización.
Utilice el panel de rendimiento de Chrome DevTools
Chrome DevTools incluye un panel de rendimiento que te ayudará a profundizar en los cuellos de botella de tu juego. Entre otras características, proporciona un panel de Fuentes para agregar puntos de interrupción en archivos JavaScript y un panel de Consola para ver mensajes de depuración e ingresar código JavaScript.
Medir el rendimiento en diferentes dispositivos
Esto te ayudará a identificar problemas de rendimiento que pueden ser específicos de un dispositivo o navegador en particular y puede ayudarte a optimizar tu juego en consecuencia.
Reducir el número de llamadas de sorteo
Las llamadas a sorteos son uno de los principales cuellos de botella de rendimiento para las compilaciones web de Unity. Utilice Unity Profiler para identificar áreas con una gran cantidad de llamadas de sorteo e intente reducirlas.
Analizar el rendimiento en dispositivos de gama baja
Pruebe en dispositivos de gama baja para asegurarse de que su aplicación esté optimizada para una amplia gama de hardware.
Habilite "Ejecutar en segundo plano" durante la creación de perfiles
Si Ejecutar en segundo plano está habilitado en la configuración de WebGL Player o si habilita Application.runInBackground, su contenido continuará ejecutándose cuando el lienzo o la ventana del navegador pierdan el foco, lo que puede ser útil al crear perfiles.
Las compilaciones web de Unity son una excelente manera de distribuir tu juego a una amplia audiencia. Durante el desarrollo, debes intentar mantener la geometría y las texturas en un tamaño modesto, reducir las llamadas de dibujo y crear perfiles y pruebas en una amplia gama de dispositivos. Por último, utilice URP para garantizar un rendimiento sólido en la más amplia gama de hardware.
Más información
Consejos y trucos para usar el módulo WebGL de Unity
Acceso temprano al nuevo backend WebGPU en Unity 2023.3
Encuentre todos los libros electrónicos y artículos avanzados de Unity en el centro de mejores prácticas de Unity.