Jump to content
Tizon

UI Vertical Layout

Recommended Posts

Hola a todos.

Antes que nada gracias por la atención. Bien, empecemos por decir que soy programador y la parte gráfica como que menos un tercio, así que si meto algún error de base, dadme un capón sin problema.

Bueno al lio. Para situarnos. Tengo un Canvas con un Canvas Scaler puesto a Scale With Screen Size para que vaya manteniendo más o menos en diferentes formatos. Hasta aquí todo genial. Bien, quiero crear un panel con un conjunto de botones con una barra de scroll que me vayan presentando una serie de objetos en pantalla y blablablabla... El caso, creo un panel el cual me hace de marco, en el que añado los componentes ScrollRect y Mask. Dentro de este un Panel contenido, al que añado un Vertical Layout Group. Luego a este Panel Contenido, voy añadiendo los prefabs de los botones. Huelga decir que en tiempo de ejecución no se cuantos de estos he de presentar. Sino sería muy fácil, no? Bueno, todo me va genial, los botones se ven estupendos, el Mask me recorta justo dónde quiero, el Scroll bar se ajusta estupendamente. Todo perfecto excepto una cosa, como no sé el número de botones en tiempo de ejecución, me deja un espacio final bastante grande que queda feo. Bueno, no importa, como conozco el tamaño de los botones, pues no importa, hago el chid count y lo multiplico por el tamaño... Que feliz es uno en su inocencia. Ni modo. He probado de varios modos. Entiendo que la forma correcta de generar el size del Panel es con un RectTransform.sizeDelta = new vector2.pasandole el ancho y el alto deseado. Esto me da bien en Weith, pero el Heigth no hay modo. Siempre me queda ese cacho vació feo abajo del todo. He probado con un float, recorriendo todos los childs y sumando su Heigth. Tampoco. Supongo que el problema viene de que entre el modo diseño y el modo ejecución varian las medidas, y que por algún motivo me coge los Heigths de los prefabs de base, antes de escalarlos. Si alguien tiene alguna idea de como puedo ajustar el alto de este panel contenido, o alguna idea de por dónde la estoy cag... estaría muy agradecido.

PD: Ya se que existe la opción de marcar que los Childs ajusten tamaño o separación, pero si permito en tamaño me los deforma, ya que tienen mucho contenido, y con la separación queda fatal.

Muchas gracias a todos.

Share this post


Link to post
Share on other sites

Osea que querés hacer entrar unos elementos de tamaño fijo (ya que impones que no se defoirmen) en un panel de tamaño fijo (supongo ?) y no permitis padding ... eso no se puede hacer, simple matemática, o por lo menos no se si estás queriendo hacer lo que me imagino, podrías subir una imagen, es que por más que lo describas bien siempre una imagen es mejor.

saludos

Share this post


Link to post
Share on other sites
hace 20 horas, lightbug said:

Osea que querés hacer entrar unos elementos de tamaño fijo (ya que impones que no se defoirmen) en un panel de tamaño fijo (supongo ?) y no permitis padding ... eso no se puede hacer, simple matemática, o por lo menos no se si estás queriendo hacer lo que me imagino, podrías subir una imagen, es que por más que lo describas bien siempre una imagen es mejor.

saludos

No me he explicado bien.

imagino que no es un problema tan poco común. Ponte por ejemplo un RTS espacial. Tienes un panel a la izquierda dónde se listan las naves que tienes (O grupos de naves). Al principio tienes dos naves, pongamos un explorador y una nave de contrucción. Pero al final del juego puedes tener un centenar de naves o de flotas... Y el panel debe de ajustarse a eso, dado que no puedes pretender que al inicio dos botones ocupen el espacio de cien sin que quede como un churro. Hasta aquí bien.

La solución parece fácil. Como no se cuantos habrá, y estos podrán ser variables en cada momento, la solución obvia es hacer el camino inverso, que el panel se adapte a la cantidad de elementos. Así pues,si partimos de que cada elemento tiene un tamaño conocido, parece una solución obvia. Se implementa una función a ejecutar cada vez que se añaden o se quitan elementos. En seudocodigo:

LargoPanel = ChildCount * TamañoConocido.

Parece evidente, no? Pues no. Cuando implemento el código, veo que me sobra un cacho importante y muy feo. Más allá de ello, parece que el cacho varía en función de la resolución con la que lo pruebo. Así pues, me da que tiene que ver con eso... Calcula los tamaños según mi pantalla en tiempo de diseño, pero en tiempo de ejecución los tamaños están escalados según la resolución. Así pues me informo y me documento.y veo que la función que cambia el tamaño en tiempo de ejecución es miPanelContenido.sizeDelta = new Vector2(Tamaño x, Tamaño Y). Para el tamaño sizeDelta X cojo el del panel contenedor. Perfecto.Y el Y que es el que interesa? Bueno, pues haga lo que haga siempre me queda ese cacho de más tan feo, he probado incluso hasta contar uno a uno los tamaños de los botones en un bucle,

ContadorTamaño =+ GetChild(X).GetComponent<RectTransform>().rect.height;

Pero haga lo que haga, siempre me queda ese cacho feo. No sé qué hacer para poder ajustarlo y que quede más o menos bien. Ahora es cuando alguien me informa de que tal función o de que tal tic, hace que el panel se adapte al contenido y que he ido por el camino más dificil y por eso soy el único que tiene ese problema, en ese caso me daré de cabezazos en la pared por haber perdido tanto tiempo de forma tan tonta y pediré perdón por mi tontería, pero de verdad que no doy con la forma de hacerlo... 

PanelForoUnity.png

Share this post


Link to post
Share on other sites

pues haz usado Layout Group Vertical/ Horizonatal / Grid cualquiera de ellos, y los elementos dentro tienen que tener el componente "Element Layout" 

y ya, el resto de las settings las haces ahi en esos componentes, padding, tamaño etc

si el contenido se genera dinamicamente en tiempo de ejecución el area donde se muestran estos elementos aumenta o decrece según sea el caso, para gestionar eso, tiene que agregar otro componente que se llama "Content Size Filter" y eso te hara la magia del tamaño del contenedor de elementos dinamico :) 

por ejemplo aca te adjunto unas capturas de como lo implemento en una de las ventanas

 

 

layouts.png

Share this post


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

Parece evidente, no? Pues no. Cuando implemento el código, veo que me sobra un cacho importante y muy feo. Más allá de ello, parece que el cacho varía en función de la resolución con la que lo pruebo. Así pues, me da que tiene que ver con eso...

mmm que raro, el tamaño está en pixels, si tus elementos se agrandan en vertical también lo hace el panel (si estás en scale with screensize y supongo que todo está en este modo) tené cuidado con los pivots, y los puntos de anclaje, yo tengo un script (mas bien tenía pero lo recuerdo mas o menos) que hace exactamente eso que buscas en base a los elementos prefabs que voy metiendo se agranda o se achica el panel de fondo siempre pasando un valor min de tamaño.

Quizas lo que diga @TiagoSan sea lo que busques, de los helpers de la UI no tengo mucha idea siempre me fui más por el lado del código, pero por las dudas te subo el ej:

(traté de reproducirlo rapidito no era exactamente así pero para tener una idea)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class canvas_elementAdd : MonoBehaviour {

	public GameObject element;
	int currentHeight = 0;
	RectTransform m_rectT;

	int currentVerticalSize = 0;

	void Start () {
		m_rectT = GetComponent<RectTransform>();
	}
	
	
	void Update () {

		if(Input.GetKeyDown(KeyCode.KeypadPlus))
		{
			GameObject newElement = Instantiate(element);			
			newElement.transform.SetParent(transform);
			RectTransform rectT = newElement.GetComponent<RectTransform>();

			

			rectT.anchoredPosition = new Vector2(0, - currentVerticalSize);	// "-" hacia abajo
			rectT.localScale = Vector3.one;

			//currentHeight++;
			currentVerticalSize += (int)Mathf.Abs(rectT.sizeDelta.y);
			

			
				
		}else if(Input.GetKeyDown(KeyCode.KeypadMinus))
		{
			Transform lastChild = transform.GetChild(transform.childCount-1);
			RectTransform rectT = lastChild.GetComponent<RectTransform>();
			currentVerticalSize -= (int)Mathf.Abs(rectT.sizeDelta.y);
			Destroy( lastChild.gameObject );
			
		}

		m_rectT.sizeDelta = new Vector2( m_rectT.sizeDelta.x , Mathf.Clamp(currentVerticalSize, 168 , Mathf.Infinity ));

		

		
	}
}

2_DLighting_3_Sin.gif

cabe mecionar que agregando alguna que otra máscara podés hacer lo que quieras, un scrollView por ej

Edited by lightbug

Share this post


Link to post
Share on other sites
On 29/4/2018 at 14:00, Tizon said:

Todo perfecto excepto una cosa, como no sé el número de botones en tiempo de ejecución, me deja un espacio final bastante grande que queda feo.

añade al Content un componente "Content Size Fitter", con Vertical Fit = Min Size

Share this post


Link to post
Share on other sites

Seeeeeeeee... Fantastico. Era justo lo que necesitaba!!!

Muchas gracias a todos!!!

Share this post


Link to post
Share on other sites

UnitySpain © Todos los derechos reservados 2020
×
×
  • Create New...