[Unity3D]Unity3D遊戲開發之鼠標旋轉、縮放實現3D物品展示

各位朋友,大家好,我是秦元培,歡迎大家關注我的博主,我的博客地址是blog.csdn.net/qinyuanpei。最近博主重點研究了攝像機旋轉、縮放等問題,那麼今天爲大家分享的是一個在3D展示中比較常用的功能,即通過鼠標右鍵實現旋轉、鼠標滾輪實現縮放、鼠標中鍵實現平移。本文采用的方法依然是在[Unity3D]Unity3D遊戲開發之自由視角下的角色控制這篇文章中所採用的方法,所以如果大家對於這部分內容不太瞭解的話,最好先去看看這篇文章。好了,下面我們將以一個具體的實例來講解今天的內容。如圖,是博主創建的一個簡單地場景。我們希望實現通過鼠標右鍵實現對角色的旋轉、鼠標滾輪實現對角色的縮放、鼠標中鍵實現對角色的平移。


    好了,接下來我們來創建一個名爲FreeView的腳本,該腳本依附在主相機上,下面我們來看它的實現過程:

  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class FreeView : MonoBehaviour {  
  5.   
  6.     //觀察目標  
  7.     public Transform Target;  
  8.   
  9.     //觀察距離  
  10.     public float Distance = 5F;  
  11.   
  12.     //旋轉速度  
  13.     private float SpeedX=240;  
  14.     private float SpeedY=120;  
  15.   
  16.     //角度限制  
  17.     private float  MinLimitY = -180;  
  18.     private float  MaxLimitY = 180;  
  19.       
  20.     //旋轉角度  
  21.     private float mX = 0.0F;  
  22.     private float mY = 0.0F;  
  23.       
  24.     //鼠標縮放距離最值  
  25.     private float MaxDistance=10;  
  26.     private float MinDistance=1.5F;  
  27.     //鼠標縮放速率  
  28.     private float ZoomSpeed=2F;  
  29.       
  30.     //是否啓用差值  
  31.     public bool isNeedDamping=true;  
  32.     //速度  
  33.     public float Damping=10F;  
  34.   
  35.     //存儲角度的四元數  
  36.     private Quaternion mRotation;  
  37.   
  38.     //定義鼠標按鍵枚舉  
  39.     private enum MouseButton  
  40.     {  
  41.         //鼠標左鍵  
  42.         MouseButton_Left=0,  
  43.         //鼠標右鍵  
  44.         MouseButton_Right=1,  
  45.         //鼠標中鍵  
  46.         MouseButton_Midle=2  
  47.     }  
  48.   
  49.     //相機移動速度  
  50.     private float MoveSpeed=5.0F;  
  51.     //屏幕座標  
  52.     private Vector3 mScreenPoint;  
  53.     //座標偏移  
  54.     private Vector3 mOffset;  
  55.   
  56.     void Start ()   
  57.     {  
  58.         //初始化旋轉角度  
  59.         mX=transform.eulerAngles.x;  
  60.         mY=transform.eulerAngles.y;  
  61.     }  
  62.       
  63.     void LateUpdate ()   
  64.     {  
  65.         //鼠標右鍵旋轉  
  66.         if(Target!=null && Input.GetMouseButton((int)MouseButton.MouseButton_Right))  
  67.         {  
  68.             //獲取鼠標輸入  
  69.             mX += Input.GetAxis("Mouse X") * SpeedX * 0.02F;  
  70.             mY -= Input.GetAxis("Mouse Y") * SpeedY * 0.02F;  
  71.             //範圍限制  
  72.             mY = ClampAngle(mY,MinLimitY,MaxLimitY);  
  73.             //計算旋轉  
  74.             mRotation = Quaternion.Euler(mY, mX, 0);  
  75.             //根據是否插值採取不同的角度計算方式  
  76.             if(isNeedDamping){  
  77.                 transform.rotation = Quaternion.Lerp(transform.rotation,mRotation, Time.deltaTime*Damping);   
  78.             }else{  
  79.                 transform.rotation = mRotation;  
  80.             }  
  81.         }  
  82.   
  83.         //鼠標中鍵平移  
  84.   
  85.   
  86.         //鼠標滾輪縮放  
  87.         Distance-=Input.GetAxis("Mouse ScrollWheel") * ZoomSpeed;  
  88.         Distance=Mathf.Clamp(Distance,MinDistance,MaxDistance);  
  89.           
  90.         //重新計算位置  
  91.         Vector3 mPosition = mRotation * new Vector3(0.0F, 0.0F, -Distance) + Target.position;  
  92.           
  93.         //設置相機的位置  
  94.         if(isNeedDamping){  
  95.             transform.position = Vector3.Lerp(transform.position,mPosition, Time.deltaTime*Damping);   
  96.         }else{  
  97.             transform.position = mPosition;  
  98.         }  
  99.           
  100.     }  
  101.       
  102.       
  103.     //角度限制  
  104.     private float  ClampAngle (float angle,float min,float max)   
  105.     {  
  106.         if (angle < -360) angle += 360;  
  107.         if (angle >  360) angle -= 360;  
  108.         return Mathf.Clamp (angle, min, max);  
  109.     }  
  110. }  
大家是不是覺得這部分代碼很熟悉?不錯,這裏的原理都是一樣的,大家只要掌握核心原理就可以了,即首先根據鼠標輸入來計算旋轉角、然後通過滾輪輸入計算距離、最後通過四元數運算計算相機的角度和距離。好了,我們來看看最終的效果吧!



         大家應該注意到博主沒有實現按下鼠標中鍵平移的相關方法,因爲這部分博主目前還沒有徹底正確地寫出來,如果大家知道的話,可以給博主留言,或者等博主什麼時候想清楚了再來更新這篇博客吧。博主的博客會經常更新的,希望大家繼續關注我的博客吧。好了,最後我們再來做一個遷移,我們將把這個功能移植到Android平臺上,本來想把這部分作爲Android手勢控制單獨寫一篇文章的,可是感覺這裏的代碼都是相似的,再寫一篇實在沒有必要,所以,就直接給出代碼吧!

  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class MobileInput : MonoBehaviour {  
  5.   
  6.     //觀察目標  
  7.     public Transform Target;  
  8.   
  9.     //觀察距離  
  10.     public float Distance = 2F;  
  11.   
  12.     //距離最值  
  13.     public float MaxDistance=5F;  
  14.     public float MinDistance=0.5F;  
  15.   
  16.     //縮放速率  
  17.     private float ZoomSpeed=0.15F;  
  18.   
  19.     //旋轉速度  
  20.     private float SpeedX=240;  
  21.     private float SpeedY=120;  
  22.     //角度限制  
  23.     private float  MinLimitY = 5;  
  24.     private float  MaxLimitY = 180;  
  25.       
  26.     //旋轉角度  
  27.     private float mX=0;  
  28.     private float mY=0;  
  29.   
  30.     //當前手勢  
  31.     private Vector2 mPos;  
  32.   
  33.     void Start ()   
  34.     {  
  35.         //允許多點觸控  
  36.         Input.multiTouchEnabled=true;  
  37.         //初始化旋轉  
  38.         mX=Target.eulerAngles.x;  
  39.         mY=Target.eulerAngles.y;  
  40.     }  
  41.   
  42.     void Update ()   
  43.     {  
  44.         if(!Target) return;  
  45.   
  46.   
  47.         //單點觸控  
  48.         if(Input.touchCount==1)  
  49.         {  
  50.             //手指處於移動狀態  
  51.             if(Input.touches[0].phase==TouchPhase.Moved)  
  52.             {  
  53.                 mX+=Input.GetAxis("Mouse X") * SpeedX * 0.02F;  
  54.                 mY-=Input.GetAxis("Mouse X") * SpeedY * 0.02F;  
  55.                 mY=ClampAngle(mY,MinLimitY,MaxLimitY);  
  56.             }  
  57.         }  
  58.   
  59.         //多點觸控  
  60.         if(Input.touchCount>1)  
  61.         {  
  62.             //兩隻手指都處於移動狀態  
  63.             if(Input.touches[0].phase==TouchPhase.Moved || Input.touches[1].phase==TouchPhase.Moved)  
  64.             {  
  65.                 //計算移動方向  
  66.                 Vector2 mDir=Input.touches[1].position-Input.touches[0].position;  
  67.                 //根據向量的大小判斷當前手勢是放大還是縮小  
  68.                 if(mDir.sqrMagnitude>mPos.sqrMagnitude){  
  69.                     Distance-=ZoomSpeed;  
  70.                 }else{  
  71.                     Distance+=ZoomSpeed;  
  72.                 }  
  73.                 //限制距離  
  74.                 Distance=Mathf.Clamp(Distance,MinDistance,MaxDistance);  
  75.                 //更新當前手勢  
  76.                 mPos=mDir;  
  77.             }  
  78.         }  
  79.   
  80.         //計算相機的角度和位置  
  81.         transform.rotation=Quaternion.Euler(new Vector3(mY,mX,0));  
  82.         transform.position=transform.rotation * new Vector3(0,0,-Distance)+Target.position;  
  83.     }  
  84.   
  85.     //角度限制  
  86.     private float ClampAngle (float angle,float min,float max)   
  87.     {  
  88.         if (angle < -360) angle += 360;  
  89.         if (angle >  360) angle -= 360;  
  90.         return Mathf.Clamp (angle, min, max);  
  91.     }  
  92. }  


下面是程序在手機上運行過程中的截圖









今天的內容就是這樣子啦,博主最近在搗鼓Unity與Android對接的一些東西,等博主研究好了就分享給大家,希望大家喜歡。最後送上:


每日箴言:生活就是種律動,須有光有影,有左有右。人生就是一場無止境的漂泊。面對生活中那些觸不及防的意外、突如其來的傷痛、從天而降的災難,相信,只要有愛,就有足夠的勇氣去承受人生中所有的風雨,一切會變得輕鬆而釋然。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章