我会使用RectTransformUtility.ScreenPointToLocalPointInRectangle 在给定RectTransform 的本地空间中获取位置。
然后将其与Rect.PointToNormalized结合起来
返回对应点的归一化坐标。
返回的Vector2 在 0 到 1 的范围内,值大于 1 或小于零。
在RectTransform.rect (0,0) 中获得标准化位置 左下角 角,(1,1) 是 右上角 角
[SerializeField] private RectTransform _rectTransform;
private void Awake ()
{
if(!_rectTransform) _rectTransform = GetComponent<RectTransform>();
}
private bool GetNormalizedPosition(PointerEventData pointerEventData, out Vector2 normalizedPosition)
{
normalizedPosition = default;
// get the pointer position in the local space of the UI element
// NOTE: For click vents use "pointerEventData.pressEventCamera"
// For hover events you would rather use "pointerEventData.enterEventCamera"
if(!RectTransformUtility.ScreenPointToLocalPointInRectangle(_rectTransform, pointerEventData.position, pointerEventData.pressEventCamera, out var localPosition)) return false;
normalizedPosition = Rect.PointToNormalized(_rectTransform.rect, localPosition);
// I think this kind of equals doing something like
//var rect = _rectTransform.rect;
//var normalizedPosition = new Vector2 (
// (localPosition.x - rect.x) / rect.width,
// (localPosition.y - rect.y) / rect.height);
Debug.Log(normalizedPosition);
return true;
}
由于归一化位置返回的值类似于
(0|1)-----(1|1)
| |
| (0|0) |
| |
(0|0)-----(1|0)
但听起来你想要得到的是
(-1|1)----(1|1)
| |
| 0|0 |
| |
(-1|-1)----(1|-1)
所以你可以简单地使用例如移动返回的值
// Shift the normalized Rect position from [0,0] (bottom-left), [1,1] (top-right)
// into [-1, -1] (bottom-left), [1,1] (top-right)
private static readonly Vector2 _multiplcator = Vector2.one * 2f;
private static readonly Vector2 _shifter = Vector2.one * 0.5f;
private static Vector2 GetShiftedNormalizedPosition(Vector2 normalizedPosition)
{
return Vector2.Scale((normalizedPosition - _shifter), _multiplcator);
}
所以最后你会使用例如
public void OnPointerDown(PointerEventData pointerEventData)
{
if(!GetNormalizedPosition(pointerEventData, out var normalizedPosition)) return;
var shiftedNormalizedPosition = GetShiftedNormalizedPosition(normalizedPosition);
SetAccelerationValue(shiftedNormalizedPosition.y);
// And probably for your other question also
SetSteeringValue(shiftedNormalizedPosition.x);
}
当然,在SetAccelerationValue 内,您无需计算任何内容,只需设置值;)
这始终使用当前矩形,因此您不必存储任何最小值/最大值,它也适用于矩形的任何动态重新缩放。
这可能也适用于您的other almost duplicate question ;)