RectTransformUtility.ScreenPointToLocalPointInRectangle
RectTransformUtility.ScreenPointToLocalPointInRectangle 是 Unity 中用于坐标转换的核心方法,主要功能是将 屏幕空间坐标(如鼠标点击位置)转换为 RectTransform 局部空间的坐标。这在处理 UI 交互(如点击按钮、拖动元素)时非常关键。
先说它的缺点
- 函数能够对坐标进行正确的转换,必须保证锚点、轴心、缩放和Canvas渲染模式都设置正确
- 锚点和轴心必须是(0.5,0.5),不然计算的就不对了,其他情况下想得到正确的结果,必须自己再把偏移考虑进去
- 缩放函数已经考虑了,不需要另外计算
- Canvas渲染模式的设置如下:
- Screen Space - Overlay:cam 必须为 null。
- Screen Space - Camera 或 World Space:cam 需传入渲染 Canvas 的相机(通常是 Camera.main)。
下面给出几个图片
-
第一张是正确的设置
-
第二张和第三张是不正确的设置
🚝
RectTransformUtility.ScreenPointToLocalPointInRectangle
是 Unity 中用于坐标转换的核心方法,主要功能是将 屏幕空间坐标(如鼠标点击位置)转换为 RectTransform 局部空间的坐标。这在处理 UI 交互(如点击按钮、拖动元素)时非常关键。
核心功能
-
屏幕坐标 → UI 局部坐标
将屏幕上的一个点(如鼠标位置)转换为 UI 元素(RectTransform)内部的相对坐标。 -
处理复杂 UI 布局
自动考虑 UI 元素的 锚点(Anchors)、轴心(Pivot)、缩放 和 Canvas 渲染模式,确保转换结果准确。
应用场景
- 点击定位:将鼠标点击位置转换为 UI 元素内的坐标,用于拖动或选择。
- 跟随鼠标:让 UI 元素(如tooltip)跟随鼠标移动。
- 触摸交互:在移动设备上处理触摸位置与 UI 的关系。
参数与返回值
public static bool ScreenPointToLocalPointInRectangle(
RectTransform rect, // 目标 UI 元素的 RectTransform
Vector2 screenPoint, // 屏幕坐标点(如鼠标位置)
Camera cam, // 渲染 Canvas 的相机(Overlay 模式下为 null)
out Vector2 localPoint // 输出的局部坐标(相对于 rect 的锚点)
);
- 返回值:若转换成功返回
true
,否则返回false
(如目标 RectTransform 不可见)。
坐标系统对比
坐标系统 | 原点位置 | 方向 | 单位 |
---|---|---|---|
屏幕坐标 | 屏幕左下角 (0,0) | X 向右,Y 向上 | 像素 |
RectTransform 局部坐标 | 锚点位置 | X 向右,Y 向上 | 单位(Unity 单位,与像素可能不同) |
🚍
在使用 RectTransformUtility.ScreenPointToLocalPointInRectangle
进行坐标转换时,需要注意以下关键点,以确保转换结果符合预期:
1. Canvas 渲染模式的影响
-
Screen Space - Overlay
Canvas 直接覆盖在屏幕上,此时worldCamera
参数必须为null
。RectTransformUtility.ScreenPointToLocalPointInRectangle( rectTransform, screenPoint, null, // 必须为 null out localPoint);
-
Screen Space - Camera 或 World Space
Canvas 由相机渲染,需传入渲染 Canvas 的相机(通常是Camera.main
)。RectTransformUtility.ScreenPointToLocalPointInRectangle( rectTransform, screenPoint, canvas.worldCamera, // 传入渲染 Canvas 的相机 out localPoint);
2. 坐标系统差异
-
屏幕坐标:
screenPoint
通常来自Input.mousePosition
或触摸位置(如Touch.position
),以像素为单位,原点为屏幕左下角。 -
RectTransform 局部坐标:
localPoint
是相对于目标RectTransform
的锚点(Anchors)的坐标:- 若锚点为中心(默认),
localPoint
的原点是 RectTransform 的中心点。 - 若锚点位于角落(如左上角),
localPoint
的原点是锚点位置。
- 若锚点为中心(默认),
3. 锚点(Anchors)与轴心(Pivot)的影响
-
锚点决定坐标系原点:
转换后的localPoint
以锚点为基准。例如,若锚点位于左上角,localPoint
的(0, 0)
对应 RectTransform 的左上角。 -
轴心影响元素位置:
若要将子元素精确定位到点击位置,需结合轴心调整:childRectTransform.anchoredPosition = localPoint; // 适用于轴心为中心的情况
4. 缩放与分辨率适配
-
Canvas Scaler 的影响:
若 Canvas 使用Canvas Scaler
(如Scale With Screen Size
),转换结果会自动处理缩放,无需额外计算。 -
多分辨率适配:
转换结果在不同分辨率下可能需要调整,特别是当 UI 布局依赖于固定像素大小时。
5. 穿透检测(Raycast)的限制
- 该方法仅计算坐标,不检查点击是否实际命中 UI 元素。若需检测点击,需配合
GraphicRaycaster
:PointerEventData eventData = new PointerEventData(eventSystem); eventData.position = screenPoint; List<RaycastResult> results = new List<RaycastResult>(); raycaster.Raycast(eventData, results);
6. 3D 场景中的 UI 元素
- 若 Canvas 位于 3D 空间(World Space 模式),需确保相机能看到目标 RectTransform,否则转换结果可能异常。
7. 常见错误案例
- 相机错误:使用 Screen Space - Camera 模式时传入
null
相机,或使用 Overlay 模式时传入相机。 - 锚点误解:锚点分散时(如拉伸填充父元素),
localPoint
的解释会更复杂。 - 穿透问题:转换成功但 UI 未响应点击,可能是
Raycast Target
未勾选或被其他元素遮挡。