C# 为什么TextMeshPro在设置文本后不更新textBounds?
我在hover上实现了一个工具提示系统。为此,我使用textmeshpro文本和图像。此图像应为简单背景,具体取决于文本的长度,而文本的长度总是不同的 如果将鼠标悬停在某个元素上,则会替换textmeshpro文本。背景图像被移动到元素,其大小应根据文本的长度而改变:C# 为什么TextMeshPro在设置文本后不更新textBounds?,c#,unity3d,C#,Unity3d,我在hover上实现了一个工具提示系统。为此,我使用textmeshpro文本和图像。此图像应为简单背景,具体取决于文本的长度,而文本的长度总是不同的 如果将鼠标悬停在某个元素上,则会替换textmeshpro文本。背景图像被移动到元素,其大小应根据文本的长度而改变: // Hover over slot in public void OnPointerEnter(PointerEventData eventData) { if (currentItem != null) {
// Hover over slot in
public void OnPointerEnter(PointerEventData eventData) {
if (currentItem != null) {
Debug.Log("hover over slot item in");
GamePlay.EnableCanvas(GamePlay.GetHoverCanvas());
TextMeshProUGUI txtMeshPro = GamePlay.GetHoverCanvas().GetComponentInChildren<TextMeshProUGUI>();
Debug.Log(currentItem.GetItemDescription(currentItem));
txtMeshPro.text = currentItem.GetItemDescription(currentItem);
var hoverCanvasText = txtMeshPro.GetComponent<RectTransform>();
var hoverCanvasTextBG = GamePlay.GetHoverCanvas().GetComponentInChildren<Image>().GetComponent<RectTransform>();
hoverCanvasText.position = new Vector3(this.GetComponent<RectTransform>().position.x, this.GetComponent<RectTransform>().position.y + 50, 0);
hoverCanvasTextBG.position = new Vector3(this.GetComponent<RectTransform>().position.x, this.GetComponent<RectTransform>().position.y + 50, 0);
hoverCanvasTextBG.sizeDelta = new Vector2(txtMeshPro.textBounds.size.x + 15, txtMeshPro.textBounds.size.y + 15);
// No clue why image is not resized properly on first hover
}
}
//将鼠标悬停在中的插槽上
公共void OnPointerEnter(pointereventdataeventdata){
如果(currentItem!=null){
Log(“将鼠标悬停在中的插槽项上”);
GamePlay.EnableCanvas(GamePlay.GetHoverCanvas());
TextMeshProUGUI txtMeshPro=GamePlay.GetHoverCanvas().getComponentChildren();
Log(currentItem.GetItemDescription(currentItem));
txtMeshPro.text=currentItem.GetItemDescription(currentItem);
var hoverCanvasText=txtmashpro.GetComponent();
var hoverCanvasTextBG=GamePlay.GetHoverCanvas().getcomponentchildren().GetComponent();
hoverCanvasText.position=newvector3(this.GetComponent().position.x,this.GetComponent().position.y+50,0);
hoverCanvasTextBG.position=newvector3(this.GetComponent().position.x,this.GetComponent().position.y+50,0);
hoverCanvasTextBG.sizeDelta=newvector2(txtmashpro.textBounds.size.x+15,txtmashpro.textBounds.size.y+15);
//不知道为什么图像在第一次悬停时没有正确调整大小
}
}
我遇到的一个奇怪的问题是,当我第一次将鼠标悬停在元素上时,图像大小不会改变
替换文本和更改位置始终没有问题。
发行说明:
首先将鼠标悬停在元素A上:图像背景大小根本不会改变
第二个鼠标悬停在元素B上:图像背景大小改变,但元素A的大小正确
第三个鼠标悬停在元素A上:图像背景大小改变,但元素B的大小正确
这怎么可能?我不明白这里发生了什么。代码对位置没有任何问题,为什么相同的逻辑对大小不起作用
注意:我对unity非常陌生,现在在附近修修补补了几天,所以我可能是一个非常简单的问题,但是在研究了几个小时之后,我没有发现任何有用的东西。在设置了
TextMeshProUGUI
的文本后,textBounds
及其大小在下一帧之前不会更新。这是由于Unity推迟了布局重建。在他们的报告中,内容如下:
重建不会立即进行,而是在当前任务结束时进行
帧,就在渲染发生之前。原因是它不是即时的
这将导致布局可能被多次重建
在同一帧中,这对性能不利
我会继续猜测游戏性。GetHoverCanvas()
正在维护一个从未被破坏的对象,因此,除了第一次运行之外,您的代码在所有情况下都能正常工作
可能有几种方法可以解决这个问题,但最简单的方法是在设置文本
和读取文本边界
的大小之间调用。这不是最快的功能,但它应该可以做到这一点
另一种选择是,代替同步函数,启动一个协同程序,将文本设置为一帧,生成下一帧,然后在第二帧执行时读取textbounds
。(这可能会导致大小弹出,看起来可能不太理想)。为了避免强制更新画布,可以使用TextMeshProUGUI.GetPreferredValues()
提前确定当前分配给画布的文本的宽度和高度。它将返回一个向量2
。然后可以使用该Vector2
而不是TextMeshProUGUI.textBounds
或者,如果您需要某个文本的大小而不实际分配它,请使用TextMeshProUGUI.GetPreferredValues(字符串文本)
该方法还有其他重载,用于获取给定宽度或高度的大小约束。您可以使用TMP_Text.ForceMeshUpdate(),而不是刷新所有画布代码>在分配字符串后立即执行。这样可以确保您的文本信息在同一帧中是正确的
如果文本的父级使用布局组,则很有可能您也需要更新这些布局组。您可以使用LayoutRebuilder.forcerebuildlayoutimediate([Layout Group.RectTransform])来实现这一点代码>()
请注意,订单很重要
分配文本
重建布局组
强制网格更新
非常感谢您的详细解释。这对我很有帮助。