Unity 4.6:运行时添加的按钮实例未按参考分辨率缩放?

10

(使用Unity 4.6.0b20)

我遇到了一个问题,当通过编辑器添加预制按钮时,它的大小可以正确工作,但是当通过脚本添加时似乎会忽略“参考分辨率”。

这个场景使用的是Canvas组件,参考分辨率为1280x720,并启用了“宽度或高度匹配”选项。Canvas上有一个Panel垂直布局组,用于管理按钮。每个按钮都有首选宽度/高度,并作为预制保存以便在运行时从资源中创建新实例。

enter image description here

在编辑器中,我可以将该预制拖动到场景中以向面板添加实例,它们会很好地堆叠和缩放:

enter image description here

但是,如果我通过脚本添加预制的新实例到Panel,则它们的大小会不正确。根据尺寸来看,我猜测102像素大小没有按比例缩放参考分辨率:

enter image description here

脚本代码通过GameObject.Instantiate()创建实例,并通过设置transform.parent将其添加到Panel中:

GameObject uiInstance = (GameObject)GameObject.Instantiate(Resources.Load<GameObject>(assetPath));
uiInstance.transform.parent = unitButtonsPanel.transform;

我认为在将按钮添加到面板时,除了设置父级之外,可能还需要完成更多工作,或者这是测试版存在的错误...

有什么建议吗?


1
我不确定我理解你的意思,“当它被导出时”? - mwk
非常敏锐 - 你是对的。默认情况下,当你实例化时,rectTransform 中的缩放默认为零。这是Unity一个惊人的愚蠢之举 - 但这就是Unity。 - Fattie
3个回答

27

使用 transform.SetParent 方法,将第二个参数传递为 false:

transform.SetParent(transform, false);

通过这种方式,您可以防止世界定位和缩放。 您可以在Unity手册中查找“UICreateFromScripting”以获取更多信息。


更好的答案,谢谢!我希望他们在测试版时有这个手册 :) - mwk
非常好的解决方案 racr -- 太棒了。 - Fattie
终于!谢谢!我浪费了太多时间来解决这个问题。它完美地运行了! - Gabcvit

4
我发现了问题所在——当预制体通过脚本添加时,比例尺的值会被错误地设置;在这个测试中,比例尺被设置为1.186284。
但是如果脚本在添加按钮后立即将比例尺设置为1.0:
GameObject uiInstance = (GameObject)GameObject.Instantiate(Resources.Load<GameObject>(assetPath));
uiInstance.transform.parent = unitButtonsPanel.transform;
// HACK force scale to 1.0
uiInstance.transform.localScale = Vector3.one;

新的按钮实例大小正确。
在我看来,这是Unity的一个bug,因为在编辑器中添加prefab实例会设置比例为1.0,prefab本身的比例也为1.0,所以我看不出为什么从脚本中添加应该有不同的表现。但是我猜测是因为新UI的文档还不够详细 :)

值得一提的是,我刚刚花了一些时间解决类似的错误...请确保所有UI预制体的缩放始终设置为1.0。否则,对齐似乎无法正常工作。 - Tom Florkiewicz
这不是Unity方面的一个很大的问题,而是非常愚蠢的行为。racr0x提供了解决方案,很好。 - Fattie

3
这不是一个错误,而是执行顺序的问题。当使用Unity的新布局组件时,值由布局组件驱动,在进行布局重建调用的帧结束时计算。如果您在脚本中基于新的rectTransform.rect计算(由布局元素驱动)来构建任何东西,您需要等待此计算已执行或通过使用LayoutRebuilder.MarkLayoutForRebuild(transform as RectTransform)自行调用它。

在使用rectTransform的任何内容之前,如缩放、位置等,仍需等待到帧结束时才能进行这些计算。当我开始动态创建UI元素时,这让我困惑了一段时间,因为根据实例化它们的时间,比例可能为零。

您可以在这里阅读有关重建调用和布局计算顺序的更多信息: http://docs.unity3d.com/Manual/UIAutoLayout.html


1
尽管这个信息是正确的,但答案很简单,你必须记得在SetParent中使用", false"参数。 - Fattie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接