Опитвам се да създам изглед на списък с новия потребителски интерфейс на Unity (2014). Вертикалният списък и списъкът с възможност за превъртане трябва да съдържа бутони с изображения, които трябва да запазят съотношението си въз основа на присвоеното им изображение! Всички бутони трябва да се простират до ширината на екрана. Бутоните не трябва да имат разстояние от следващия. (доста като UITableView в iOS)
Открих, че VerticalLayoutGroup, който идва с новия потребителски интерфейс, няма да ми помогне, тъй като не работи добре вграден в ScrollRect. Мисля, че ще трябва да се преоразмери въз основа на съдържащите се елементи, за да може да работи със ScrollRect.
Друг проблем е, че не можах да накарам бутоните да запазят съотношението си ширина към височина, което реших, като написах малък скрипт (вижте по-долу).
За да постигна действително желания ефект от списъка, създадох Canvas със ScrollRect, който след това съдържа RectTransform за моя персонализиран скрипт ListLayout. Децата на RectTransforms са бутоните.
Структурата изглежда така:
Всеки елемент в списъка получава скрипт за поддържане на аспект, който изглежда така:
public class KeepAspect : MonoBehaviour {
public Sprite sprite;
public float aspect = 1;
void Start() {
if (sprite != null) {
aspect = sprite.bounds.size.x / sprite.bounds.size.y;
}
}
void Update() {
RectTransform rectTransform = GetComponent<RectTransform>();
Rect rect = rectTransform.rect;
rectTransform.sizeDelta = new Vector2(rect.width, rect.width * (1f / aspect));
}
}
Моят персонализиран скрипт ListLayout, който изчислява височината си в зависимост от съдържащите се елементи:
public class ListLayout : MonoBehaviour {
public enum Direction { Vertical, Horizontal }
public Direction direction = Direction.Vertical;
public float spacing = 0;
void Start() {
}
RectTransform[] GetItems() {
RectTransform rect = GetComponent<RectTransform>();
RectTransform[] items = new RectTransform[rect.childCount];
for (int i = 0; i < rect.childCount; i++) {
items[i] = rect.GetChild(i).GetComponent<RectTransform>();
}
return items;
}
void Update() {
RectTransform rectTransform = GetComponent<RectTransform>();
RectTransform[] items = GetItems();
// stick together
if (direction == Direction.Vertical) {
float y = 0;
foreach (RectTransform item in items) {
Rect rect = item.rect;
item.anchoredPosition = new Vector2(0, -y);
item.sizeDelta = new Vector2(rectTransform.rect.width, rect.height);
y += rect.height + spacing;
}
// adjust height
rectTransform.sizeDelta = new Vector2(rectTransform.sizeDelta.x, y);
}
// TODO: horizontal layout
}
}
Имам два въпроса към този подход:
1) Има ли начин да се направи списъчен изглед без персонализирани (грозни) скриптове? Трябва ли да има по-добър начин?
2) В скрипта KeepAspect бих искал да имам автоматичен достъп до спрайта от GameObject. Работата е там, че спрайтът се съдържа в скрипта за изображение на новата UI система и изглежда, че нямам достъп до този. MonoDevelop не можа да го препоръча? Или пропускам нещо?