使用 Unity 5 UI 进行双指缩放

Van*_*000 5 c# user-interface unity-game-engine pinchzoom unity5

我正在尝试在基于 Unity UI 的应用程序中重新实现双指缩放系统。大约六个月前,我能够通过使 UI 画布成为常规 GameObject 的子项并操纵该对象的变换来一起破解一个,但自从更新到 Unity 5.5+ 后,我发现这不起作用。我能得到的最接近的允许捏手势改变画布的比例因子,这 a) 可以根据它们的对齐方式使图像、面板等不正确地调整大小,b) 一旦缩放就不允许我平移。

到目前为止,我所拥有的是:

public class PinchToZoomScaler : MonoBehaviour {

    public Canvas canvas; // The canvas
    public float zoomSpeed = 0.5f;        // The rate of change of the canvas scale factor

    public float _resetDuration = 3.0f;
    float _durationTimer = 0.0f;

    float _startScale = 0.0f;

    void Start() {
        _startScale = canvas.scaleFactor;
    }

    void Update()
    {
            // If there are two touches on the device...
            if (Input.touchCount == 2) {
                // Store both touches.
                Touch touchZero = Input.GetTouch (0);
                Touch touchOne = Input.GetTouch (1);

                // Find the position in the previous frame of each touch.
                Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
                Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;

                // Find the magnitude of the vector (the distance) between the touches in each frame.
                float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
                float touchDeltaMag = (touchZero.position - touchOne.position).magnitude;

                // Find the difference in the distances between each frame.
                float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag;

                // ... change the canvas size based on the change in distance between the touches.
                canvas.scaleFactor -= deltaMagnitudeDiff * zoomSpeed;

                // Make sure the canvas size never drops below 0.1
                canvas.scaleFactor = Mathf.Max (canvas.scaleFactor, _startScale);
                canvas.scaleFactor = Mathf.Min (canvas.scaleFactor, _startScale * 3.0f);

                _durationTimer = 0.0f;
            } else {
                _durationTimer += Time.deltaTime;

                if (_durationTimer >= _resetDuration) {
                    canvas.scaleFactor = _startScale;
                }
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

正如我所说,这在一定程度上有效,但不能给我一个很好的统一缩放,也不能让我平移画布。在此先感谢您的帮助。

Moh*_*der 0

您可以使用此函数(只需将负 deltaMagnitudeDiff 传递给它)另外,以 ( 0.05 ) 之类的比率多重播放 deltaMagnitudeDiff 也很好

float currentScale = 1f;
void Zoom (float increment)
{
    currentScale += increment;
    if (currentScale >= maxScale)
    {
        currentScale = maxScale;
    }
    else if (currentScale <= minScale)
    {
        currentScale = minScale;
    }
    rectTransform.localScale = new Vector3 (currentScale, currentScale, 1);

    pan.ValidatePosition ();
}
Run Code Online (Sandbox Code Playgroud)

对于平移,您可以使用如下内容:

public class Pan : MonoBehaviour
{
    public float Speed;

    Vector3 startDragPosition;

    public void BeginDrag ()
    {
        startDragPosition = Input.mousePosition;
    }

    public void Drag ()
    {
        transform.localPosition += (Input.mousePosition - startDragPosition) * Speed;
        startDragPosition = Input.mousePosition;

        ValidatePosition ();
    }

    public void ValidatePosition ()
    {
        var temp = transform.localPosition;

        var width = ((RectTransform)transform).sizeDelta.x;
        var height = ((RectTransform)transform).sizeDelta.y;

        var MaxX = 0.5f * width * Mathf.Max (0, transform.localScale.x - 1);
        var MaxY = 0.5f * height * Mathf.Max (0, transform.localScale.y - 1);

        var offsetX = transform.localScale.x * width * (((RectTransform)transform).pivot.x - 0.5f);
        var offsetY = transform.localScale.y * width * (((RectTransform)transform).pivot.y - 0.5f);

        if (temp.x < -MaxX + offsetX)
            temp.x = -MaxX + offsetX;
        else if (temp.x > MaxX + offsetX)
            temp.x = MaxX + offsetX;

        if (temp.y < -MaxY + offsetY)
            temp.y = -MaxY + offsetY;
        else if (temp.y > MaxY + offsetY)
            temp.y = MaxY + offsetY;

        transform.localPosition = temp;
}
Run Code Online (Sandbox Code Playgroud)

只需从事件触发器组件调用函数(BeginDrag 和 Drag)即可。