首页 > 解决方案 > 无法将父画布适合子文本

问题描述

在我的统一应用程序中,我需要制作带有字符串的小矩形组件。但是,我希望矩形的大小动态对齐其中的文本。这是我的预制中的层次结构:

预制层次结构

根据这篇文章,我只需要在画布上添加一个内容调整器。我这样做并将水平和垂直尺寸都设置为“首选”,但显然宽度仅为 0(我的 Debug.Log 打印出 0)。这是我的代码。我认为这个问题可能与更改渲染模式有关,但这是针对 VR 应用程序的,因此需要保留:

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

public class Script : MonoBehaviour
{
    public static string s_text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";

    public Transform panel;
    public GameObject wordPrefab;

    private float panelWidth;
    private float panelHeight;
  
    // Start is called before the first frame update
    void Start()
    {
        
        panelWidth = panel.GetComponentInParent<Canvas>().GetComponent<RectTransform>().rect.width;
        panelHeight = panel.GetComponentInParent<Canvas>().GetComponent<RectTransform>().rect.height;

        Vector3 nextPosition = new Vector3(-panelWidth / 2, panelHeight / 2, 0);

        foreach (string word in s_text.Split(' '))
        {
            GameObject go = Instantiate(wordPrefab, panel, false);
            go.GetComponentInChildren<Canvas>().renderMode = RenderMode.WorldSpace;
            go.GetComponentInChildren<Text>().text = word;
            go.transform.localPosition = nextPosition;

            float wordWidth = go.GetComponentInChildren<Canvas>().GetComponent<RectTransform>().rect.width;
            Debug.Log(wordWidth); // This is 0 every time when it shouldn't be!

            nextPosition = 0; // I will figure this out once I can access the size of the blocks
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

TL;DR:我需要正确调整父画布的大小,并且由于某种原因,在完全按照链接文章所说的内容并使用内容调整器之后,它的宽度/高度为 0。

标签: c#unity3d

解决方案


我相信这应该回答您的问题 - 如果您对此实施有更多问题,请告诉我。

首先,通过调整大小删除所有代码。如果使用得当,Unity 的组件 UI 系统非常强大。几乎任何你想用动态 UI 实现的东西都可以只使用组件来完成。

首先,保存文本的容器应该附有aHorizontal Layout Group或 a 。Vertical Layout Group关闭Control Child Size-之外的所有切换框Height。将此容器的宽度设置为您想要的任何宽度,文本将填充为此大小。

除了布局组(您可以选择其中任何一个,但由于您的文本是垂直的,您可以使用垂直布局组),您将需要一个Content Size Fitter带有Horizontal Fitset toUnconstrainedVertical Fitset to 的Preferred Size

它应该看起来像...... 示例容器

现在转到文本组件,您可以使用一个Unity.UI.Text组件或一个TMPro.TMP_Text组件,任何一个都可以。在这个例子中,我使用的是 vanilla Unity.UI.Text。只需在文本字段中输入您想要的任何消息,您的父容器就会调整为文本字段的大小。如果您经常动态设置此文本,您可能需要强制 Unity 重建父对象的布局组以重新缩放。

一个示例片段可能看起来像......

using UnityEngine.UI;

// the text object that is resizable
[SerializeField] private Text dynamicText = null;

// the parent container that holds the text
[SerializeField] private RectTransform dynamicTextParent = null;

public void UpdateTextField(string txt)
{
    // assign the new text info
    dynamicText.text = txt;
    
    // force Unity to recalculate the UI hierarchy of this object recursively down its child nodes
    LayoutRebuilder.ForceRebuildLayoutImmediate(dynamicTextParent);
}

在此示例中,您需要在检查器中分配dynamicTextParentdynamicText。您也有可能不需要强制重建 UI 层次结构,因此无需先进行测试。如果遇到问题,请LayoutRebuilder在分配新文本字段的行下方添加。


推荐阅读