查找 Unity UI 元素的世界空间坐标
Posted
技术标签:
【中文标题】查找 Unity UI 元素的世界空间坐标【英文标题】:Finding World Space Coordinates of a Unity UI Element 【发布时间】:2015-05-07 14:12:48 【问题描述】:因此,根据 Unity 文档,RectTransform.anchoredPosition 将返回 UI 元素的屏幕坐标,如果锚点在 RectTransform 的轴心点处接触。但是,如果它们是分开的(在我的情况下位于矩形的角落),它们将为您提供锚点相对于枢轴点的位置。除非您想通过多种分辨率保持 UI 对象的适当尺寸并同时基于该位置定位不同的对象,否则这非常棒。
让我们分解一下。我有object1和object2。 object1 位于 (322.5, -600) 处,并且当锚点在对象的中心(枢轴)相遇时,anchoredPosition 会返回该位置,并且 object2 的位置也很好。另一方面,一旦我将锚点放置在 object1 的 4 个角上,anchoredPosition 就会返回 (45.6, -21)。那只是没有好处。我什至尝试过使用Transform.position
,然后使用Camera.WorldToScreenPoint()
,但这对我实现目标的作用同样重要。
我希望您能帮助我找到一种方法来获取该对象的实际屏幕坐标。如果有人对此主题有任何见解,将不胜感激。
注意:我已经尝试使用 RectTranfrom.rect.center 并且它返回 (0, 0)
我还研究了RectTransformUtility,这些辅助函数已经完成了所有的蹲下动作。
【问题讨论】:
【参考方案1】:anchoredPosition 返回“此 RectTransform 的枢轴相对于锚参考点的位置。”它与屏幕坐标或世界空间无关。
如果您在 Unity 中查找 UI 元素的屏幕坐标,您可以使用 rectTransform.TransformPoint
或 rectTransform.GetWorldCorners
来获取您在世界空间中需要的任何 Vector3
s。无论您决定使用哪个,都可以将它们传递给Camera.WorldToScreenPoint()
【讨论】:
有什么理由使用rectTransform.TransformPoint
会比transform.position
更好用吗?
@user1311199 我推荐了 TransformPoint,因为它的返回位置受比例影响,并且您提到您正在使用多种分辨率,所以我假设正在进行一些缩放。如果你不担心这个,transform.position 仍然可以工作。只要你能得到实际的世界位置,Camera.WorldToScreenPoint() 就可以工作;在最新版本的 Unity 中,我没有遇到任何错误。【参考方案2】:
如果您遇到困难并且需要将自己的转换从视图空间滚动到世界空间,这里将简要介绍如何查找 UI 元素的世界空间坐标。
如果说您需要的不仅仅是 rectTransform.TransformPoint 或想知道它是如何工作的,这可能会有所帮助。
好的,所以您想从 [-1, 1] 范围内的规范化 UI 坐标进行转换,然后将它们反投影回世界空间坐标。
要做到这一点,您可以使用 Camera.main.ScreenToWorldPoint 或 Camera.main.ViewportToWorldPoint 之类的东西,或者如果您缺乏经验,甚至可以使用 rectTransform.position。
这是仅使用相机的投影矩阵的方法。
/// <summary>
/// Get the world position of an anchor/normalised device coordinate in the range [-1, 1]
/// </summary>
private Vector3 GetAnchor(Vector2 ndcSpace)
Vector3 worldPosition;
Vector4 viewSpace = new Vector4(ndcSpace.x, ndcSpace.y, 1.0f, 1.0f);
// Transform to projection coordinate.
Vector4 projectionToWorld = (_mainCamera.projectionMatrix.inverse * viewSpace);
// Perspective divide.
projectionToWorld /= projectionToWorld.w;
// Z-component is backwards in Unity.
projectionToWorld.z = -projectionToWorld.z;
// Transform from camera space to world space.
worldPosition = _mainCamera.transform.position + _mainCamera.transform.TransformVector(projectionToWorld);
return worldPosition;
【讨论】:
【参考方案3】:我发现您可以将坐标乘以相机尺寸的 2 倍,然后除以屏幕高度。
我在全高清屏幕 (1920 x 1080) 上的 (0, 1080) 处放置了一个面板,相机尺寸为 7。所以世界空间中的 Y 坐标将为 1080 * 7 * 2 / 1080 = 14 -> (0, 14).
【讨论】:
【参考方案4】:ScreenToWorldPoint 将画布位置转换为世界位置:
Camera.main.ScreenToWorldPoint(transform.position)
【讨论】:
以上是关于查找 Unity UI 元素的世界空间坐标的主要内容,如果未能解决你的问题,请参考以下文章