1.前言
在某些情况下我们需要在Image中进行点击并获取到点击点在Image中的具体位置,那么如果我们只添加一个Button,仅仅只能响应点击事件,如何获取该UGUI中的具体发生点击的位置坐标呢?
本文实现了一种获取点击点在UGUI中的具体位置的方法,该方法适用于所有继承Graphic的UGUI。
2.原理
原理很简单,就是将发生点击的屏幕坐标转换为目标对象的本地坐标,再根据目标的宽和高进行一系列转换,得出点击点相对于目标对象的坐标。该方法适用于所有继承Graphic的对象,Raycast Target要为true。
3.效果展示
#Clicked position (local)是相对于轴点的本地坐标,和轴点有关。
#Clicked position (normalized)是转换成归一化的坐标,范围是0到1,和轴点无关,ugui左下角为(0, 0),右上角为(1, 1)。
#relativePos是轴点为(0.5f,0.5f)时的本地坐标。
1)轴点在中心
Image对象的属性
可以看到Pivot为(0.5f,0.5f),即轴点在Image中心点。
红色标记是我所标记的这次点击的大概位置,可能不准确。
可以看到我尽可能的点击在中心点,由于轴点就在中心,所以点击点Clicked position应该比较接近(0,0)的。归一化后的坐标也应该在(0.5,0.5)左右。由于轴点就是(0.5f,0.5f),所以Position relative和local相同。
再次点击最左下角测试下,预期结果应该是local和relative接近(-200,-200),归一化后接近(0,0)。
结果和预期相符。
2)轴点不在中心点
我们将轴点修改为(0,0)。
再次点击Imgae的中心点和左下角,预期结果应该是中心点的local为(200,200)左右,归一化在(0.5,0.5)左右,relative在(0,0)左右,和第一次测试差不了多少;左下角点的local为(0,0)左右,归一化在(0,0)左右,relative在(-200,-200)左右,和第一次测试差不了多少。
实际结果:
再次修改轴点
4.代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[RequireComponent(typeof(Graphic))]
public class UIClickPosition : MonoBehaviour, IPointerClickHandler
{
RectTransform rectTf;
void Start()
{
rectTf = GetComponent<RectTransform>();
}
public void OnPointerClick(PointerEventData eventData)
{
Vector2 localPoint;
//将屏幕空间的点转换成RectTransform指定的本地空间点
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTf, eventData.position, eventData.pressEventCamera, out localPoint))
{
// localPoint 是相对于轴点的本地坐标,和轴点有关
Debug.Log("Clicked position (local): " + localPoint);
//转换成归一化的坐标,范围是0到1,和轴点无关,ugui左下角为(0, 0),右上角为(1, 1)
Vector2 normalizedPoint = Rect.PointToNormalized(rectTf.rect, localPoint);
Debug.Log("Clicked position (normalized): " + normalizedPoint);
//relativePos是轴点为(0.5,0.5)时的本地坐标
Vector2 pivot = rectTf.pivot;
Vector2 size = new Vector2(rectTf.rect.width, rectTf.rect.height);
Vector2 offsetPivot = new Vector2(0.5f, 0.5f) - pivot;
Vector2 relativePos = localPoint - offsetPivot * size;
Debug.Log("Clicked position relative to pivot(0.5f,0.5f)(local):" + relativePos);
}
}
}