周末的時候接了一個公司派的緊急任務,接收了一個半成品程序,雖然不是unity寫的,但是在一個腳本里直接干了四五千行,類都沒有分的有沒有,這能搞死人的有沒有(希望別讓老大看見了)。
總之呢,現在是好好的坐在電腦前,由於現在也在逐漸的從現在的語言過度到unity上,所以偶爾也會查下unity的一些資料。廢話少說,以下是此貼的內容,轉自https://blog.csdn.net/inlet511/article/details/46822259,我本人沒有試驗過,請看此貼的人注意。
關鍵點1:
在unity中touch事件同時也會觸發GetMouseButton事件,有時候可能會給你帶來方便,但是如果沒有意識到這個問題的話,也很可能給你帶來很大的麻煩。
關鍵點2:
觸摸操作也可以使用Input.GetAxis(“Mouse X”)(或”Mouse Y”,下同,略去不寫)來判斷指尖移動的距離,雖然這點很方便,但是這樣就帶來了另外兩個問題,見關鍵點3和4;
關鍵點3:
Input.GetAxis(“Mouse X”)取得的值與Input.GetTouch(0).deltaPosition的取值有一些細微但是很重要的差別:
- 如果使用鼠標操作,那么Input.GetAxis對鼠標移動的取值方式表現的很正常,因為不管是否點擊,鼠標始終存在,鼠標位置始終能夠正常獲取,Input.GetAxis(“Mouse X”)原本是為鼠標設計的,取值方式是連續的;使用Input.GetTouch(0).deltaPosition無效,因為沒有觸摸操作;
- 如果使用觸摸操作,再細分兩種情形:
- 如果使用if(Input.GetMouseButton(0))來作為判斷是否按下的條件:
那么使用Input.GetAxis來獲取手指的移動就需要注意了,觸摸的手指是可以離開屏幕的,一旦手指離開屏幕,GetAxis(“Mouse X”)就不知所措了,只好記住離開前的手指位置,下一次手指再接觸的時候和這個位置對比(個人猜測GetAxis(“Mouse X”)是對比鼠標/觸摸點位置的方法來取得的)。例如手指從屏幕的左邊拿開,然后再觸摸屏幕的右邊,那么取得的x位置會是一個很大的正值。這就是個很大的問題,這個問題是GetMouseButton和GetAxis在使用手指觸摸的情況下配合上的不默契產生的。但是使用Input.GetTouch(0).deltaPosition就不會有這種現象,個人猜測可能是因為deltaPosition是測量每一幀內的移動距離的方法吧。 - 如果使用 if(Input.touchCount>0&&Input.GetTouch(0).phase == TouchPhased.Moved)來做為判斷是否按下的條件:
使用Input.GetAxis(“Mouse X”),沒有任何問題;
使用deltaPosition同樣沒有任何問題,因為這就是為觸摸操作而設計的。
- 如果使用if(Input.GetMouseButton(0))來作為判斷是否按下的條件:
關鍵點4:
實踐中發現在直觀感覺差不多的滑動過程(分別用鼠標拖動和手指拖動)中,Input.GetTouch(0).deltaPosition.x 的值總是比Input.GetAxis(“Mouse X”)取得的值要大很多,分析可能是手機屏幕dpi比較大的原因,因此在實踐中為了獲取直觀感受差不多的旋轉速度,要分別調試旋轉加成系數。
總結
不要使用一條代碼判斷兩種情況,最好分開,做一個單選(可以使用Enum),要么鼠標操作,要么觸摸操作,分別使用最合適的判斷和函數,並分別調試旋轉加成系數
事件回顧
在寫一個慣性拖動旋轉的腳本的時候,為在pc和Android平台上都能使用(即用鼠標和觸摸都能控制),我使用了如下的判斷語句:
1 if(Input.GetMouseButton(0) || (Input.touchCount>0 && Input.GetTouch(0).phase == TouchPhase.Moved)
來判斷鼠標按下或者手指按下,並用Input.GetAxis(“Mouse X”)來獲取拖動的值,期望能夠一次判斷兩種情況,分別適應不同平台的操作。在pc上使用鼠標操作沒有任何問題,但是在android上觸摸操作時出現了問題。經過多次測試並查閱資料,發現原來觸摸操作也可以觸發Input.GetMouseButton(0)的事件,這就引發了前述 關鍵點3第二條第一項中的問題。
附:慣性旋轉物體腳本:
using UnityEngine; using System.Collections; //操作方式 public enum ControlType{ mouseControl, touchControl, } public class RotateTarget: MonoBehaviour { public ControlType controlType; public Transform rotTarget; //旋轉速度加成系數 public float rotSpeedScalar; private float currentSpeed = 0; void Update() { if (controlType==ControlType.mouseControl) { //鼠標操作 if (Input.GetMouseButton(0)) { //拖動時速度 //鼠標或手指在該幀移動的距離*deltaTime為手指移動的速度,此處為Input.GetAxis("Mouse X") / Time.deltaTime //不通幀率下lerp的第三個參數(即混合比例)也應根據幀率而不同-- //考慮每秒2幀和每秒100幀的情況,如果此參數為固定值,那么在2幀的情況下,一秒后達到目標速度的0.75,而100幀的情況下,一秒后則基本約等於目標速度 currentSpeed = Mathf.Lerp(currentSpeed, Input.GetAxis("Mouse X") / Time.deltaTime,0.5f*Time.deltaTime); } else { //放開時速度 currentSpeed = Mathf.Lerp(currentSpeed, 0, 0.5f*Time.deltaTime); } } else if(controlType==ControlType.touchControl) { //觸摸操作 if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved) { //在安卓設備上也可以用Mouse X,根據實驗,touch[0].deltaPosition.x的值總是比Mouse X的值大很多,所以此處使用Mouse X currentSpeed = Mathf.Lerp(currentSpeed, Input.GetAxis("Mouse X")/Time.deltaTime,0.5f*Time.deltaTime); } else { //放開時速度 currentSpeed = Mathf.Lerp(currentSpeed, 0, 0.5f*Time.deltaTime); } } rotTarget.Rotate(Vector3.down, Time.deltaTime * currentSpeed * rotSpeedScalar); } }
