Jump to content
UnitySpain
Sign in to follow this  
banics

Lag al mostrar UI por primera vez.

Recommended Posts

Hola buenas. Tengo un problema al usar elementos UI para mostrar distintos menús en mi juego. He estado buscando información y veo que es un problema que suele ocurrir, pero ,aún intentando todos los métodos que he encontrado, no soy capaz de resolverlo.
El tema es el siguiente. Tengo un canvas, y dentro de él, tengo emparentados todos los menús que quiero mostrar (cada uno es un objeto vacío con todos los elementos dentro). El problema es que, al mostrar cualquiera e ellos por primera vez, se produce un pequeño tirón, el cual desluce algunas animaciones y sonidos, ademas de ser algo molesto.

Cosas que he intentado y no han funcionado:

  • Sustituir el gameObject.setActive(true o false), para mostrar/ocultar el menú, asignando un canvas a cada menú, y desactivar / activar dicho canvas.
  • Sustituir el gameObject.setActive(true o false), para mostrar/ocultar el menú, modificando la escala del menú (1 cuando se active y 0 cuando se muestre) empezando este activado.
  • Sustituir el gameObject.setActive(true o false), para mostrar/ocultar el menú por Instantiate.
  • Haciendo que el menú empiece activado y desactivarlo en el Awake o Start.
  • Cargando la escena desde otra
  • Haciendo que el menú a activar este vacío (aún así pega el tirón).
  • Haciendo que el objeto empiece activado en un punto, y al activarlo, traerlo al punto por defecto para mostrarlo por pantalla.
  • Desactivar todos los check box Raycast en textos e imágenes.

El problema solo pasa la primera vez que se muestra, luego no da tirón ninguno. 

Muchas gracias de antemano y un saludo.

Share this post


Link to post
Share on other sites

Es una de las cosas que tengo controladas, así que te lo puedo explicar. Atento:

  1. NUNCA uses gameObject.SetActive(true/false), para mostrar u ocultar, o activar y desactivar. NUNCA.
  2. En lugar de tener un Canvas del cual descienden los menús, trátalo por separado: Cada Canvas es un menú propio o una página del menú. Es correcto usar múltiples Canvas en una escena.

 

Vale. Una vez has entendido ésto, existe un componente que le puedes asignar a cada panel, control, o a cada Canvas completo para controlarlo cuando quieras....

Se trata del CanvasGroup, y permite manipular la Interactividad, la visibilidad (alpha), y el raycasting de cualquier gameobject (y children) al que está añadido. Échale un vistazo...

 

La cosa es, ten múltiples Canvas en una escena, que sirvan para mostrar uno u otro menú de tu juego, con sus controles cada uno, etc. Desde aquí:

  • Cada Canvas tiene un componente llamado Canvas, y otro más pasivo llamado CanvasRenderer.

Cuando quieras mostrar u ocultar un Canvas concreto, o bien usas el CanvasGroup o bien recoges y cambias una propiedad del CanvasRenderer. La gracia está en que te sepas gestionar bien trabajando con varios Canvas a la vez.

 

Al principio crees que no tiene sentido tener mútliples Canvas y que va a ser contra-intuitivo, pero nada más lejos de la verdad. Notarás la diferencia abismal en rendimiento, apenas le afecta y va estupendo.

Share this post


Link to post
Share on other sites

Hola pioj. Antes de nada, gracias por contestar. 

La cosa es que ya probé esa opción. A un menú en concreto lo saqué del canvas principal, le asigne un canvas y probé dichas opciones. Activar/Desactivar el canvas y asignarle un canvas group, para manejar el componente alpha y ninguno funcionó.

La cosa es que, incluso activando un menú vacío (sin ningún componente que mostrar) da le tirón, cosa que me tiene desquiciado XD.

De todas maneras, he estado viendo el componente CanvasRendered y no tiene apenas nada que se pueda tocar. Como mucho en Debug,  se puede alterar un campo InstanceID, Local identifier File, que supongo por el nombre que serán cosas internas del motor ajenas a este problema.

Gracias de antemano y un saludo.

Share this post


Link to post
Share on other sites
18 hours ago, banics said:

El problema solo pasa la primera vez que se muestra, luego no da tirón ninguno.

Yo he tenido un solo canvas, con cada menú dentro (multiples canvas) y nunca paso nada. Me pregunto que script tendrás asignado en tus menus (u objetos internos) que al dispararles el Awake o Start (sobretodo awake) te estará causando ese tirón. Me parece que después de todo lo que dejiste no es un problema de "On/Off" sino más bien interno.

Podrías subir el código que tengas asignado al menú/items? o simplemente tenés los UnityEvents de OnClick, etc?

O simplemente crea un build de tu escena y compártela, así vemos si nos pasa lo mismo o no ... para ir descartando un poco.

6 hours ago, banics said:

De todas maneras, he estado viendo el componente CanvasRendered y no tiene apenas nada que se pueda tocar. Como mucho en Debug,  se puede alterar un campo InstanceID, Local identifier File, que supongo por el nombre que serán cosas internas del motor ajenas a este problema.

CanvasRenderer es un componente (https://docs.unity3d.com/ScriptReference/CanvasRenderer.html) podés activar o desactivarlo, esto es lo que se debe hacer para menús (o lo mismo para objetos 3D y MeshRenderer, o Sprites y spriteRenderer).

Saludos

 

Share this post


Link to post
Share on other sites

Yo tampoco he tenido problemas de ese tipo. Ahora bien, yo preparo todos los datos necesarios de los componentes de los Canvas (instanciamientos, parámetros dinámicos, posición gps si el caso, AR targets, etc) antes de visualizar un sólo píxel de la scene colocando un background de carga o lo que sea por encima.

Share this post


Link to post
Share on other sites

Hola buenas. 
Ante todo, muchas gracias por las respuestas!
Haciendo múltiples pruebas, ya he descubierto lo que causa el pequeño tirón de lag, y no es otro que los componentes que uso para capturar los eventos (Button y EventTrigger), los cuales uso para capturar las pulsaciones de botón, o cuando lo clickeas pero no levantas el dedo para que se iluminen botones, etc....
 

He hecho la siguiente prueba. Implemente un Invoke, que hizo que cargara un menú a los 4 segundos de iniciar la App, y al cargarlo, no pega tirón ninguno.
Ahora sabiendo esto, quiero probar implementando otro método para capturar las pulsaciones, pero no se muy bien como hacerlo, ya que lo único que se me ocurre es por raycast.

Gracias de antemano y un saludo.

Edited by banics

Share this post


Link to post
Share on other sites
2 hours ago, banics said:

o que causa el pequeño tirón de lag, y no es otro que los componentes que uso para capturar los eventos (Button y EventTrigger), los cuales uso para capturar las pulsaciones de botón, o cuando lo clickeas pero no levantas el dedo para que se iluminen botones

Luego, íbamos bien encaminados cuando sospechábamos que no tenía que ver con el renderizado del Canvas en sí, sinó en algún código paralelo que tuvieras por ahí... :27_sunglasses:

 

2 hours ago, banics said:

quiero probar implementando otro método para capturar las pulsaciones,

¿Lo estabas haciendo todo dentro de un bucle o algo? Exactamente, qué hacías con los EventTrigger? 

¿Asignabas algún OnClick.AddListener por código, o algo así? Yo me he encontrado con lag en ocasiones al asociar una acción a Buttons, por código...

Share this post


Link to post
Share on other sites
On 6/23/2019 at 8:42 PM, pioj said:

Luego, íbamos bien encaminados cuando sospechábamos que no tenía que ver con el renderizado del Canvas en sí, sinó en algún código paralelo que tuvieras por ahí... :27_sunglasses:

¿Lo estabas haciendo todo dentro de un bucle o algo? Exactamente, qué hacías con los EventTrigger? 

¿Asignabas algún OnClick.AddListener por código, o algo así? Yo me he encontrado con lag en ocasiones al asociar una acción a Buttons, por código...

Hacía lo básico, le asignaba una función al componente button o al EventTrigger que correspondiera. Pero no era ni un bucle ni nada, simplemente una función.

Un saludo.

 

Saludos de nuevo. Voy comentando cosas que he descubierto, por si a alguien le pasa el mismo problema que no se vuelva loco.
Al descubrir que el lag provenía (o al menos eso creía) del componente button y eventTrigger propios de Unity, hice un nuevo método para pulsar botones, basado en hacer raycast.
Pues bien, al hacerlo nos dimos cuenta de cual era el verdadero origen del lag era el acto de pulsar la pantalla (Ya sea por el Event trigger de PointerDown o al tirar el rayo).

El código que se ejectura es el siguiente:

public void PressedChangeSprite()
    {
        if (!_disableButton && !_active) 
        {
            _buttonImage.sprite = _pressedSprite;
            
            if (_buttonText != null) {
                PressedIluminateText ();
            }
        }
    }

public void PressedIluminateText()
    {
            Color color = new Color ();
            color.a = 1f;
            color.b = 1f;
            color.g = 1f;
            color.r = 1f;

            _textColor = _buttonText.color;
            _buttonText.color = color;

    }

 

No creo que sea del código, por que he probado a comentarlo y sigue dando lag la primera vez...no entiendo por que.

Seguiré investigando y os avanzare cualquier cosa que descubra. Gracias de antemano y un saludo.

Share this post


Link to post
Share on other sites
17 hours ago, iRobb said:

Todo eso del color lo podrías hacer con las opciones automáticas de selectable.colors en vez de a piñón y así asignar el color en el editor.

https://docs.unity3d.com/ScriptReference/UI.Selectable-colors.html

Tampoco entiendo que te estés montando un sistema para pulsar botones basado en raycast a menos que sea VR y no me haya enterado.

 

Hola iRobb, gracias por contestar. Lo del raycast era simplemente por probar a ver si el lag lo causaba el componente propio del botón de unity....pero bueno, al final  se ha visto que no era así.
Intentare lo del color, pero aun así, he comentado ese código entero, y sigue dando el tirón. Lo raro es que en el editor nada, no da ningún tirón. No sabemos si es algo propio de las pantallas de movil, algún tipo de latencia interna o algo. 

Gracias y un saludo.

Share this post


Link to post
Share on other sites

Yo trabajo mucho con UI de móvil y a menos que esté moviendo rápidamente una textura de pantalla completa que contenga más texturas/sprites dentro, no tengo lags en móviles de gama media.

Falta mucha más info para saber dónde está el problema.

Share this post


Link to post
Share on other sites

Hola de nuevo. Comento mis nuevos progresos. 

He ido ahondando en el asunto, y finalmente ya sabemos la causa real del pequeño tirón del lag, y no es otro que la primera pulsación que se haga en la pantalla.

En cuanto se hace una pulsación (sea donde sea) pega un pequeño tirón de lag..de ahí que creyera que era al cargar un menú....por que mi primera pulsación era dar a un botón para cargar dicho menú.

Os dejo una captura del profiler, la cual me parece interesante. El pico que he encerrado en el círculo rojo, es el pico que da cuando ocurre la primera pulsación (pequeño tirón de lag).

La cosa es que, investigando este problema, he visto que a varias personas le ocurre. Encontré una que lo solucionó eliminando el componente Standalone Input Module (este componente esta en el EventSystem). La cosa es que si lo elimino, no hay manera de que los botones hagan funciones salvo que tire un rallo manualmente.
No se si a alguno mas os habrá pasado.

Gracias de antemano y un saludo.

PD: Se que no va a ser debido a esto pero...¿Podria ser que estamos usando un atlas (varias imagenes en una misma recortadas con el sprite editor de Unity) en vez de una imagen por sprite el origen del problema?

 

Captura.PNG

Edited by banics

Share this post


Link to post
Share on other sites
11 hours ago, banics said:

Hola de nuevo. Comento mis nuevos progresos. 

He ido ahondando en el asunto, y finalmente ya sabemos la causa real del pequeño tirón del lag, y no es otro que la primera pulsación que se haga en la pantalla.

En cuanto se hace una pulsación (sea donde sea) pega un pequeño tirón de lag..de ahí que creyera que era al cargar un menú....por que mi primera pulsación era dar a un botón para cargar dicho menú.

Os dejo una captura del profiler, la cual me parece interesante. El pico que he encerrado en el círculo rojo, es el pico que da cuando ocurre la primera pulsación (pequeño tirón de lag).

La cosa es que, investigando este problema, he visto que a varias personas le ocurre. Encontré una que lo solucionó eliminando el componente Standalone Input Module (este componente esta en el EventSystem). La cosa es que si lo elimino, no hay manera de que los botones hagan funciones salvo que tire un rallo manualmente.
No se si a alguno mas os habrá pasado.

Gracias de antemano y un saludo.

PD: Se que no va a ser debido a esto pero...¿Podria ser que estamos usando un atlas (varias imagenes en una misma recortadas con el sprite editor de Unity) en vez de una imagen por sprite el origen del problema?

 

Captura.PNG

Señala en el profiler ese pico azul que es un script a ver cual es y el desglose de sus componentes.

 

Share this post


Link to post
Share on other sites

Voy a decir una tontería... Tal vez desactivando desde el principio el StandAloneInput y luego activarlo mediante script en el Start()? Creéis que haría algo?

Share this post


Link to post
Share on other sites
Sign in to follow this  

×
×
  • Create New...