Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使自定义Unity LayoutGroup扩展以适应内容_C#_Unity3d_Unity3d 2dtools_Unity3d Ui - Fatal编程技术网

C# 如何使自定义Unity LayoutGroup扩展以适应内容

C# 如何使自定义Unity LayoutGroup扩展以适应内容,c#,unity3d,unity3d-2dtools,unity3d-ui,C#,Unity3d,Unity3d 2dtools,Unity3d Ui,我正在尝试使用一个自定义FlowLayoutGroup,如的答案(也是up on)中所述,它需要垂直调整大小以包含其子项 我的设置如下所示: ScrollableRect 带有VerticalLayoutGroup组件(父scrollrect的内容)的面板,该面板应垂直调整大小以适合子级: 带有FlowLayoutGroup的面板,该面板应垂直调整大小以适合子级 带有FlowLayoutGroup(2)的面板也必须调整大小 等等 我向FlowLayoutGroup添加了一个内容大小调

我正在尝试使用一个自定义FlowLayoutGroup,如的答案(也是up on)中所述,它需要垂直调整大小以包含其子项

我的设置如下所示:

  • ScrollableRect
    • 带有VerticalLayoutGroup组件(父scrollrect的内容)的面板,该面板应垂直调整大小以适合子级:
      • 带有FlowLayoutGroup的面板,该面板应垂直调整大小以适合子级
      • 带有FlowLayoutGroup(2)的面板也必须调整大小
      • 等等
我向FlowLayoutGroup添加了一个内容大小调整器,调整了垂直组的布局子大小控件,但没有成功

用户可以在应用程序运行时添加和删除组的子级,我希望UI做出响应,这样就不可能预先设置所有内容的高度

我还查看了unity源代码,试图找出如何将其写入组件中。这看起来是最好的选择,但这需要我相当长的时间,因为我对Unity和C#还不熟悉。希望有人已经解决了类似的问题

除了LayoutGroup的缺失行为(调整大小以垂直适应其子女)之外,所有功能均按预期/预期运行


我怎样才能做到这一点呢?

经过一段时间和风滚草徽章,我决定花时间制定解决方案,希望其他人也能从中受益

同样,这是的一个修改版本。谢谢你。该组件现在计算自己的首选大小

主要变化:

  • 我很严厉地把它剥了回去:
    • 所有水平覆盖都是空的,我只需要水平环绕行为
    • 从GridLayout类中删除了一些明显的遗留变量
  • 逻辑计算子位置和行数,首选的高度是在它自己的方法
  • 子位置存储在Vector2数组中,以将计算与子设置分开
  • 这解决了整个组件高度不调整的问题,它也会立即响应原始脚本,因为设置子对象的方式,然后访问该脚本。脚本花了两个“周期”来识别子对象的尺寸

    这适合我所有的需要,我想它可以相当容易地重新处理垂直包装太

    using UnityEngine;
    using UnityEngine.UI;
    
    [AddComponentMenu("Layout/Wrap Layout Group", 153)]
    public class WrapLayoutGroup : LayoutGroup
    {
        [SerializeField] protected Vector2 m_Spacing = Vector2.zero;
        public Vector2 spacing { get { return m_Spacing; } set { SetProperty(ref m_Spacing, value); } }
    
        [SerializeField] protected bool m_Horizontal = true;
        public bool horizontal { get { return m_Horizontal; } set { SetProperty(ref m_Horizontal, value); } }
    
        private float availableWidth { get { return rectTransform.rect.width - padding.horizontal + spacing.x; } }
    
        private const float MIN_HEIGHT = 80;
    
        private int preferredRows = 1;
        private float calculatedHeight = MIN_HEIGHT;
    
        private Vector2[] childPositions = new Vector2[0];
    
        protected WrapLayoutGroup()
        { }
    
    #if UNITY_EDITOR
        protected override void OnValidate()
        {
            base.OnValidate();
        }
    
    #endif
    
        public override void CalculateLayoutInputVertical()
        {
            calculatePositionsAndRequiredSize();
            SetLayoutInputForAxis(calculatedHeight, calculatedHeight, -1, 1);
        }
    
        public override void SetLayoutHorizontal() { }
    
        public override void SetLayoutVertical()
        {
            SetChildren();
        }
    
        private void SetChildren()
        {
            for (int i = 0; i < rectChildren.Count; i++)
            {
                RectTransform child = rectChildren[i];
                SetChildAlongAxis(child, 0, childPositions[i].x, LayoutUtility.GetPreferredWidth(child));
                SetChildAlongAxis(child, 1, childPositions[i].y, LayoutUtility.GetPreferredHeight(child));
            }
        }
    
        private void calculatePositionsAndRequiredSize()
        {
            childPositions = new Vector2[rectChildren.Count];
    
            Vector2 startOffset = new Vector2(
                GetStartOffset(0, 0),
                GetStartOffset(1, 0)
            );
    
            Vector2 currentOffset = new Vector2(
                startOffset.x,
                startOffset.y
            );
    
            float childHeight = 0;
            float childWidth = 0;
            float maxChildHeightInRow = 0;
    
            int currentRow = 1;
    
            for (int i = 0; i < rectChildren.Count; i++)
            {
                childHeight = LayoutUtility.GetPreferredHeight(rectChildren[i]);
                childWidth = LayoutUtility.GetPreferredWidth(rectChildren[i]);
    
                //check for new row start
                if (currentOffset.x + spacing.x + childWidth > availableWidth && i != 0)
                {
                    currentOffset.x = startOffset.x;
                    currentOffset.y += maxChildHeightInRow + spacing.y;
                    currentRow++;
                    maxChildHeightInRow = 0;
                }
    
                childPositions[i] = new Vector2(
                    currentOffset.x,
                    currentOffset.y
                );
    
                //update offset
                maxChildHeightInRow = Mathf.Max(maxChildHeightInRow, childHeight);
                currentOffset.x += childWidth + spacing.x;
    
            }
    
            //update groups preferred dimensions
            preferredRows = currentRow;
            calculatedHeight = currentOffset.y + maxChildHeightInRow + padding.vertical - spacing.y;
        }
    }
    
    
    使用UnityEngine;
    使用UnityEngine.UI;
    [添加组件菜单(“布局/换行布局组”,153)]
    公共类播放组:LayoutGroup
    {
    [SerializeField]受保护向量2 m_间距=向量2.0;
    公共向量2间距{get{return m_spacing;}set{SetProperty(ref m_spacing,value);}
    [SerializeField]受保护的布尔m_水平=真;
    公共bool horizontal{get{return m_horizontal;}set{SetProperty(ref m_horizontal,value);}
    私有浮点可用宽度{get{return rectTransform.rect.width-padding.horizontal+spacing.x;}
    私人施工浮动最小高度=80;
    private int preferredRows=1;
    专用浮点数计算高度=最小高度;
    私有向量2[]子位置=新向量2[0];
    受保护的播放组()
    { }
    #如果统一编辑器
    受保护的重写void OnValidate()
    {
    base.OnValidate();
    }
    #恩迪夫
    公共覆盖无效CalculateLayoutInputVertical()
    {
    计算位置和所需大小();
    SetLayoutPutforaxis(计算高度,计算高度,-1,1);
    }
    公共重写void setLayoutAuthorizontal(){}
    公共覆盖无效SetLayoutVertical()
    {
    SetChildren();
    }
    私人子女
    {
    for(int i=0;iavailableWidth&&i!=0)
    {
    currentOffset.x=startOffset.x;
    currentOffset.y+=maxChildHeightInRow+spacing.y;
    currentRow++;
    maxChildHeightInRow=0;
    }
    childPositions[i]=新向量2(
    currentOffset.x,
    电流偏移量
    );
    //更新偏移量
    maxChildHeightInRow=数学最大值(maxChildHeightInRow,childHeight);
    currentOffset.x+=childWidth+spacing.x;
    }
    //更新组首选维度
    preferredRows=currentRow;
    计算高度=currentOffset.y+maxChildHeightInRow+padding.vertical-spacing.y;
    }
    }