U3D对GridLayoutGourp的重写实现适配

Posted 有间猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了U3D对GridLayoutGourp的重写实现适配相关的知识,希望对你有一定的参考价值。

Grid对最后不能铺满的一行不能根据设置的Alignment进行对齐。故此对 GridLayoutGourp进行重写,实现最后一行按照Alignment进行对齐

原因是在做一个项目的时候,策划要求的展示效果与grid的实现效果不一致
Grid对最后不能铺满的一行不能根据设置的Alignment进行对齐,又不懒得自己去算。故此对GridLayoutGourp进行重写,实现最后一行按照Alignment进行对齐

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class AdapGridLayoutGroup : GridLayoutGroup

    public override void CalculateLayoutInputHorizontal()
    
        base.CalculateLayoutInputHorizontal();
    

    public override void CalculateLayoutInputVertical()
    
        base.CalculateLayoutInputVertical();
    

    public override void SetLayoutHorizontal()
    
        SetCellsAlongAxis(0);
    

    public override void SetLayoutVertical()
    
        SetCellsAlongAxis(1);
    

    private void SetCellsAlongAxis(int axis)
    
        // Normally a Layout Controller should only set horizontal values when invoked for the horizontal axis
        // and only vertical values when invoked for the vertical axis.
        // However, in this case we set both the horizontal and vertical position when invoked for the vertical axis.
        // Since we only set the horizontal position and not the size, it shouldn\'t affect children\'s layout,
        // and thus shouldn\'t break the rule that all horizontal layout must be calculated before all vertical layout.
        var rectChildrenCount = rectChildren.Count;
        if (axis == 0)
        
            // Only set the sizes when invoked for horizontal axis, not the positions.

            for (int i = 0; i < rectChildrenCount; i++)
            
                RectTransform rect = rectChildren[i];

                m_Tracker.Add(this, rect,
                    DrivenTransformProperties.Anchors |
                    DrivenTransformProperties.AnchoredPosition |
                    DrivenTransformProperties.SizeDelta);

                rect.anchorMin = Vector2.up;
                rect.anchorMax = Vector2.up;
                rect.sizeDelta = cellSize;
            
            return;
        

        float width = rectTransform.rect.size.x;
        float height = rectTransform.rect.size.y;

        int cellCountX = 1;
        int cellCountY = 1;
        if (m_Constraint == Constraint.FixedColumnCount)
        
            cellCountX = m_ConstraintCount;

            if (rectChildrenCount > cellCountX)
                cellCountY = rectChildrenCount / cellCountX + (rectChildrenCount % cellCountX > 0 ? 1 : 0);
        
        else if (m_Constraint == Constraint.FixedRowCount)
        
            cellCountY = m_ConstraintCount;

            if (rectChildrenCount > cellCountY)
                cellCountX = rectChildrenCount / cellCountY + (rectChildrenCount % cellCountY > 0 ? 1 : 0);
        
        else
        
            if (cellSize.x + spacing.x <= 0)
                cellCountX = int.MaxValue;
            else
                cellCountX = Mathf.Max(1, Mathf.FloorToInt((width - padding.horizontal + spacing.x + 0.001f) / (cellSize.x + spacing.x)));

            if (cellSize.y + spacing.y <= 0)
                cellCountY = int.MaxValue;
            else
                cellCountY = Mathf.Max(1, Mathf.FloorToInt((height - padding.vertical + spacing.y + 0.001f) / (cellSize.y + spacing.y)));
        

        int cornerX = (int)startCorner % 2;
        int cornerY = (int)startCorner / 2;

        int cellsPerMainAxis, actualCellCountX, actualCellCountY;
        if (startAxis == Axis.Horizontal)
        
            cellsPerMainAxis = cellCountX;
            actualCellCountX = Mathf.Clamp(cellCountX, 1, rectChildrenCount);
            actualCellCountY = Mathf.Clamp(cellCountY, 1, Mathf.CeilToInt(rectChildrenCount / (float)cellsPerMainAxis));
        
        else
        
            cellsPerMainAxis = cellCountY;
            actualCellCountY = Mathf.Clamp(cellCountY, 1, rectChildrenCount);
            actualCellCountX = Mathf.Clamp(cellCountX, 1, Mathf.CeilToInt(rectChildrenCount / (float)cellsPerMainAxis));
        

        Vector2 requiredSpace = new Vector2(
            actualCellCountX * cellSize.x + (actualCellCountX - 1) * spacing.x,
            actualCellCountY * cellSize.y + (actualCellCountY - 1) * spacing.y
        );
        Vector2 startOffset = new Vector2(
            GetStartOffset(0, requiredSpace.x),
            GetStartOffset(1, requiredSpace.y)
        );

        int endRowCount = rectChildrenCount % cellsPerMainAxis;
        int endRowStart = rectChildrenCount - endRowCount;

        for (int i = 0; i < rectChildrenCount; i++)
        
            // 在最后一行开始的时候更新开始偏移坐标
            if(i == endRowStart)
            
                if (startAxis == Axis.Horizontal)
                
                    actualCellCountX = Mathf.Clamp(cellCountX, 1, endRowCount );
                    actualCellCountY = Mathf.Clamp(cellCountY, 1, Mathf.CeilToInt(rectChildrenCount / (float)cellsPerMainAxis));
                
                else
                
                    actualCellCountY = Mathf.Clamp(cellCountY, 1, endRowCount);
                    actualCellCountX = Mathf.Clamp(cellCountX, 1, Mathf.CeilToInt(rectChildrenCount / (float)cellsPerMainAxis));
                

                requiredSpace = new Vector2(
                    actualCellCountX * cellSize.x + (actualCellCountX - 1) * spacing.x,
                    actualCellCountY * cellSize.y + (actualCellCountY - 1) * spacing.y
                );
                startOffset = new Vector2(
                    GetStartOffset(0, requiredSpace.x),
                    GetStartOffset(1, requiredSpace.y)
                );
            

            int positionX;
            int positionY;
            if (startAxis == Axis.Horizontal)
            
                positionX = i % cellsPerMainAxis;
                positionY = i / cellsPerMainAxis;
            
            else
            
                positionX = i / cellsPerMainAxis;
                positionY = i % cellsPerMainAxis;
            

            if (cornerX == 1)
                positionX = actualCellCountX - 1 - positionX;
            if (cornerY == 1)
                positionY = actualCellCountY - 1 - positionY;

            SetChildAlongAxis(rectChildren[i], 0, startOffset.x + (cellSize[0] + spacing[0]) * positionX, cellSize[0]);
            SetChildAlongAxis(rectChildren[i], 1, startOffset.y + (cellSize[1] + spacing[1]) * positionY, cellSize[1]);
        
    

暂未实现GridLayoutGroup根据内容进行ContentFilterSize的功能

PTA基础编程题目集——爬动的蠕虫

原题链接https://pintia.cn/problem-sets/14/problems/797

       这题一开始考虑时犯了一些错误,一开始是这样考虑的,按题目的意思,每2分钟蠕虫爬行的距离是(U-D)寸。那么平均每分钟爬行的距离是(U-D+1)/2寸。然后对照样例数据N=12,U=3,D=1算出需要8分钟爬完,当然这个结果是错的。调整一下思路,假设时间为t,爬行距离为s。当t=0时,s=0;当t=1时,s=U;当t=2时,s=U-D;当t=3时,s=U-D+U;当t=4时,S=U-D+U-D;.......所以,可以根据s和t的关系得出以t为自变量关于s的函数关系f(t),这是个分段函数,当t%2==0时,f(t)=(t/2)(U-D);当t%2==1时,f(t)=f(t-1)+U。这里有个递归的形式,因为当t%2==1时,t-1肯定是偶数,所以可以进一步将t-1代入f(t)=(t/2)(U-D)得出当t为奇数时f(t)=((t-1)/2)(U-D)+U。

有了函数关系,就可以写代码了,代码如下:

 1 #include <stdio.h>
 2 int main(void){
 3     int t = 0, s, n, u, d;      //t表示时间,s表示爬行距离
 4     scanf("%d %d %d", &n, &u, &d);
 5     while(1){
 6         if(t % 2 == 0){
 7             s = (t / 2)*(u - d);
 8         }else{
 9             s = ((t - 1) / 2) * (u - d) + u;
10         }
11         if(s >= n){          //当爬行距离大于指定距离,跳出循环
12             break;
13         }
14         t++;
15     }
16     printf("%d
", t);       //打印所花费的时间
17     return 0;
18 }    

如果直接采用递归形式,代码如下:

 1 #include <stdio.h>
 2 int distance(const int t, const int u, const int d);
 3 int main(void){
 4     int t, s, n, u, d;
 5     scanf("%d %d %d", &n, &u, &d);
 6     for(t = 0; ; t++){
 7         s = distance(t, u, d);
 8         if(s >= n){
 9             break;
10         }
11     }
12     printf("%d
", t);
13     return 0;
14 }
15 
16 //计算指定时间点爬行的距离
17 int distance(const int t, const int u, const int d){
18     if(t % 2 == 0){
19         return (t / 2)*(u - d);
20     }else{
21         return distance(t - 1, u, d) + u;
22     }
23 }

 

以上是关于U3D对GridLayoutGourp的重写实现适配的主要内容,如果未能解决你的问题,请参考以下文章

普适计算的六大必备条件

winForm窗体嵌入U3d

JavaScript如何实现鼠标悬浮适表格对应行变色?

[小巩u3d] 关于Raycast对BoxCollider和BoxCollider2d的碰撞监测规则

U3D 文档 GPU INSTANCING

U3D面试汇总!!!