团结:让父母的大小适合孩子的大小

时间:2019-02-06 19:59:49

标签: unity3d parent-child scale

我的Canvas中有一个空白,其中有多个对象作为子对象。随着游戏的进行,更多的孩子被添加到父对象中。我希望父母将其尺寸适合孩子。

我已经阅读了很多有关此主题的内容,但是每次遇到ContentSizeFitter时,不幸的是它对我不起作用,因为它需要一个我没有的布局组,因为子级没有顺序并摆放得很乱。

我正在使用Unity 2018.3.4f1 Personal。

父级未调整大小:

Example

父级(红色:新,绿色:旧):

Example 2

结构:

Canvas
 |- Empty
     |- Child 1
     |- Child 2
     |- Child X

4 个答案:

答案 0 :(得分:1)

我已经写了一小段代码来完成其工作,或者按照我想要的方式来工作,这对我来说已经足够了:

using UnityEngine;

public class SizeFitter : MonoBehaviour {
    public void CheckForChanges() {
        RectTransform children = transform.GetComponentInChildren<RectTransform>();

        float min_x, max_x, min_y, max_y;
        min_x = max_x = transform.localPosition.x;
        min_y = max_y = transform.localPosition.y;

        foreach (RectTransform child in children) {
            Vector2 scale = child.sizeDelta;
            float temp_min_x, temp_max_x, temp_min_y, temp_max_y;

            temp_min_x = child.localPosition.x - (scale.x / 2);
            temp_max_x = child.localPosition.x + (scale.x / 2);
            temp_min_y = child.localPosition.y - (scale.y / 2);
            temp_max_y = child.localPosition.y + (scale.y / 2);

            if (temp_min_x < min_x)
                min_x = temp_min_x;
            if (temp_max_x > max_x)
                max_x = temp_max_x;

            if (temp_min_y < min_y)
                min_y = temp_min_y;
            if (temp_max_y > max_y)
                max_y = temp_max_y;
        }

        GetComponent<RectTransform>().sizeDelta = new Vector2(max_x - min_x, max_y - min_y);
    }
}

答案 1 :(得分:0)

我认为您可以找到最左边的边界和最右边的边界,然后将该值的差添加为父项sizeDelta的{​​{1}}。

这应该确定大小(Y的顶部和底部重复)。

对于该位置,您可以在RectTransform中获得具有最左侧边框和顶部边框的左上角,然后将该向量设置为父级Vector2的{​​{1}}。

请注意,父级的枢轴必须在左上角才能起作用。

此代码仅适用于某些方面,但还不够好。

anchoredPosition

GIF HERE

enter image description here

答案 2 :(得分:0)

类似的事情应该起作用。它循环遍历您选择的对象的所有子对象,然后找到这些对象的渲染器边界,并随其更新最小和最大。在Start()函数的末尾,变量min和max将坐标保存到定义边界的框的角。

public class NewBehaviourScript : MonoBehaviour
{
    void Start ()
    {
        Vector2 min = new Vector2 (0, 0);
        Vector2 max = new Vector2 (0, 0);

        GetParentBounds (gameObject, out min, out max);
        Debug.Log (min);
        Debug.Log (max);

    }

    void GetParentBounds (GameObject GO, out Vector2 pMin, out Vector2 pMax)
    {
        Transform[] ts = GO.GetComponentsInChildren<Transform> ();

        Vector2 parentMin = new Vector2 (float.MaxValue, float.MaxValue);
        Vector2 parentMax = new Vector2 (float.MinValue, float.MinValue);

        foreach (Transform t in ts) {
            Renderer rend = t.GetComponent<Renderer> ();
            if (rend != null) {
                Vector2 min = rend.bounds.min;
                Vector2 max = rend.bounds.max;
                Debug.Log (string.Format ("[{0}, {1}], [{2}, {3}]", min.x, min.y, max.x, max.y));
                parentMin.x = Mathf.Min (parentMin.x, min.x);
                parentMin.y = Mathf.Min (parentMin.y, min.y);
                parentMax.x = Mathf.Max (parentMax.x, max.x);
                parentMax.y = Mathf.Max (parentMax.y, max.y);
            }
        }

        pMin = parentMin;
        pMax = parentMax;
    }
}

答案 3 :(得分:0)

Bounds bound = new Bounds();
for (int i = 0; i < children.Length; ++i)
{
    RectTransform child = children[i];
    if (child != null && child.gameObject.activeSelf)
    {
        Vector2 pos = child.localPosition;
        Vector2 min = pos - child.sizeDelta * child.pivot;
        Vector2 max = min + child.sizeDelta;
        Bounds temp = new Bounds();
        temp.SetMinMax(min, max);
        bound.Encapsulate(temp);
    }
}