【问题标题】:Can't fit parent Canvas to child Text无法将父画布适合子文本
【发布时间】:2021-08-12 21:10:39
【问题描述】:

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

根据this article,我只需要在画布上添加一个内容调整器。我这样做了,并将水平和垂直尺寸都设置为“首选”,但显然宽度只是 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。

【问题讨论】:

  • 同时向画布添加水平或垂直布局组。您无需尝试动态缩放代码中的任何内容。仅使用 UI 组件就可以完全实现。如果您需要,我可以发布更具体的答案。
  • 可以吗?听起来很完美
  • 为了清楚起见,您是否要将整个画布重新缩放为文本对象?或者你只是想要一些父对象重新缩放到文本对象。您是否有特定原因希望重新调整画布本身的比例?
  • 我只需要一些父对象来缩放那么多,不管它是否是画布。我添加了一个水平布局组并使用了设置,但我无法让它适合文本。要么是固定宽度,要么是 0
  • 您希望文本为固定大小吗?还是希望对象缩放到其中的文本量?并且宽度或高度应该是固定大小。您希望它按高度增长还是按宽度增长?

标签: c# unity3d


【解决方案1】:

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

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

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

除了一个布局组(您可以选择其中一个,但由于您的文本是垂直的,您可以使用垂直布局组),您将需要一个 Content Size Fitter 并将 Horizontal Fit 设置为 Unconstrained 和 @ 987654333@ 设置为Preferred Size

它应该看起来像...

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

这样的示例 sn-p 可能看起来像...

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

【讨论】:

  • 这是完美的。最后一行LayoutRebuilder.ForceRebuildLayoutImmediate(dynamicTextParent); 刚刚解决了我所有的问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-24
  • 1970-01-01
相关资源
最近更新 更多