Как настроить только два объекта, чтобы они входили в горизонтальный макет группы в Unity3d? - PullRequest
0 голосов
/ 12 февраля 2019

То, чего я пытаюсь достичь, похоже на технику GridLayout.В Grid Layout есть опция для столбца с фиксированным ограничением, там я устанавливаю значение 2.

Проблема с сеткой состоит в том, что когда мы устанавливаем размер ячейки на определенное значение, после этого размер ячейки будетНе расширяйте себя на все остальные размеры экрана.Таким образом, пытаясь вручную установить HorizontalGroup Layout только с двумя столбцами.Проблема заключается в том, когда мне нужно создать много экземпляров.Должно быть порядка 1,2 позиции в первой строке и 3,4 позиции во второй строке и так далее.Тот, который я пробовал с Gridview, показан в Link

1 Ответ

0 голосов
/ 12 февраля 2019

Я сделал это, используя комбинацию HorizontalLayoutGroup, VerticalLayoutGroup и простого StayQuadratic, который я написал, чтобы элементы были квадратичными по ширине.

public class StayQuadratic : MonoBehaviour
{
    private RectTransform rectTransform;

    private void Awake()
    {
        rectTransform = GetComponent<RectTransform>();
    }

    private void Update()
    {
        rectTransform.sizeDelta = Vector2.one * rectTransform.rect.width;
    }
}

Конечно, этого может быть достаточно для установки этого размера только один раз, поскольку вы не будете динамически изменять размер экрана в сборке.

  • Корневому объекту требуется VerticalLayoutGroup ширина

    • childControlHeight = true;
    • childControlWidth = true;
    • childForceExpandHeight = true;
    • childForceExpandWidth = true;

    и ContentSizeFitter (только для расширения фона внизу или в случае, если вы хотите использовать его для прокрутки)

  • Будет прикреплять строки.Строка нуждается в HorizontalLayoutGroup с

    • childControlHeight = false;(Высота будет контролироваться с помощью StayQuadratic)
    • childControlWidth = true;
    • childForceExpandHeight = true;
    • childForceExpandWidth = true;

Я сделал следующий скрипт для его настройки.В этом примере я просто создаю все объекты и предметы, но, конечно, вы также можете использовать префабы с одинаковыми настройками.

[RequireComponent(typeof(ContentSizeFitter), typeof(VerticalLayoutGroup))]
public class GridWith2Columns : MonoBehaviour
{
    public Sprite sprite;

    private HorizontalLayoutGroup _currentRow;
    private GameObject placeholder;
    private int itemCounter;

    private void Awake()
    {
        var verticle = GetComponent<VerticalLayoutGroup>() ? GetComponent<VerticalLayoutGroup>() : gameObject.AddComponent<VerticalLayoutGroup>();
        verticle.childAlignment = TextAnchor.UpperCenter;
        verticle.childControlHeight = true;
        verticle.childControlWidth = true;
        verticle.childForceExpandHeight = true;
        verticle.childForceExpandWidth = true;

        var sizeFitter = GetComponent<ContentSizeFitter>() ? GetComponent<ContentSizeFitter>() : gameObject.AddComponent<ContentSizeFitter>();
        sizeFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
        sizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
    }

    public void AddChild()
    {
        // if exists remove placeholder
        if (placeholder)
        {
            if (Application.isPlaying) Destroy(placeholder);
            else DestroyImmediate(placeholder);
        }

        // Every second item we add a new horizontal row
        // starting with the first ;)
        if (itemCounter % 2 == 0)
        {
            var newRowObj = new GameObject("row", typeof(RectTransform), typeof(HorizontalLayoutGroup));
            newRowObj.transform.SetParent(transform, false);
            _currentRow = newRowObj.GetComponent<HorizontalLayoutGroup>();
            _currentRow.childAlignment = TextAnchor.UpperCenter;
            _currentRow.childControlHeight = false;
            _currentRow.childControlWidth = true;
            _currentRow.childForceExpandHeight = true;
            _currentRow.childForceExpandWidth = true;
        }

        // Add a new item child to the current
        // I use some example settings like sprite and color just to show how it works
        // you can ofcourse also simply instantiate a prefab
        var newItem = new GameObject("item", typeof(RectTransform), typeof(Image), typeof(StayQuadratic));
        newItem.transform.SetParent(_currentRow.transform, false);
        var itemImage = newItem.GetComponent<Image>();
        itemImage.color = Color.red;
        itemImage.sprite = sprite;

        newItem.GetComponent<RectTransform>().sizeDelta = Vector2.one * _currentRow.GetComponent<RectTransform>().rect.width / 2;

        itemCounter++;

        // add an invisble filler in case of impair child count
        if (itemCounter % 2 != 0)
        {
            placeholder = new GameObject("placeholder", typeof(RectTransform), typeof(StayQuadratic));
            placeholder.transform.SetParent(_currentRow.transform, false);
            placeholder.GetComponent<RectTransform>().sizeDelta = Vector2.one * _currentRow.GetComponent<RectTransform>().rect.width / 2;
        }
    }

    // Don't mind this further it is just for adding the 
    // AddChild button to the inspector for the example
    [CustomEditor(typeof(GridWith2Columns), true)]
    private class AddchildsEditor : Editor
    {
        public override void OnInspectorGUI()
        {
            DrawDefaultInspector();

            EditorGUILayout.Space();

            if (GUILayout.Button("Add Child"))
            {
                ((GridWith2Columns)target).AddChild();
            }
        }
    }
}

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...