Unity RectTransform.sizeDelta не изменяет размер

#c# #unity3d #graphics #resize

#c# #unity3d #графика #изменение размера

Вопрос:

Я пытаюсь изменить размер игрового объекта, который имеет TextMeshPro - Text (UI) компонент, соответствующий его родительскому. Вот код.

 static public Cube CreateCube(Transform parent, Vector2 anchors, Vector2 position)
{
    Cube c = Instantiate(cubePrefab); // prefab has Cube component

    var tr = (RectTransform)c.transform;
    tr.SetParent(parent); // canvas or other 2d object
    tr.anchorMin = tr.anchorMax = anchors;
    tr.anchoredPosition = position;

    var textObj = new GameObject("Text");

    var textTr = textObj.AddComponent<RectTransform>();
    textTr.SetParent(tr);
    textTr.anchorMin = textTr.anchorMax = Vector2.one / 2; // anchors at the center of the parent
    textTr.anchoredPosition = Vector2.zero;

    // tr.sizeDelta is Vector2(60, 60) from prefab;
    print(new Vector2(tr.sizeDelta.x, tr.sizeDelta.y * 2 / 3)); // Vector2(60, 40)
    textTr.sizeDelta = new Vector2(tr.sizeDelta.x, tr.sizeDelta.y * 2 / 3); // width is the same as parent's width
    // height is two thirds of parent's height
    print(textTr.sizeDelta); // also Vector2(60, 40)

    var text = textObj.AddComponent<TextMeshProUGUI>();
    text.text = "Test";
    text.fontSize = 14;
    text.alignment = TextAlignmentOptions.Center;

    return c;
}
 

Второй print показывает, что sizeDelta он был установлен, но в инспекторе и на сцене размер равен (200, 50), как без textTr.sizeDelta = ... строки.

Но если я добавлю

 private void Start()
{
    ((RectTransform)transform.GetChild(0)).sizeDelta = new Vector2(60, 40);
}
 

в Cube классе это будет работать. Почему это не работает, когда я создаю текст?

Иерархия объектов:

-> Некоторый 2d-объект

—> Объект с Cube компонентом

——> Текстовый объект

введите описание изображения здесь

Комментарии:

1. Что-нибудь отменяет ваше изменение, например, a ContentSizeFittet и т. HorizontalLayoutGroup Д.?

Ответ №1:

Иерархия холста вычисляется не сразу, когда вы создаете и добавляете в нее новые объекты, и это часто может привести к некоторым непредсказуемым результатам. Рекомендуемый обходной путь — подождать не менее 1 кадра после создания объекта и только после этого применить изменения для свойств, таких как sizeDelta. Вы можете сделать это с помощью сопрограммы и пропустить 1 кадр yield return null . В качестве альтернативы для вашего конкретного варианта использования вы можете попробовать использовать RectTransform.SetSizeWithCurrentAnchors вместо прямой настройки sizeDelta, я бы сказал, сначала попробуйте этот подход.

     textRt.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal,  60);
    textRt.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical,  40);
 

Комментарии:

1. Да. Я думал об этом, и сопрограмма действительно помогла. Но мне нужен метод, возвращающий некоторое значение, но я читал, что сопрограмма не может этого сделать. Поэтому я использовал Start для этого метод. P.s.: SetSizeWithCurrentAnchors не работает.