坑不是很多,直接放代码了。有问题联系QQ412484723,直接挂到UI上就可以用
思路就是ui的坐标位置始终跟第一次按下去的位置的x距离和y距离保持一致,单指的时候直接是第一次按下去的坐标,双指的时候是当前帧的两个点位置中心。之所以用前一帧和当前帧的touch数量判断是为了避免更多点触摸造成位置不准确的问题
在两指中间的缩放,我的思路是先按比例缩放,上一帧两手指的距离/上一帧的scale等于当前帧的两手指距离/scale,这样可以求出scale,记录上一帧两手指中心位置在要缩放的ui下的坐标和ui父物体下的坐标,然后计算当前两手指中心位置在ui下的坐标和父物体下的坐标,用ui的pos加上这两个值就行了。还有一种方法,按下去的时候记录两个手指在ui中坐标,下一帧的时候两个手指在屏幕的坐标换算到ui本地坐标也是上两个值,根据前后四个点反推坐标轴的旋转位移和缩放,这里给出第一种的实现。(canvas用的camera模式,这里直接用的maincamera,具体的应该getcomponentinparent<canvas>().worldcamera这样获取camera)
链接: https://pan.baidu.com/s/1iS_0CltNGaY3z7bSYIOwGA 提取码: hz9g 复制这段内容后打开百度网盘手机App,操作更方便哦
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.UI;
public class PinchZoom : MonoBehaviour
{
private bool _isMousePressed;
public float MaxScale = 6.0f;
public float MinScale = 0.6f;
private Vector2 _midPoint = new Vector2(0, 0);
private Vector2 _start1;
private Vector2 _start2;
private Vector2 _startMid;
private Vector2 _touchScale;
private Vector2 _touchPos;
private Vector2 _startMouse;
private Vector2 pp3;
private Vector2 pp4;
private float _touchLength;
Vector2 aPos1 = new Vector2();
Vector2 aPos2 = new Vector2();
private float _x;
private float _y;
private float _pressTime;
//上一帧touch数量
private int _priorInputCount;
private RectTransform _t;
void Start()
{
_t = (RectTransform)transform;
var c = GetComponentInParent<Canvas>();
Application.targetFrameRate = 60;
Debug.Log(c.worldCamera.name);
}
void Update()
{
//CheckZoomForMobile();
CheckMovingForMobile();
}
private void CheckMovingForMobile()
{
#if UNITY_EDITOR_WIN
if (Input.GetMouseButtonDown(0))
_isMousePressed = true;
else if (Input.GetMouseButtonUp(0))
_isMousePressed = false;
if (_isMousePressed)
_pressTime += Time.deltaTime;
else
_pressTime = 0;
//Zoom out
if (Input.GetAxis("Mouse ScrollWheel") > 0)
{
var pos1 = ScreenToAnchorPosition(Input.mousePosition, _t);
if (_t.localScale.x < MaxScale)
_t.localScale *= 1.1f;
var pos2 = ScreenToAnchorPosition(Input.mousePosition, _t);
Debug.Log(pos1 + "/" + pos2);
_t.anchoredPosition += (pos2 - pos1) * _t.localScale.x;
}
//Zoom in
if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
var pos1 = ScreenToAnchorPosition(Input.mousePosition, _t);
if (_t.localScale.x > MinScale)
_t.localScale *= 0.9f;
var pos2 = ScreenToAnchorPosition(Input.mousePosition, _t);
_t.anchoredPosition += (pos2 - pos1) * _t.localScale.x;
}
if (_pressTime > 0.05f)
{
var x = Input.mousePosition.x;
var y = Input.mousePosition.y;
_t.anchoredPosition += new Vector2(x - _x, y - _y);
}
_x = Input.mousePosition.x;
_y = Input.mousePosition.y;
#endif
//text1.text=_midPoint.ToString();
if (Input.touchCount == 1)
{
var aPos = ScreenToAnchorPosition(Input.GetTouch(0).position, transform.parent.transform as RectTransform);
//第一个点按下或者其余点离开的时候
if (_priorInputCount != 1)
{
_x = aPos.x - _t.anchoredPosition.x;
_y = aPos.y - _t.anchoredPosition.y;
}
_midPoint = aPos;
_t.anchoredPosition = new Vector2(_midPoint.x - _x, _midPoint.y - _y);
}
if (Input.touchCount == 2)
{
//第二个点按下或者其余点离开的时候
var iPos1 = Input.GetTouch(0).position;
var iPos2 = Input.GetTouch(1).position;
_start1 = ScreenToAnchorPosition(iPos1, _t);
_start2 = ScreenToAnchorPosition(iPos2, _t);
if (_priorInputCount != 2)
{
_touchScale = _t.localScale;
_touchPos = _t.anchoredPosition;
_touchLength = Vector2.Distance(iPos1, iPos2);
}
var pos1 = new Vector2((_start1.x + _start2.x) / 2, (_start1.y + _start2.y) / 2);
var curLength = Vector2.Distance(iPos1, iPos2);
var scale = curLength * _touchScale.x / _touchLength;
scale = Mathf.Clamp(scale, MinScale, MaxScale);
_t.localScale = new Vector3(scale, scale, 1);
var p1 = ScreenToAnchorPosition(Input.GetTouch(0).position, _t);
var p2 = ScreenToAnchorPosition(Input.GetTouch(1).position, _t);
var pos2 = new Vector2((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
_t.anchoredPosition += (pos2 - pos1) * scale;
if(_priorInputCount==2)
{
var pp1 = ScreenToAnchorPosition(iPos1, _t.parent.transform as RectTransform);
var pp2 = ScreenToAnchorPosition(iPos2, _t.parent.transform as RectTransform);
var curMid = new Vector2((pp1.x + pp2.x) / 2, (pp1.y + pp2.y) / 2);
var priorMid=new Vector2((pp3.x + pp4.x) / 2, (pp3.y + pp4.y) / 2);
_t.anchoredPosition += curMid - priorMid;
}
pp3 = ScreenToAnchorPosition(iPos1, _t.parent.transform as RectTransform);
pp4 = ScreenToAnchorPosition(iPos2, _t.parent.transform as RectTransform);
}
_priorInputCount = Input.touchCount;
}
Vector2 ScreenToAnchorPosition(Vector2 pos, RectTransform rT)
{
Vector2 position;
RectTransformUtility.ScreenPointToLocalPointInRectangle(rT, pos, Camera.main, out position);
return position;
}
}
网友评论