Unity中觸摸和鼠標操作的幾個問題


  周末的時候接了一個公司派的緊急任務,接收了一個半成品程序,雖然不是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的取值有一些細微但是很重要的差別:

  1. 如果使用鼠標操作,那么Input.GetAxis對鼠標移動的取值方式表現的很正常,因為不管是否點擊,鼠標始終存在,鼠標位置始終能夠正常獲取,Input.GetAxis(“Mouse X”)原本是為鼠標設計的,取值方式是連續的;使用Input.GetTouch(0).deltaPosition無效,因為沒有觸摸操作;
  2. 如果使用觸摸操作,再細分兩種情形:
      1. 如果使用if(Input.GetMouseButton(0))來作為判斷是否按下的條件: 
        那么使用Input.GetAxis來獲取手指的移動就需要注意了,觸摸的手指是可以離開屏幕的,一旦手指離開屏幕,GetAxis(“Mouse X”)就不知所措了,只好記住離開前的手指位置,下一次手指再接觸的時候和這個位置對比(個人猜測GetAxis(“Mouse X”)是對比鼠標/觸摸點位置的方法來取得的)。例如手指從屏幕的左邊拿開,然后再觸摸屏幕的右邊,那么取得的x位置會是一個很大的正值。這就是個很大的問題,這個問題是GetMouseButton和GetAxis在使用手指觸摸的情況下配合上的不默契產生的。但是使用Input.GetTouch(0).deltaPosition就不會有這種現象,個人猜測可能是因為deltaPosition是測量每一幀內的移動距離的方法吧。
      2. 如果使用 if(Input.touchCount>0&&Input.GetTouch(0).phase == TouchPhased.Moved)來做為判斷是否按下的條件: 
        使用Input.GetAxis(“Mouse X”),沒有任何問題; 
        使用deltaPosition同樣沒有任何問題,因為這就是為觸摸操作而設計的。

關鍵點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);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM