Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

UI Vertical Layout

Iniciado por Tizon, Abril 29, 2018, 09:00:08 PM

Tema anterior - Siguiente tema
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.

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

Cita de: lightbug date=1525030239Osea 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... 
 

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
 
 
 
 
 

Vamos por partes Jack, que...


"Todo parece imposible hasta que se hace" (The_Code)


De lo único que se aprende es de los errores. 


 "Ley de Alzheimer de la programación: si lees un código que escribiste hace más de dos semanas es como si lo vieras por primera vez"
     -- Via Dan Hurvitz


-----



@SantiagoSilva87


 


 


 



Abril 30, 2018, 08:22:07 PM #4 Ultima modificación: Abril 30, 2018, 08:22:57 PM por lightbug
Cita de: Tizon date=1525104173Parece 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.anc***dPosition = 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 ));
   
   
}
}

 

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

Cita de: Tizon date=1525028408Todo 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

Seeeeeeeee... Fantastico. Era justo lo que necesitaba!!!
 
Muchas gracias a todos!!!

Etiquetas: