简体   繁体   English

如何在Unity3d中仅将两个对象设置为水平组布局?

[英]How to set only two objects to come inside a Horizontal Group Layout in Unity3d?

What I am trying to achieve is similar to GridLayout technique. 我要实现的目标类似于GridLayout技术。 In Grid Layout there is option for constraint-fixed column count, there I set the value to 2. 在“网格布局”中,有一个用于约束固定列数的选项,我将该值设置为2。

The problem with grid layout is that when we set the cell size to a specific value after that the cell size will not expand itself to all other screen sizes. 网格布局的问题在于,当我们将像元大小设置为特定值之后,该像元大小将不会扩展为所有其他屏幕尺寸。 So trying with manually set HorizontalGroup Layout with only two columns. 因此,尝试仅用两列手动设置Horizo​​ntalGroup布局。 The problem lies is when I need to instantiate many items. 问题在于,当我需要实例化许多项目时。 It should come in the order 1,2 items in row one and 3,4 items in row two and so on. 它应该在第一行中的顺序为1,2,在第二行中的顺序为3,4。依此类推。 The one I tried with Gridview is shown in the Link 我在Gridview中尝试过的一个显示在链接中

I did this using a combintation of HorizontalLayoutGroup , VerticalLayoutGroup and a simple StayQuadratic I wrote to keep the items quadratic by their width. 我通过使用HorizontalLayoutGroupVerticalLayoutGroup和一个简单的StayQuadratic的组合来做到这一点,我编写了这个项目以使它们的宽度保持二次方。

public class StayQuadratic : MonoBehaviour
{
    private RectTransform rectTransform;

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

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

Ofcourse it might be enough to set this size only once since you won't change the screen size dynamically in a build. 当然,仅设置一次此大小就足够了,因为您不会在构建中动态更改屏幕大小。

  • The root object needs a VerticalLayoutGroup width 根对象需要VerticalLayoutGroup宽度

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

    and a ContentSizeFitter (just for expanding the background at the bottom or in case you want to use it for scroll) ContentSizeFitter (仅用于扩展底部的背景,或者用于滚动时)

  • It will attach rows. 它将附加行。 A row needs a HorizontalLayoutGroup with 行需要一个HorizontalLayoutGroup

    • childControlHeight = false; childControlHeight = false; (The height will be controlled by the StayQuadratic ) (高度将由StayQuadratic控制)
    • childControlWidth = true; childControlWidth = true;
    • childForceExpandHeight = true; childForceExpandHeight = true;
    • childForceExpandWidth = true; childForceExpandWidth = true;

I made following script to set it up. 我制作了以下脚本进行设置。 For this example I just generate all objects and items but ofcourse you could as well use Prefabs with the same settings. 对于此示例,我只生成所有对象和项目,但是您当然也可以使用具有相同设置的预制件。

[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();
            }
        }
    }
}

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM