Compatibilidad del navegador con WebGL
Depuración y la resolución de problemas de construcciones WebGL

Construyendo y Corriendo un Proyecto WebGL

Cuando usted construya un proyecto WebGL, Unity va a crear una carpeta con los siguientes archivos:

  • un archivo index.html para que los navegadores puedan navegar y cargar su contenido.
  • una carpeta Development o Release que contiene los archivos output de su construcción generada (el cual depende si usted hizo una development build o no).
  • una carpeta TemplateData (al menos cuando construya con el default template (plantilla predeterminada), conteniendo la barra de cargar y otros assets plantilla. Ver la página del manual acerca de WebGL templates para más información.

El Development o Release contiene los siguientes archivos (remplace MyProject con el nombre de sus proyectos). Si usted hace una construcción release, los archivos en esta carpeta serán comprimidos y tendrán un sufijo gz. Ver los comentarios en el tamaño de Distribución abajo.

  • un archivo JavaScript MyProject.js que contiene el código para su reproductor.
  • un archivo MyProject.js.mem que contiene una imagen binaria para inicializar la memoria heap par su reproductor.
  • un archivo MyProject.data que contiene los datos del asset y escenas.
  • un archivo UnityLoader.js que contiene el código necesitado para cargar el contenido de Unity en la página web.

Usted puede ver su reproductor WebGl directamente en la mayoría de exploradores al simplemente abrir el archivo index.html. Por razones de seguridad, Chrome coloca restricciones en scripts abiertos desde file: URLs locales, por lo que esta técnica no va a funcionar. Si usted utiliza el comando Build & Run de Unity (menú File > Build & Run) entonces el archivo será temporalmente alojado en el servidor local web y abierto desde un URL localhost (esto evita las restricciones de seguridad). Usted también puede correr Chrome con la opción de linea de comando --disable-web-securitypara habilitar que se cargue contenido desde file: urls.

En algunos servidores usted necesitará hacer que los archivos “.mem” y “.data” sean accesibles. El servidor va a necesitar proporcionar estos archivos a clientes.

Build Player Options (Opciones para Construir el Reproductor)

WeGl le permite a usted seleccionar un nivel de optimización en la ventana de Build Player. Estos corresponden a flags de optimización (–01 - –03) pasados a un compilador emscripten. En general, “Slow” produce construcciones no optimizadas, pero tienen un mucho menor tiempo de construcción que las otras opciones, por lo que puede ser utilizado para iterar en problemas de código. “Fast” produce construcciones optimizadas, y “Faster” habilita algunas optimizaciones adicionales, pero hace que sus construcciones tomen un mayor tiempo para completarse (por lo que usted podría querer utilizarlo para su lanzamiento final).

Cuando usted marca la casilla de verificación “Development Build”, Unity va a generar una construcción de desarrollo (con soporte del perfilador y la consola de desarrollo para errores, como en cualquier otra plataforma). Adicionalmente, los Development builds no son minimizados, por lo que el JavaScript generado es leíble para humanos y preserva los nombres de las funciones (para que usted tenga una pila de seguimiento para errores útil), pero muy grande para distribuir.

La casilla de verificación “Autoconnect Profiler” debe ser utilizada cuando usted quiere perfilar su contenido WebGL de Unity. No es posible conectar el Profiler a una construcción en ejecución como otras plataformas, ya que la conexión del perfilador es manejado utilizando WebSockets en WebGL, pero el explorador solamente va a permitir conexiones salientes del contenido, por lo que la única manera de utilizar el Profiler en WebGl es marcar “Autoconnect Profiler” para tener el contenido conectado al Editor.

Ajustes del Reproductor (Player Settings)

WebGL tiene algunas opciones adicionales en los Player Settings (menú: Edit > Project Settings > Player).

La opción Strip Engine Code en Other Settings le permite a usted habilitar el stripping de código para WebGl. Si usted habilita Stripping, Unity no va a incluir el código para cualquier clase que usted no utilice - por lo que si usted no utiliza algún componente de física o métodos para instanciar, todo el motor de física será stripped (extraído) de su construcción. Ver la sección de stripping abajo para más detalles.

El campo de WebGL memory size en Publishing Settings le permite a usted específica qué tanta memoria (en MB) el contenido debería asignar para su heap. Si este valor es demasiado bajo, usted obtendrá errores ‘out of memory’ cuando su contenido cargado y escenas no encajen en la memoria disponible. Sin embargo, si usted configura este valor demasiado alto, su contenido podría fallar en cargar algunos exploradores o en algunas maquinas, ya que su explorador podría no tener la suficiente memoria disponible para asignar el tamaño heap solicitado. Este valor está escrito en una variable llamada “TOTAL_MEMORY” en el archivo html generado, por lo que si usted quiere experimentar con este ajuste, usted puede editar el archivo html para evitar la necesidad de re-construir su proyecto. Ver la página del manual acerca del uso de memoria de WebGL para más detalles.

La ventana emergente Enable Exceptions en Publishing Settings le permite a usted habilitar el soporte de excepciones en WebGL. Si usted no necesita un soporte de excepción, configure esto a “None”, que le dará a usted el mejor rendimiento y las construcciones más chiquitas. Cualquier excepción lanzada va a causar que su contenido pare con un error en ese ajuste. No obstante, si usted necesita utilizar excepciones, usted puede configurarlo a:

  • Explicitly Thrown Exceptions Only (por defecto), lo cual le va a permitir atrapar excepciones que son explícitamente lanzadas con una declaración “trow”, y hará bloques “finally” en su código que funcionen. Esto hará que el código JavaScript generado de los scripts del usuario más grandes y lentos, pero usualmente esto no es mucho problema si los scripts no son el cuello de botella principal de su proyecto.
  • Full, que, adicionalmente a lo anterior, también va a generar excepciones para referencias Null y para accesos que estén fuera del limite de un arreglo. Estas son generada al incrustar revisiones a cualquier acceso a referencias al código generado, por lo que va a causar un aumento en el tamaño del código adicional y slowdowns (más lento). También, esto va a agregar managed stack traces a excepciones. Es recomendable utilizar este modo solamente cuando usted necesite depurar problemas en su código, ya que genera construcciones muy grandes y lentas.

La casilla de verificación Data caching en Publishing Settings le permite habilitar un almacenamiento en caché local de los datos de su reproductor automáticamente. Si esto está activado, sus assets serán almacenados a un almacenamiento en caché local en la base de datos IndexedDB en los explorados, para que no tengan que ser re-descargados en posteriores ejecuciones de su contenido. Tenga en cuenta que diferentes explorados tienen diferentes reglas acerca del almacenamiento en IndexedDB, y puede preguntarle al usuario por permiso para almacenar los datos si esto es habilitado, y su construcción excede alguna limitación de tamaño definida por el explorador.

Tamaño de Distribución

Cuando publique para WebGl, es importante mantener el tamaño de su construcción baja para que las personas obtengan un tiempo de descarga razonable antes de que el contenido inicio. Para recomendaciones generales acerca de la reducción de tamaños de asset, ver Reduciendo el tamaño del archivo de la construcción. Algunos comentarios adicionales específicos a WebGL:

  • Especifique el formato de compresión de textura “Crunch” para todas sus texturas comprimidas en el Texture Importer.
  • No despliegue Development Builds (Construcciones de desarrollo), estas no son comprimidas ni Minified y tienen tamaños de archivo mucho mayores.
  • Configure el Optimization Level (nivel de optimización) a “Fastest”
  • Configure “Enable Exceptions” en los Payer Settings a “None” si usted no necesita excepciones en su construcción.
  • Habilite “Strip Engine Code” en los Player Settings.
  • Tenga cuidado cuando utilice dlls manejadas por terceros, ya que estos pueden traer muchas dependencias y aumentar el tamaño del código emitido significativamente.

Si usted hace una construcción de lanzamiento, Unity va a comprimir los archivos de construcción de salida utilizando la compresión gzip. Si su servidor web está configurado correctamente, estos archivos serán des-comprimidos por el explorador durante la descarga en en nivel del protocol http. Sin embargo, esto significa que usted necesita asegurarse de que su servidor http en realidad proporcione los datos comprimidos. Si usted es anfitrión de sus archivos en un servidor web Apache, Unity va a escribir un archivo .htaccess invisible en la carpeta de resultados de la construcción, que le dice a Apache en comprimir las transferencias, por lo que esto debería funcionar. Si usted está utilizando otros servidores web, revise el manual de su servidor.

Si su servidor web no está configurado para servir archivos gzip comprimidos en el nivel del protocol http, desde Unity 5.3, Unity va a descomprimir los datos para usted en el tiempo de carga en JavaScript. Por lo que usted todavía estaría utilizando archivos comprimidos, pero habría una demora extra al comienza para descomprimir los datos. Usted podría darse cuenta que esto sucede cuando usted ve un mensaje así en la consola JavaScript del explorador:

Decompressed Release/build.asm.jsgz in 82ms. You can remove this delay if you configure your web server to host files using gzip compression.

AssetBundles

Debido a que todos los datos de sus assets necesitan ser pre-descargados antes de que su contenido inicio, usted debería considerar mover los assets afuera de sus archivos de datos principales a AssetBundles. De esta manera, usted puede crear una pequeña escena de cargar para su contenido el cual carga rápidamente, y dinámicamente carga los assets en demanda a medida que el usuario procede a través de su contenido. También, los AssetBundles lo ayudarán con asset data memory, ya que usted será capaz de descargar datos de assets desde memoria para assets que usted no necesita más al llamar AssetBundle.Unload].

Algunas consideraciones aplican cuando utilice AssetBundles en la plataforma WebGL.

  • Cuando usted esté utilizando tipos de clases en su AssetBundle que no están siendo utilizados en su construcción principal, esto puede causar que Unity strip (excluya) el código para esas clases de la construcción, lo que luego causa que falle cuando intente cargar los assets del AssetBundle. Ver la sección acerca de Stripping abajo para aprender a cómo solucionar esto.

  • Ya que WebGL no soporta threading (hilos), y ya que las descargas http serán solamente disponibles cuando terminen, las construcciones WebGL de Unity necesitan descomprimir los datos de AssetBundle en el thread (hilo) principal cuando la descarga haya finalizado, por lo tanto bloquea el thread principal. Para evitar esta interrumpción, usted podría de dejar de utilizar el formato por defecto LZMA para sus AssetBundles, y comprimirlos utilizando LZ4 más bien, el cual tiene una descompresión muy eficiente en demanda. Si usted necesita tamaños de compresión más pequeños entonces LZ4 cumple, usted puede configurar su servidor web para comprimir gzip los archivos en el nivel del protocol http (encima de la compresión LZ4).

  • El almacenamiento en caché de AssetBundle utilizando WWW.LoadFromCacheOrDownload es soportado en WebGL utilizando el API INdexedDB del explorador para implementar el almacenamiento en caché en el computador del usuario. Tenga en cuenta que IndexedDB podría tener un soporte limitado en algunos exploradores, y que los navegadores podrían pedirle autorización al usuario para almacenar los datos en disco.

Stripping

Por defecto, Unity va a realizar code stripping en su construcción - esto puede ser controlado utilizando la opción Strip Engine Code en other Settings. Code Stripping va a escanear su proyecto para cualquier clase utilizada derivada de UnityObject (ya sea siendo referenciada en su código script, o en los datos serializados de sus escenas), y va a strip el código de cualquier de los Unity subsystems que no tienen ninguna de sus clases utilizadas de la construcción. Esto hará que su construcción emita menos código, resultando en descargas más pequeñas y menos código para parse (significando que el código será parsed más rápido utilizando menos memoria). Por lo que por lo general es recomendable siempre construir con stripping habilitado.

Es posible, sin embargo, que el code stripping pueda causar problemas con su proyecto y excluya código que sea necesario. Esto puede ser en el caso cuando usted cargue AssetBundles en tiempo de ejecución que contienen clases que no están incluidas en la construcción principal, y por lo tanto han sido stripped del proyecto. Usted verá mensajes de error como este en la consola JavaScript del explorador cuando esto suceda (potencialmente seguido por más errores):

Could not produce class with ID XXX
  • dónde XXX puede ser consultado en la Class ID Reference para ver qué cual a cuál clase pertenece la instancia que está creando. En tales casos usted puede obligar a Unity en que incluya el código para esa clase en la construcción, ya sea al agregar una referencia a la clase a sus scripts o a sus escenas, p al agregar un archivo link.xml a su proyecto. Aquí hay un ejemplo que se asegura que la clase Collider (y por lo tanto el modulo de Físicas) sea conservada en el proyecto - agregue este código xml a un archivo llamadolink.xml, y coloque ese archivo a la carpeta suya de Assets:
<linker>
    <assembly fullname="UnityEngine">
        <type fullname="UnityEngine.Collider" preserve="all"/>
    </assembly>
</linker>

Usted siempre puede intentar desactivar la opción Strip Engine Code para pruebas, si usted sospecha que el stripping está causando problemas con su construcción.

Unity todavía no proporciona una manera conveniente de ver qué módulos y clases son incluidas en la construcción, lo cual le permitiría a usted optimizar su proyecto para que haga el stripping bine. Estamos trabajando para proporcionar esa información - mientras tanto, usted podría querer mirar al archivo generado Temp/StagingArea/Data/il2cppOutput/UnityClassRegistration.cpp después de hacer una construcción, para obtener una visión general de las clases y módulos.

Tenga en cuenta que la opción Strip Engine Code solamente afecta el código del motor de Unity. IL2CPP siempre siempre va a strip código byte de sus managed dlls y scripts. Esto puede causar problemas cuando usted necesite referenciar managed types dinámicamente a través de reflection en vez de a través de referencias estáticas en su código. Si usted necesita acceder tipos a través de reflection, usted podrían también necesitar configurar un archivo link.xml para preservar estos tipos. Ver la página de documentación acerca de optimización del tamaño de la construcción iOS par más información acerca de archivos link.xml.

Moviendo archivos de salida (output) de la construcción

Si usted quiere cambiar la ubicación de los archivos de salida relativo al archivo index.html, usted lo puede hacer al editar los campos dataUrl, codeUrl, y memUrl y la etiqueta script UnityLoader.js en el archivo index.html. Usted puede especificar URLs en servidores externos para estos si usted quiere ser un anfitrión de sus archivos en un CDN, pero usted tiene que asegurarse que el servidor que es anfitrión tiene habilitado CORS para este trabajo. Ver la página del manual WebGL networking para más información acerca de CORS.

Compatibilidad del navegador con WebGL
Depuración y la resolución de problemas de construcciones WebGL