主要有單指移動3D物體、單指旋轉3D物體、雙指縮放3D物體。ide
基類函數
using UnityEngine; using System.Collections; /// <summary> /// 手勢操做父類,並用於互斥三種手勢 /// </summary> public class GestureControl : MonoBehaviour { //記錄手勢狀態: //-1——沒有任何手勢在操做 //0——移動手勢正在操做 //1——旋轉手勢正在操做 //2——縮放手勢正在操做 public static int status = -1; //用於記錄觸碰物體的時間(區分同爲單指時移動與旋轉,詳見相應代碼) public static float TouchTime = 0; protected bool isSelected = false; //判斷是否事先選擇到了某物體 protected void OnMouseDown() { isSelected = true; } //手指擡起,記錄歸零 protected void OnMouseUp() { isSelected = false; status = -1; TouchTime = 0; } // Update is called once per frame protected void Update() { if (!isSelected) { return; } else if(status == -1) { InputCheck(); } } /// <summary> /// 之類相應操做 /// </summary> protected virtual void InputCheck() { } }
單指移動3D物體this
using UnityEngine; using System.Collections; using UnityEngine.EventSystems; using System; public class MoveControl : GestureControl { protected override void InputCheck() { //單指移動 if (Input.touchCount == 1) { //觸碰按住3D物體不動1秒後物體隨手指一塊兒移動 if (Input.GetTouch(0).phase == TouchPhase.Stationary) { TouchTime += Time.deltaTime; if (TouchTime > 1) { status = 0; } } if (status == 0) { StartCoroutine(CustomOnMouseDown()); } } } IEnumerator CustomOnMouseDown() { //將物體由世界座標系轉化爲屏幕座標系,由vector3 結構體變量ScreenSpace存儲,以用來明確屏幕座標系Z軸的位置 Vector3 ScreenPoint = Camera.main.WorldToScreenPoint(transform.position); //因爲鼠標的座標系是二維的,須要轉化成三維的世界座標系; Vector3 WorldPostion = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, ScreenPoint.z)); //三維的狀況下才能來計算鼠標位置與物體的距離 Vector3 distance = transform.position - WorldPostion; //當鼠標左鍵按下時 while (Input.GetMouseButton(0)) { //獲得如今鼠標的二維座標系位置 Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, ScreenPoint.z); //將當前鼠標的2維位置轉化成三維的位置,再加上鼠標的移動距離 Vector3 CurPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + distance; //CurPosition就是物體應該的移動向量賦給transform的position屬性 transform.position = CurPosition; //鼠標釋放前都起做用 yield return new WaitForFixedUpdate(); } } }
單指旋轉3D物體spa
using UnityEngine; using System.Collections; using UnityEngine.EventSystems; using System; public class RotateControl : GestureControl { protected override void InputCheck() { #region 單點觸發旋轉(真實模型旋轉) if (Input.touchCount == 1) { //觸摸爲移動類型 if (Input.GetTouch(0).phase == TouchPhase.Moved) { status = 1; try { StartCoroutine(CustomOnMouseDown()); } catch (Exception e) { Debug.Log(e.ToString()); } } } #endregion #region 鍵盤A、D、W、S模擬旋轉(真實模型旋轉) if (Input.GetKeyDown(KeyCode.A)) { transform.Rotate(Vector3.up, 45 * Time.deltaTime, Space.World); } if (Input.GetKeyDown(KeyCode.D)) { transform.Rotate(Vector3.up, -45 * Time.deltaTime, Space.World); } if (Input.GetKeyDown(KeyCode.W)) { transform.Rotate(Vector3.left, 45 * Time.deltaTime, Space.World); } if (Input.GetKeyDown(KeyCode.S)) { transform.Rotate(Vector3.left, -45 * Time.deltaTime, Space.World); } #endregion } IEnumerator CustomOnMouseDown() { //當檢測到一直觸碰時,會不斷循環運行 while (Input.GetMouseButton(0)) { //判斷是否點擊在UI上 #if UNITY_ANDROID || UNITY_IPHONE if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)) #else if (EventSystem.current.IsPointerOverGameObject()) #endif { Debug.Log("當前點擊在UI上"); } else { float XX = Input.GetAxis("Mouse X"); float YY = Input.GetAxis("Mouse Y"); #region //判斷左右滑動的距離與上下滑動距離大小 if (Mathf.Abs(XX) >= Mathf.Abs(YY)) { //單指向左滑動狀況 if (XX < 0) { transform.Rotate(Vector3.up, 45 * Time.deltaTime, Space.World); } //單指向右滑動狀況 if (XX > 0) { transform.Rotate(-Vector3.up, 45 * Time.deltaTime, Space.World); } } else { //單指向下滑動狀況 if (YY < 0) { transform.Rotate(Vector3.left, 45 * Time.deltaTime, Space.World); } //單指向上滑動狀況 if (YY > 0) { transform.Rotate(-Vector3.left, 45 * Time.deltaTime, Space.World); } } #endregion } yield return new WaitForFixedUpdate(); } } }
雙指縮放3D物體code
using UnityEngine; using System.Collections; public class ZoomControl : GestureControl { //記錄上一次手機觸摸位置判斷用戶是在左放大仍是縮小手勢 private Vector2 oldPosition1; private Vector2 oldPosition2; //實時大小 Vector3 RealScale = new Vector3(1f, 1f, 1f); //原始大小 float InitialScale = 0; //縮放速度 public float ScaleSpeed = 0.1f; //縮放比例 public float MaxScale = 2.5f; public float MinScale = 0.5f; void Start() { //獲取物體最原始大小 InitialScale = this.transform.localScale.x; } protected override void InputCheck() { #region 多點觸摸縮放(真實模型縮放) if (Input.touchCount > 1) { status = 2; StartCoroutine(CustomOnMouseDown()); } #endregion } IEnumerator CustomOnMouseDown() { //當檢測到一直觸碰時,會不斷循環運行 while (Input.GetMouseButton(0)) { //實時記錄模型大小 RealScale = this.transform.localScale; if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved) { //觸摸位置 Vector3 tempPosition1 = Input.GetTouch(0).position; Vector3 tempPosition2 = Input.GetTouch(1).position; //函數返回真爲放大,返回假爲縮小 if (isEnlarge(oldPosition1, oldPosition2, tempPosition1, tempPosition2)) { //判斷是否超過邊界 if (RealScale.x < InitialScale * MaxScale) { this.transform.localScale += this.transform.localScale * ScaleSpeed; } } else { //判斷是否超過邊界 if (RealScale.x > InitialScale * MinScale) { this.transform.localScale -= this.transform.localScale * ScaleSpeed; } } //備份上一次的觸摸位置 oldPosition1 = tempPosition1; oldPosition2 = tempPosition2; } yield return new WaitForFixedUpdate(); } } //記錄手指位置與初始位置是縮小或放大 bool isEnlarge(Vector2 oP1, Vector2 oP2, Vector2 nP1, Vector2 nP2) { float leng1 = Mathf.Sqrt((oP1.x - oP2.x) * (oP1.x - oP2.x) + (oP1.y - oP2.y) * (oP1.y - oP2.y)); float leng2 = Mathf.Sqrt((nP1.x - nP2.x) * (nP1.x - nP2.x) + (nP1.y - nP2.y) * (nP1.y - nP2.y)); if (leng1 < leng2) { return true; } else { return false; } } }