Я пытаюсь создать представление списка с новым Unity UI (2014). Вертикальный и прокручиваемый список должен содержать кнопки изображений, которые должны сохранять их соотношение сторон на основе назначенного ими изображения! Все кнопки должны растягиваться до ширины экрана. Кнопки не должны иметь пробела к следующему. (почти как UITableView в iOS)
Я обнаружил, что VerticalLayoutGroup, которая поставляется с новым интерфейсом, не поможет мне, так как она не работает хорошо встроенной в ScrollRect. Я думаю, что для его работы с ScrollRect потребуется изменить размер на основе содержащихся элементов.
Другая проблема заключается в том, что я не мог заставить кнопки удерживать их ширину в соотношении высоты, которые я решил, написав немного script (см. ниже).
Чтобы на самом деле выполнить желаемый эффект списка, я создал Canvas с ScrollRect, который затем содержит RectTransform для моего пользовательского ListLayout script. Дети RectTransforms - это кнопки.
Структура выглядит следующим образом:
Каждый элемент в списке получает аспект сохранения script, который выглядит так:
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 script, который вычисляет его высоту в зависимости от содержащихся элементов:
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 script я хотел бы получить доступ к спрайту из GameObject автоматически. Дело в том, что Sprite содержится в Image script новой системы пользовательского интерфейса, и, похоже, я не могу получить доступ к этому. MonoDevelop не мог ссылаться на него? Или я что-то упускаю?