標籤:style blog http io color os ar 使用 for
前幾篇文章介紹了很多Unity3D引擎自身的一些問題, 今天我們在回到IOS裝置上討論一些觸控螢幕幕手勢,本章的目標是通過觸摸iPhone螢幕手勢 實現模型左右的旋轉,與模型的縮放。
大家想一想模型的旋轉,實際上是鏡頭的旋轉。模型的縮放實際上是鏡頭Z軸方向的座標。那麼實現本章的內容只需要控制鏡頭的位置方可實現。
我們建立一個簡單的遊戲平面, 然後平面中放一個箱子做為旋轉縮放的參照物。如所示,選中攝像機,給攝像機添加一個指令碼名稱為Move. 指令碼中有一個參數 Target,它的作用是設定網路攝影機旋轉移動參照物,這裡把一個箱子賦值給了Target,那麼左右滑動螢幕會發現箱子在旋轉,兩手縮放螢幕會發現箱子在放大與縮小。
//用於綁定參照物對象 public Transform target; //縮放係數 float distance = 10.0f; //左右滑動移動速度 float xSpeed = 250.0f; float ySpeed = 120.0f; //縮放限制係數 float yMinLimit = -20f; float yMaxLimit = 80f; //網路攝影機的位置 float x = 0.0f; float y = 0.0f; //記錄上一次手機觸摸位置判斷使用者是在左放大還是縮小手勢 private Vector2 oldPosition1; private Vector2 oldPosition2; //初始化遊戲資訊設定 void Start() { //eulerAngles(歐拉角):x、y、z角代表繞z軸旋轉z度,繞x軸旋轉x度,繞y軸旋轉y度(這個順序)。 var angles = transform.eulerAngles;//即網路攝影機的相對Rotation的值 x = angles.y; y = angles.x; // Make the rigid body not change rotation if (rigidbody) rigidbody.freezeRotation = true;//凍結旋轉,如果freezeRotation被啟用,旋轉不會被物體類比修改。這對於建立第一人稱射擊遊戲時是很有用的,因為玩家需要使用滑鼠完全控制旋轉。 } void Update() { //判斷觸摸數量為單點觸摸 if (Input.touchCount == 1) { //觸摸類型為移動觸摸 if (Input.GetTouch(0).phase == TouchPhase.Moved) { //根據觸摸點計算X與Y位置 x += (float)(Input.GetAxis("Mouse X") * xSpeed * 0.02); y -= (float)(Input.GetAxis("Mouse Y") * ySpeed * 0.02); } } //判斷觸摸數量為多點觸摸 if (Input.touchCount > 1) { //前兩隻手指觸摸類型都為移動觸摸 if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved) { //計算出當前兩點觸摸點的位置 var tempPosition1 = Input.GetTouch(0).position; var tempPosition2 = Input.GetTouch(1).position; //函數返回真為放大,返回假為縮小 if (isEnlarge(oldPosition1, oldPosition2, tempPosition1, tempPosition2)) { //放大係數超過3以後不允許繼續放大 //這裡的資料是根據我項目中的模型而調節的,大家可以自己任意修改 if (distance > 3) { distance -= 0.5f; } } else { //縮小係數返回18.5後不允許繼續縮小 //這裡的資料是根據我項目中的模型而調節的,大家可以自己任意修改 if (distance < 18.5) { distance += 0.5f; } } //備份上一次觸摸點的位置,用於對比 oldPosition1 = tempPosition1; oldPosition2 = tempPosition2; } } } //函數返回真為放大,返回假為縮小 bool isEnlarge(Vector2 oP1, Vector2 oP2, Vector2 nP1, Vector2 nP2) { //函數傳入上一次觸摸兩點的位置與本次觸摸兩點的位置計算出使用者的手勢 // var leng1 = Mathf.Sqrt((oP1.x - oP2.x) * (oP1.x - oP2.x) + (oP1.y - oP2.y) * (oP1.y - oP2.y)); // var leng2 = Mathf.Sqrt((nP1.x - nP2.x) * (nP1.x - nP2.x) + (nP1.y - nP2.y) * (nP1.y - nP2.y)); var leng1 = Vector2.Distance(oP1, oP2); var leng2 = Vector2.Distance(nP1, nP2); if (leng1 < leng2) { //放大手勢 return true; } else { //縮小手勢 return false; } } //Update方法一旦調用結束以後進入這裡算出重設攝像機的位置 void LateUpdate() { //target為我們綁定的箱子變數,縮放旋轉的參照物 if (target) { //重設攝像機的位置 y = ClampAngle(y, yMinLimit, yMaxLimit); var rotation = Quaternion.Euler(y, x, 0); var position = rotation * new Vector3(0.0f, 0.0f, -distance) + target.position; //rotation.ToAngleAxis(out zwhangle, out zwhaxis); 轉換一個旋轉用“角-軸”表示。 //position表示此時將camera對象的位置設定為new Vector3(0.0f, 0.0f, -distance),然後從這個位置繞zwhaxis軸旋轉zwhangle角度,從而獲得新的位置,而加上target.position,是使camera對象的位置距離zwhaxis軸的更遠 //transform.rotation = rotation;//這句可以用下面的方式,都是一樣的 transform.position = position; transform.rotation = Quaternion.LookRotation(target.position - transform.position); } } static float ClampAngle(float angle, float min, float max) { if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp(angle, min, max); }
我們看看Move這條指令碼,說明一下幾個重要的 :
這些方法都是系統自己調用的方法
function Start () : 遊戲啟動以後只調用一次,可用於指令碼的初始化操作,
function Update ():Start()方法調用結束以後每一幀都會調用,可以在這裡更新遊戲邏輯。
function LateUpdate (): Start()方法調用結束以後每一幀都會調用,但是它是在 Update()調用完後調用。
:http://vdisk.weibo.com/s/abssL
- 本文固定連結: http://www.xuanyusong.com/archives/512
- 轉載請註明: 雨松MOMO 2012年05月01日 於 雨松MOMO程式研究院 發表
上面關鍵的代碼是:
var position = rotation * new Vector3(0.0f, 0.0f, -distance) + target.position;
我已經注釋說明了!不懂的可以看另一個列子,有助於理解:
public GameObject cameraObject; public float cameraDistance;//the distance the camera should be palced from the palyer public float cameraHeight;//how heigh the camera should be private float cameraAngleToPlayer;// the current angle the camera is to the palyer private Vector3 tempVector; // the temporary vector we shall use for calcuations void Update() { tempVector = Vector3.left; if (Input.GetKey("left")) //rotation the angle based on input { cameraAngleToPlayer = cameraAngleToPlayer - (Time.deltaTime * 50f); } else if (Input.GetKey("right")) { cameraAngleToPlayer = cameraAngleToPlayer + (Time.deltaTime * 50f); } tempVector = Quaternion.AngleAxis(cameraAngleToPlayer, Vector3.up) * tempVector; Debug.DrawLine(transform.position, tempVector * 10f, Color.yellow); //cameraObject.transform.position = transform.position + (tempVector.normalized * cameraDistance); cameraObject.transform.position = tempVector; //tempVector表示此時的camera對象的位置將從Vector3.left(-1f,0,0)這個位置繞Vector3.up軸旋轉cameraAngleToPlayer角度,從而獲得新的位置,而乘以10,是使camera對象的位置距離Vector3.up軸的更遠 cameraObject.transform.rotation = Quaternion.LookRotation(transform.position - cameraObject.transform.position); }
參考:http://www.cnblogs.com/88999660/archive/2013/08/16/3262656.html
【轉載】Unity3D研究院之IOS觸控螢幕手勢控制鏡頭旋轉與縮放