ScrollView双指缩放
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
//参考自 https://blog.csdn.net/qq_39162826/article/details/108587752
public class TouchScale : MonoBehaviour
{
RectTransform contentRect;
RectTransform scrollRect;
public ScrollRect scroll;
float scrollW;
float scrollH;
float contentW;
float contentH;
void Start()
{
scrollRect = scroll.GetComponent<RectTransform>();
contentRect = scroll.content;
scrollW = scrollRect.sizeDelta.x;
scrollH = scrollRect.sizeDelta.y;
contentW = contentRect.sizeDelta.x;
contentH = contentRect.sizeDelta.y;
float scaleWMin = scrollW / contentW;
float scaleHMin= scrollH / contentH;
scaleRange.x = scaleWMin > scaleHMin ? scaleWMin : scaleHMin;
}
float baseDistance;
float baseScale;
Vector2 scaleRange = new Vector2(0.675f, 1);
Vector2 midPos;
Vector3 contentPos;
Vector3 baseDisV3;
void Update()
{
if (Input.touchCount > 1)
{
scroll.enabled = false;
Touch t1 = Input.touches[0];
Touch t2 = Input.touches[1];
if (t1.phase == TouchPhase.Canceled || t2.phase == TouchPhase.Canceled || t1.phase == TouchPhase.Ended || t2.phase == TouchPhase.Ended)
{
return;
}
bool isNew =t1.phase==TouchPhase.Began|| t2.phase == TouchPhase.Began;
if (isNew)//两个触控点中任意一个刚按下时
{
//的焦点位置
Vector3 midPos = new Vector3((Camera.main.ScreenToWorldPoint(t1.position).x + Camera.main.ScreenToWorldPoint(t2.position).x) / 2, (Camera.main.ScreenToWorldPoint(t1.position).y + Camera.main.ScreenToWorldPoint(t2.position).y) / 2, 0);
//的界面初始位置 也是它的中心位置
contentPos = contentRect.position;
//的焦点到界面中心位置的初始向量
baseDisV3 = midPos - contentPos;
//的两个触控点的初始距离
baseDistance = Vector2.Distance(t1.position, t2.position);
//的界面的初始缩放值
baseScale = contentRect.localScale.x;
}
else
{
//两个触控点 任意一个移动时
if (t1.phase == TouchPhase.Moved || t2.phase == TouchPhase.Moved)
{
//当前的两个触控点的距离
float nowDistance = Vector2.Distance(t1.position, t2.position);
//根据两个触控点的当前距离和初始距离的比值等比例改变缩放值
float scale = baseScale* nowDistance / baseDistance;
//确保缩放值在限制范围内
scale = Mathf.Clamp(scale, scaleRange.x, scaleRange.y);
//设置缩放值
contentRect.localScale = Vector3.one * scale;
//由于缩放导致的焦点到界面中心位置的向量disV3变化了 获得disV3变化的值
Vector3 disV3Change = baseDisV3 * (scale / baseScale - 1);
#region 根据content的缩放获取当前的xy轴移动范围
float scaleWidth = contentW * scale;
float scaleHeight = contentH * scale;
float wL = Mathf.Abs((scaleWidth - scrollW) / 2);
float hL = Mathf.Abs((scaleHeight - scrollH) / 2);
#endregion
//通过移动content位置来保证焦点的相对位置不变
float x = contentPos.x - disV3Change.x;
float y = contentPos.y - disV3Change.y;
contentRect.position = new Vector3(x, y, 0);
//移动完content位置后校验一下 来保证在限制范围内
contentRect.localPosition = new Vector3(Mathf.Clamp(contentRect.localPosition.x, -wL, wL),
Mathf.Clamp(contentRect.localPosition.y, -hL, hL),0);
}
}
}
else
{
scroll.enabled = true;
}
}
}