Ha pasado una cantidad infinita de tiempo optimizando la interfaz de usuario de Unity. Pero para causar inhibición, es suficiente una pequeña modificación del pequeño atributo del elemento casi invisible UI Canvas. Y cuando eso suceda, incluso la creación de perfiles de Unity UI no lo salvará de reducir FPS. ¿Estás listo para una larga corrección de errores?Esto es exactamente lo que sucedió en mi último proyecto ...Trabajé duro para optimizar varios paneles de interfaz de usuario en el puerto de nuestro juego en
Oculus Quest . Básicamente, la tarea consistía en reducir el nivel de sobregiro a valores aceptables para que la GPU pudiera hacer frente a lo más importante: el renderizado 3D real.
Así que trabajé en optimizar la interfaz de usuario de Unity durante al menos un mes, y finalmente hice un progreso bastante bueno.
En algún momento, la interfaz de usuario se optimizó tanto que apenas afectó los tiempos de la GPU. Las técnicas de atenuación de la interfaz de usuario opaca que implementé compensaron la mayoría de los redibujos causados por la superposición de la interfaz de usuario (elementos dibujados sobre otros elementos).
Entonces, obtuve un sistema de interfaz de usuario híbrido altamente optimizado, que esencialmente superpuso los elementos 3D dibujados debajo de él. Se ha vuelto muy fácil descartar la representación de estos fragmentos superpuestos.
Sin embargo, el trabajo aún estaba lejos de completarse ...Cuando conecté el
Unity UI Profiler , una cosa me llamó la atención.
Vi que una CPU sobrecargada gasta más de
1 ms en cada cuadro al representar la interfaz de usuario. Esto es mucho tiempo para una plataforma que te da un presupuesto de
13 ms para todo el juego: física, lógica, renderizado 3D, entrada, realidad virtual y código de red.
Y después de todo, hubo casos en que la interfaz de usuario "mató" el rendimiento de la CPU aún más.
Interfaz de usuario de Unity: lotes de compilación costososY esto dice una cosa: la
interfaz de usuario se puede optimizar para la GPU, pero esto no significa necesariamente la optimización para la CPU .
De hecho, cuando se procesa Unity UI, las tareas de CPU y GPU son muy diferentes. No es sorprendente que recomiendo abordar la optimización de CPU y GPU de manera diferente, y esto se discutió en mi publicación anterior sobre la
optimización de la interfaz de usuario de Unity .
Un perfil adicional de la interfaz de usuario de Unity reveló un problema obvio: la interfaz de usuario se recreaba constantemente en cada nuevo marco, es decir,
El lienzo (Reconstrucción del lienzo) se reconstruyó en cada cuadro .
Carga constante en la CPU durante
1 ms ... oh-oh.
Pero, ¿por qué Unity me está haciendo esto? Pensé que Unity almacena en caché todas las interfaces de Canvas ...En realidad sí, lo es. Unity efectivamente almacena en caché Canvas para que se recopilen solo una vez.
Sin embargo, el problema surge cuando cambia las propiedades de cualquiera de los elementos de la interfaz de usuario en el lienzo: color, posición, etc.
Es decir, todas las animaciones que amamos, por ejemplo, los efectos de los botones cuando pasas el mouse por encima, matas la productividad y probablemente no lo sepas.
Cuando se produce un cambio en la propiedad de la interfaz de usuario, Unity ejecuta la famosa Reconstrucción de lienzo, que arruina el rendimiento del juego .
La reconstrucción de Canvas de la interfaz obliga al motor de Unity a recorrer iterativamente todos los elementos de la interfaz de usuario de este Canvas para generar una lista optimizada de llamadas de dibujo (muchos vértices, colores, materiales, etc.). Y la reconstrucción del lienzo lleva más tiempo que el
Seat Panda para acelerar
de cero a 60 mph .
Al darse cuenta de que sufrimos constantemente la reconstrucción de Canvas, sería lógico hacer una pregunta ...
¿Por qué sufrimos reconstrucciones de Canvas y qué se puede hacer al respecto?Para responder a esta simple pregunta, tuve que pasar más de 5 horas estudiando el tema y trabajando con
Unity UI Profiler .
Vamos a hacerlo bien.
1. Profiling Unity UI: todo está bien, por ahora ...
Imagine que tenemos una interfaz de usuario simple.
Esta interfaz de usuario no hace nada, solo aparece en la pantalla y molesta al jugador que intenta ver algo a través de ella.
Como un conjunto de más de 350 imágenes en el Grupo de diseño de cuadrícula, se ve así:
Ejemplo de perfil de UI de UnityY todo está en orden, incluso a pesar de las 350 imágenes impares. En el caso estándar, la interfaz de usuario se procesará en solo dos llamadas de sorteo, porque solo hay dos imágenes únicas que no están en el atlas de sprites.
De hecho, en el generador de perfiles, puedo ver que prácticamente no hay carga por parte de la CPU.
La mayor parte del tiempo dedicado a la interfaz de usuario es inferior a
0,01 ms , lo cual es bastante bueno.
Unity UI Profiling: A Mysterious Surge(... la mayor parte del tiempo)Espera, ¿de dónde vino este aumento en los recursos de la CPU al final del gráfico?2. Perfiles de UI de Unity: ¡Reconstrucción repentina del lienzo!
¿Qué sucedió al final del Perfil de Unity? Muy extraño, en solo un segundo, la sobrecarga de la CPU en la interfaz de usuario de Unity fue más del doble.
Quiero jugar un juegoEncuentre las dos diferencias en los ejemplos a continuación
(puede que tenga que abrir las imágenes en una ventana separada para ver mejor) .
Perfiles de UI de Unity: lienzo de bajo costoUnity UI Profiling: Canvas RebuildTe doy cinco segundos para resolverlo.
5, 4 ... bueno, aquí hay un consejo para simplificar la tarea:Unity UI Profiling: Overhead Canvas RebuildWow!PostLateUpdate.UpdateRectTransform
y
UGUI.Rendering.UpdateBatches
quieren convertirse en las estrellas principales de este espectáculo.
¿Qué hacen estas áreas?
El primero,
UpdateRectTransform
, deja en claro que la transformación de algún objeto ha cambiado y, por lo tanto, Unity tiene que realizar una lógica costosa para reflejar los cambios visuales. No sabemos si fue una posición, rotación, escala o alguna otra de las propiedades de
RectTransform
.
Demonios, ni siquiera sabemos si era solo un atributo, o todos a la vez. ¿Fue un solo objeto o varios? Y cuales?
Este es el problema: no lo sabemos .
La segunda pieza costosa,
UpdateBatches
, está relacionada con la necesidad de reconstruir toda la geometría de Canvas. Este proceso se llama
Reconstrucción de lienzo . Reconstruir Canvas significa que Unity recorre toda la jerarquía de Canvas para generar una lista de llamadas de sorteo. Se calculan los vértices, índices, colores y uv de todos los elementos, y luego se realiza una pasada para combinar el número máximo posible de llamadas de sorteo para reducir la carga innecesaria en la CPU, pasándola al controlador de gráficos.
Ahora parece que sabemos lo que está sucediendo y estamos en el camino correcto. Pero, ¿cómo evitar esta revisión de Canvas? ¿Qué los causa?
Necesitamos información más específica ...
Para resumir- Cambiar un atributo en un elemento de la IU marca el elemento como sucio.
- El elemento UI puede estar completamente sucio, pero también puede estar parcialmente: partes sucias, diseño sucio, materiales sucios. Es más fácil recuperarse de estados parcialmente sucios
- Una vez que los elementos de Canvas se marcan como sucios, Unity lo reconstruye por completo.
- Las reconstrucciones de lienzo son caras para la CPU, por lo que lo más importante a evitar es
3. Buscando una plaga: una forma de fuerza bruta políticamente incorrecta
Todavía tenemos que responder la siguiente pregunta:
¿Qué causa la reconstrucción de este lienzo?Resulta que no hay
una forma
rápida de averiguarlo, especialmente con una gran jerarquía de Canvas.
Pero primero, le mostraré
un método de fuerza bruta para encontrar el motivo de la reconstrucción de Canvas .
1. Deje que Unity UI Profiler continúe grabandoFiltraremos las métricas para que podamos centrarnos en lo más importante: renderizado, scripts y UI.
Haga un seguimiento de la marca inicial para comprender los costos del esquema actual, que debe incluir la costosa reconstrucción de Canvas.
2. Desactive los objetos de juego de la interfaz de usuario y compare las lecturasSeleccione el grupo de objetos del juego y desactívelos.
Compara las métricas de rendimiento.
Si las lecturas no han mejorado mucho, continúe desactivando los objetos del juego hasta que vea una mejora significativa.
3. Encuentra lo que cambia sus propiedadesPudimos seleccionar el objeto que llama a la reconstrucción de Canvas. Pero, ¿qué se convierte exactamente en su causa?
¿Quizás su escala cambia a través del guión? ¿O está cambiando su posición por la animación?
Será conveniente hacer clic derecho en
RectTransform y seleccionar "
Buscar referencias en escena "
Cuando descubra las causas de la reconstrucción del lienzo, haga algo al respecto, como desactivar las animaciones o las transformaciones.
Rubén, pero ¿cómo uso este método con una gran jerarquía de interfaz de usuario? No me digas estupidecesDije que el proceso no será rápido ni interesante, pero los jugadores te lo agradecerán.
Ese es el punto. En primer lugar, la existencia de una gran jerarquía no es una situación ideal. Son jerarquías tan masivas y profundas que hacen que Canvas Rebuild sea tan costoso para la CPU.
Pero las jerarquías de interfaz de usuario grandes y anidadas pueden surgir (y lo harán), por lo que se espera que la reconstrucción del lienzo golpee lo más importante: la jugabilidad.
Aunque el método de fuerza bruta ayuda a encontrar la fuente de la revisión de Canvas, a la larga no escala bien.
Después de ser más profesional en la optimización de la interfaz de usuario, creé una herramienta que brinda todas las respuestas que necesito para que el proyecto cumpla con las expectativas de los jugadores ...
Reconstrucción de lienzo de perfilado4. Bonificación: Mejora de las características de optimización de la interfaz de usuario de Unity Profiler
Espero que ya entiendas lo frecuente e inquietante que puede ser la reconstrucción de Canvas.
¡Estas perestroika, que infectaron mi juego, se llevaron hasta el 10% del presupuesto total de la CPU!
Como hemos visto, existe un método de fuerza bruta para encontrar fuentes de reconstrucción de Canvas. Quizás pueda lidiar con ellos utilizando las estrategias enumeradas en mi publicación sobre la
optimización de la interfaz de usuario de Unity .
Pero un proceso tan propenso a errores nunca satisfaría a un verdadero gurú. Puede pasar varios días luchando con Canvas Rebuild, pero en el momento más inesperado volverán a desaparecer tan pronto como conecte el Unity UI Profiler.
Si está desarrollando un juego para realidad virtual, esto se vuelve crítico. No queremos que Canvas se reconstruya en la interfaz de usuario del espacio mundial. Si no puedes deshacerte de la perestroika, lo más probable es que tus jugadores no lo soporten.
Muy bien, tengo la idea de deshacerme de Canvas Rebuilds. ¡Pero Unity Profiler casi no proporciona información sobre ellos! ¿Qué me puedes aconsejar?Me alegra que hayas preguntado. Resulta que
podemos convencer a Unity Profiler para que nos brinde información útil sobre lo que dificulta el rendimiento de la interfaz de usuario .
Podemos ampliar la funcionalidad de
Unity UI Profiler . Para hacer esto, debe modificar el código fuente de Unity UI disponible públicamente.
Una vez que llegue al código fuente, necesitará
encontrar las funciones de código en las que se producen las Reconstrucciones de Canvas . Entonces necesitamos magia API con
BeginSample y
EndSample profiler .
Si está ejecutando Unity 2019.1 o anterior, el código fuente de Unity UI se ha cargado en
el repositorio de Bitbucket . También hay una guía para descargar, instalar y modificar.
¿Qué te aconsejo? Use una versión más nueva de Unity, no inferior a 2019.2.0.
Las versiones más nuevas de Unity vienen por defecto con la interfaz de usuario de origen , ya que el sistema de la interfaz de usuario ahora es parte del administrador de paquetes. Esta es la forma más sencilla.
Aquí hay una lista de piezas de código que descubrí durante mi investigación donde puedo agregar llamadas a la API de perfiles:
UI de Unity: fuente de creación de perfiles¿Es útil? Si
Conveniente para el artista / diseñador? No
Fue el poeta quien
escribió la pequeña Extensión de Unity de código abierto que amplía las capacidades del Unity Profiler .
Esta herramienta gratuita nos permitirá cambiar rápidamente entre diferentes modos de creación de perfiles para garantizar el máximo rendimiento del juego.
¿Qué es lo mejor de este expansor de Unity Profiler? Funciona fuera del editor, esencialmente lo libera de todo el dolor de cabeza al perfilar la interfaz de usuario para Android y otras plataformas.
Aquí está, toda su potencia se controla con solo dos botones:
- Mejora mi Unity Profiler
- Nerf my Unity Profiler .
Puedes obtener esta herramienta
aquí .