[英]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. 因此,尝试仅用两列手动设置HorizontalGroup布局。 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. 我通过使用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;
}
}
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
宽度
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
与
StayQuadratic
) (高度将由StayQuadratic
控制) 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.