思路都是:
每一幀以兩指坐標生成一個向量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; } } }
新聞熱點
疑難解答