我有一個由影像元素和影像中的文本元素組成的預制件。根據文本的長度,預制件會變得更寬或更高。在腳本中,我需要在使用 Instantiate(prefab) 之前更改文本并獲取預制件的新尺寸(高度、寬度)。我的問題是我總是得到一個 0 的大小,或者原始預制的大小,沒有文本修改。我的腳本看起來像這樣:
prefab.GetComponent<Text>().text = myNewText; //insert a long text, supposed to make the prefab wider
float newSize = prefab.GetComponent<Image>().preferredWidth // always getting 0 or the original width of the prefab
// do some things with newSize
Instantiate(prefab);
PS:我的預制件中沒有碰撞器或網格渲染器。
我也試過.GetComponent<RectTransform>().sizeDeltaor.GetComponent<RectTransform>().rect.size.y但我總是得到 0 或原始預制件的大小,沒有更長的文本。
uj5u.com熱心網友回復:
問題是您必須等到 UI 完成重繪 ,以便所有布局組等都是最新的。
默認
畫布在一幀結束時執行其布局和內容生成計算,就在渲染之前,以確保它基于該幀期間可能發生的所有最新更改。
如果您不想等待一幀,您需要使用的是Canvas.ForceUpdateCanvases
var newInstance = Instantiate(prefab);
newInstance.GetComponent<Text>().text = myNewText;
Canvas.ForceUpdateCanvases();
Debug.Log(newInstance.GetComponent<Text>().preferredWidth);
當然,這可能會很昂貴,但這取決于您擁有的 Canvas 的復雜性和數量。
如果您想等待一幀,則需要使用協程并執行
StartCoroutine(SpawnRoutine());
...
private IEnuemrator SpawnRoutine()
{
var newInstance = Instantiate(prefab);
newInstance.GetComponent<Text>().text = myNewText;
yield return new WaitForEndOfFrame();
Debug.Log(newInstance.GetComponent<Text>().preferredWidth);
}
uj5u.com熱心網友回復:
我對此的解決方案是:實體化預制件,在場景中將其設定為非活動狀態,獲取大小,根據需要進行修改,然后再次將其設定為活動狀態。它應該看起來像這樣
Gameobject newPrefab = Instantiate(prefab);
newPrefab.SetActive(false);
float newSize = newPrefab.GetComponent<Image>().preferredWidth;
DoStuff();
newPrefab.SetActive(true);
尚未對此進行測驗,但我認為這就是為什么您在實體化之前沒有獲得寬度
uj5u.com熱心網友回復:
多虧了幫手才弄明白。如果它對某人有用,這就是我所做的更改:
Instantiate(prefab);
prefab.GetComponent<Text>().text = myNewText; //edit some properties
prefab.SetActive(false); // set inactive in the same frame so that we can't see it
StartCoroutine(foo()); //start this coroutine with a WaitForEndOfFrame() and then I can get updated properties
prefab.SetActive(true);
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/449576.html
