Я пытаюсь создать представление списка с новым пользовательским интерфейсом 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 автоматически. Дело в том, что Sprite содержится в скрипте изображения новой системы пользовательского интерфейса, и мне кажется, что я не могу получить к нему доступ. MonoDevelop не может ссылаться на это? Или я что-то упускаю?