查找 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.TransformPointrectTransform.GetWorldCorners 来获取您在世界空间中需要的任何 Vector3s。无论您决定使用哪个,都可以将它们传递给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 -&gt; (0, 14).

【讨论】:

【参考方案4】:

ScreenToWorldPoint 将画布位置转换为世界位置:

Camera.main.ScreenToWorldPoint(transform.position)

【讨论】:

以上是关于查找 Unity UI 元素的世界空间坐标的主要内容,如果未能解决你的问题,请参考以下文章

unity中UI坐标转3d世界坐标

unity 坐标变化

统一3d。如何获取ui元素的屏幕或世界位置

Unity学习笔记—本地坐标转世界坐标

Unity世界坐标转换屏幕坐标(详解)

Unity从深度缓冲重建世界空间位置