如何通过RectTransform组件计算sizeDelta的值?

Number of views 51

最近在编写可自动适配的内容适配器,这是为了满足我自定义的布局需求。所以当锚点改变时,我需要获取RectTransform.sizeDelta值,不过我对这个属性一知半解,也查过Unity的文档了。

The size of this RectTransform relative to the distances between the anchors. If the anchors are together, sizeDelta is the same as size. If the anchors are in each of the four corners of the parent, the sizeDelta is how much bigger or smaller the rectangle is compared to its parent.

看了半天还是不知所云,有人能帮忙解释下么?

2 Answers

这个定义确实有些令人困惑。

sizeDelta基本上可以认为返回的是UI元素的实际矩形与由锚点所组成的矩形之间的差异值。

例如,给定一个300x200的矩形:

锚点位于矩形角落的相同位置:那么sizeDelta 是 (0,0)。
image.png

当矩形宽度的一半的位置设置左或右锚点时:sizeDelta 是 (150,0)。
image.png

所有四个锚点汇聚为同一个点上:sizeDelta 是 (300,200)(即:与矩形大小相同)。
image.png
image.png
正如上面图示看到的,锚点定义的矩形中心位置并不重要,唯一重要的是UI元素的矩形与锚点矩形的宽度和高度之间的差异。

在伪代码中可以表示如下:

sizeDelta.x = UIElementRectangle.width - AnchorsRectangle.width;
sizeDelta.y = UIElementRectangle.height - AnchorsRectangle.height;

如果uirectangle的尺寸大于锚点所围成的矩形尺寸,则sizeDelta为正,如果相反,则sizeDelta为负。

当然可以!RectTransform.sizeDelta 是一个非常有用但有时也容易混淆的属性。让我们详细解释一下。

RectTransform.sizeDelta 的含义

sizeDelta 表示当前 RectTransform 相对于其锚点(anchors)之间的距离的大小。简单来说,它描述了内容区域的大小。

  • 如果锚点在一起sizeDelta 将等于 RectTransform.rect.size,也就是直接等于内容区域的尺寸。
  • 如果锚点分布在四个角落sizeDelta 则表示 RectTransform 相对于其父对象的大小。具体来说,sizeDelta 会告诉你内容区域比父对象大多少或小多少。

如何计算 sizeDelta

假设你有一个 RectTransform 对象,并且你想计算它的 sizeDelta,你可以通过以下步骤来实现:

  1. 获取 RectTransformrect 属性

    Rect rect = myRectTransform.rect;
    
    1. 获取 RectTransformanchoredPositionanchorMaxanchorMin 属性csharp Vector2 anchoredPosition = myRectTransform.anchoredPosition; Vector2 anchorMax = myRectTransform.anchorMax; Vector2 anchorMin = myRectTransform.anchorMin;
  2. 根据锚点的位置计算 sizeDelta: “`csharp Vector2 sizeDelta;

// 如果锚点在四个角落 if (anchorMin.x == 0 && anchorMin.y == 0 && anchorMax.x == 1 && anchorMax.y == 1) { // 计算相对于父对象的大小 sizeDelta = new Vector2( rect.width - myRectTransform.parent.rect.width, rect.height - myRectTransform.parent.rect.height ); } else { // 如果锚点在一起,直接使用 rect.size sizeDelta = rect.size; }


### 示例代码

假设你有一个 `RectTransform` 对象 `myRectTransform`,你可以这样计算 `sizeDelta`:

```csharp
public class SizeDeltaCalculator : MonoBehaviour
{
    public RectTransform myRectTransform;

    void Start()
    {
        CalculateSizeDelta();
    }

    void CalculateSizeDelta()
    {
        Rect rect = myRectTransform.rect;
        Vector2 anchoredPosition = myRectTransform.anchoredPosition;
        Vector2 anchorMax = myRectTransform.anchorMax;
        Vector2 anchorMin = myRectTransform.anchorMin;

        Vector2 sizeDelta;

        // 如果锚点在四个角落
        if (anchorMin.x == 0 && anchorMin.y == 0 && anchorMax.x == 1 && anchorMax.y == 1)
        {
            // 计算相对于父对象的大小
            sizeDelta = new Vector2(
                rect.width - myRectTransform.parent.rect.width,
                rect.height - myRectTransform.parent.rect.height
            );
        }
        else
        {
            // 如果锚点在一起,直接使用 rect.size
            sizeDelta = rect.size;
        }

        Debug.Log("SizeDelta: " + sizeDelta);
    }
}

总结

sizeDelta 的计算取决于锚点的位置。如果你希望内容区域能够根据锚点自动调整大小,那么上述方法可以帮助你正确地计算 sizeDelta。希望这对你有所帮助!