Unity双指旋转
发表于2018-09-16
Input.touchCount为屏幕触摸的数量(2个手指),我们通过双指移动完成旋转操作,所以屏幕上需要至少2个手指并且手指在移动。
思路都是:
每一帧以两指坐标生成一个向量Vector2,不同帧比较向量的角度变化Vector2.Angle()。
简化版:参考EasyTouch的实现
public class TouchTest : MonoBehaviour { Touch oldTouch1; //上次触摸点1(手指1) Touch oldTouch2; //上次触摸点2(手指2) void Update() { if (Input.touchCount <= 1) { return; } Touch touch1 = Input.GetTouch(0); Touch touch2 = Input.GetTouch(1); //启用双指,尚未旋转 if (touch2.phase == TouchPhase.Began) { oldTouch2 = touch2; oldTouch1 = touch1; return; } if (touch1.phase == TouchPhase.Moved || touch2.phase == TouchPhase.Moved) { Vector2 curVec = touch2.position - touch1.position; Vector2 oldVec = oldTouch2.position - oldTouch1.position; float angle = Vector2.Angle(oldVec, curVec); angle *= Mathf.Sign(Vector3.Cross(oldVec, curVec).z); transform.Rotate(new Vector3(0, 0, angle)); oldTouch1 = touch1; oldTouch2 = touch2; } } }
另一种写法,参考的博客已失效,这里贴一下
const float pinchTurnRatio = Mathf.PI / 2; //用这个数值来判定旋转的最小角度,自己决定大小 const float minTurnAngle = 0; /// <summary> /// The delta of the angle between two touch points /// </summary> static public float turnAngleDelta; /// <summary> /// The angle between two touch points /// </summary> static public float turnAngle; /// <summary> /// Calculates Pinch and Turn - This should be used inside LateUpdate /// </summary> static public void Calculate() { //pinchDistance = pinchDistanceDelta = 0; turnAngle = turnAngleDelta = 0; // if two fingers are touching the screen at the same time ... if (Input.touchCount == 2) { Touch touch1 = Input.touches[0]; Touch touch2 = Input.touches[1]; // ... if at least one of them moved ...如果有一根手指有移动 if (touch1.phase == TouchPhase.Moved || touch2.phase == TouchPhase.Moved) { // ... or check the delta angle between them ... //当前两手指与X轴的角 turnAngle = Angle(touch1.position, touch2.position); //之前两手指与X的角度 float prevTurn = Angle(touch1.position - touch1.deltaPosition, touch2.position - touch2.deltaPosition); //旋转的偏移量, 增量角 turnAngleDelta = Mathf.DeltaAngle(prevTurn, turnAngle); // ... if it's greater than a minimum threshold, it's a turn! //增量角如果大于设定值 if (Mathf.Abs(turnAngleDelta) > minTurnAngle) { turnAngleDelta *= pinchTurnRatio; } else { turnAngle = turnAngleDelta = 0; } } } //鼠标判断事件,这个只是个测试 #if UNITY_EDITOR MouseRotateEvent(); #endif } /// <summary> /// 取两个向量之间的角度 与X轴 /// </summary> /// <param name="pos1"></param> /// <param name="pos2"></param> /// <returns></returns> static private float Angle(Vector2 pos1, Vector2 pos2) { //取两个向量相减 Vector2 from = pos2 - pos1; //X轴 Vector2 to = new Vector2(1, 0); //与X轴夹角 float result = Vector2.Angle(from, to); //向量的叉乘 Vector3 cross = Vector3.Cross(from, to); //如果超出360度 if (cross.z > 0) { //用360来减这个角度 result = 360f - result; } return result; } #if UNITY_EDITOR static bool isPress = false; static float preAngle = 0; /// <summary> /// 鼠标右键旋转事件,并非完美实现,因为没有判断角度为正还是为负。 /// </summary> static public void MouseRotateEvent() { if (Input.GetMouseButton(1)) { //第一次按下 if (!isPress) { //上一帧的角度 preAngle = Angle(Input.mousePosition, Vector2.zero); isPress = true; } else { //转动的角度 turnAngle = Angle(Input.mousePosition, Vector2.zero); //旋转的偏移量, 增量角 turnAngleDelta = Mathf.DeltaAngle(preAngle, turnAngle); Log.log("增量角:"+turnAngleDelta); //增量角如果大于设定值 if (Mathf.Abs(turnAngleDelta) > minTurnAngle) { turnAngleDelta *= pinchTurnRatio; } else { turnAngle = turnAngleDelta = 0; } //更新为这一帧 preAngle = Angle(Input.mousePosition, Vector2.zero); } } else { isPress = false; } } #endif /// <summary> /// 绕点旋转,或者是Z轴旋转? /// </summary> public bool isRotateAround = false; //目标 public Transform target; //围绕点 protected Vector3 axis { get { return new Vector3(target.position.x, transform.position.y, target.position.z); } } //void Start() //{ // if (target == null) { // Debug.Log("target is null!"); // enabled = false; // } //} void Update() { Calculate(); if (Mathf.Abs(turnAngleDelta) > 0) { if (isRotateAround) { //围点旋转 transform.RotateAround(axis, Vector3.up, -turnAngleDelta); //目视对方 transform.LookAt(target); } else { Quaternion desiredRotation = transform.rotation; Vector3 rotationDeg = Vector3.zero; //z轴旋转 rotationDeg.z = -turnAngleDelta; desiredRotation *= Quaternion.Euler(rotationDeg); transform.rotation = desiredRotation; } } }
来自:https://blog.csdn.net/ys5773477/article/details/54986021