寫在前面

繼續填坑了。這次是講手機端。

  1. 電腦端 [ 按我跳轉 ]
    1. 鍵盤按鍵控制 [ 上文內容 ]
    2. 滑鼠點擊控制 [ 上文內容 ]
  2. 手機端
    1. 觸屏控制 [ 上文內容 ] [ 按我跳轉 ]
    2. 手勢控制 [ 上文內容 ] [ 按我跳轉 ]
    3. 重力控制 [ 本文內容 ]
    4. 陀螺儀控制 [ 本文內容 ]

本文的限制:接上文,本文主要講在手機檢查操作的方法,至於之後執行的相關命令,讀者完全可大開腦洞。如果你有什麼好的想法,歡迎告訴我!

正文

重力和陀螺儀感應器是手機內建的感測器。這兩種感測器都可以檢測玩家手中手機的方向,比如:移動、轉動、搖晃手機等。

1 重力控制

在講解前,要先了解重力感測器(G-sensor)的工作原理。也有人會將其稱為加速感測器(Accelerometer),反正它們指的是同一個東西就是了。我們來看一張圖:

一般而言,手機的三個方向對應Unity中方向的關係如上圖所示。利用重力在三軸上的分壓進行判斷,比如:當手機豎立時,重力作用於Y軸,故得到Y等於-1;手機橫放時,重力作用於X軸,故得到X等於-1;手機平放於桌面上時,重力作用於Z軸,故得到Z等於-1。

所以我們可以得知,三軸方向的定義是根據遊戲畫面而定的,如不注意,便會影響控制的正確性。

要使用重力感測器,只需要用到Input.acceleration即可,可在代碼的Update中加入以下代碼

float x = Input.acceleration.x;
float y = Input.acceleration.y;
float z = Input.acceleration.z;
Debug.Log("("+x+" , "+y+" , "+z+")")

將它掛到Main Camera的屬性欄中,接下來你就可以接上手機來測試一下結果了。

試著將手機平放(畫面朝天),緩緩轉動手機,觀察三軸的數值變化,為了方便讀者進行測試,我畫了一個示意圖提供參考。

當手機向左傾斜,由於重力施加於X軸的負方向,因此X軸遞減;當手機向右傾斜,由於重力施加於X軸正方向,因此X軸遞增;同樣的道理,當手機向玩家傾斜,由於重力施加於Y軸的負方向,因此Y軸遞減;當手機向外傾斜,由於重力施加於Y軸正方向,因此Y軸遞增;

於是我們就可以運用方向感應器的X與Y值為遊戲物件施加力了。假設我們已經定義了一個叫做ball的滾球,並需要對Ball進行基於重力檢測的操作。

Ball ball; // pre-defined
...

那麼上文提到的代碼就可以改成這樣:

float x = Input.acceleration.x;
float y = Input.acceleration.y;
float z = Input.acceleration.z;
Vector3 force = new Vector3(x * 10.0F , 0.0F , y * 10.0F);
ball.forward(force);

因為x與y的值太小了,因此乘上10來讓操作的效果更明顯。實際上,這個值是可以預先設定的,比如說我們可以預先設定一個浮點數叫作speed,每次需要用到便調用speed,這樣也方便日後修改。

2 陀螺儀

陀螺儀(Gyroscope)的用處在測量手機的相對移動距離,因此不要把它和重力感測器搞混了。首先,重力感測器沒辦法準確測出旋轉的角度。

你可能就覺得,不對啊,我們不是學過什麼cos,sin什麼的數學公式嗎?我們只要知道手機在移動的同時,各個軸的移動差不就可以算出角度了嗎?

沒錯,重力感測器確實可以做到這一點,但是某些情況下它並不奏效。比如,如果讀者把手機放在桌上,然後原地旋轉手機,你就會發現重力感測器的數值並不會改變。這是因為重力只會對單個軸施加影響,如果手機被旋轉,另外兩個軸並不受重力影響。看圖

以上述方法旋轉所得到得值一樣

以上就是重力感測器無法檢測或會受到影響得情況。另外,如果讀者想學習關於陀螺儀的控制方法,則必須將項目輸出為手機安裝檔,e.g. apk檔案,並將其傳入手機安裝後才能啟用。Unity的編譯環境無法調用直接陀螺儀。

接下來的例子給一個簡單的例子,首先需要開發人員自行檢測手機是否有提供陀螺儀的功能,如有才開啟陀螺儀的輸入檢測功能,否則告訴用戶該換手機了。接著我拿移動一個小球為例子,解釋可以如何使用陀螺儀的輸入值。

Ball ball;
bool isHasGyo = false;
GUItext infoMsg;
float x;
float y;
float z;
Vector Force;

void Start(){
if (SystemInfo.supportsGyroscope){ // 檢查手機是否有提供陀螺儀功能
Input.gyro.enabled = true; // 啟用陀螺儀
isHasGyro = true;
infoMsg.text = "Using Gyroscope";
}
else{
infoMsg.text = "Not using Gyroscope";
}
}

void Update(){
if (isHasGyro){
x = Input.gyro.attitude.x;
y = Input.gyro.attitude.y;
z = Input.gyro.attitude.z; // 讀取陀螺儀的值
infoMsg.text = "Using Gyroscope : "+ x +" , "+ y +" , "+ z;
force = new Vector3(-x * 10.0F , 0.0F , -z * 10.0F);
}
ball.forward(force);
}

Unity - Scripting API: Input.gyro?

docs.unity3d.com圖標

關於Input.gyro的使用方法在文檔里可以詳細閱讀。在速度的選擇方面,使用了10F來讓陀螺儀的變化更明顯,讀者可自行設計速度等輸出相關參數。

至於Input.gyro.attitude這個數據,如果讀者直接調用,那麼返回的將會是一個Quaternion(四元數)類型。熟悉Unity的小夥伴都知道,這是處理旋轉常用的一種數據類型。

四元數是一種比較複雜的數學概念,還有一些旋轉相關的處理方式比如矩陣旋轉歐拉旋轉,篇幅關係就不延申講了。四元數本質上一種高階複數,用以描述四維空間。與複數的二維空間不同。一個複數由虛實兩部分組成,體現為 x = a + bi,其中 i 為虛數單位,亦或根號-1。四元數與複數二維空間相對類似,不同在於它擁有三個虛數單位,i、j、k,函式體現為q = w + xi + yj + zk

嘛這些公式看看就好了,四元數的概念過於複雜,幾乎可以用一章的時間來講。要更加理解四元數,我們還需要大量的數學知識和基礎。然而即使你不知道原理,也並不妨礙我們使用Unity。在Unity裡面,transform組件擁有一個rotation的變數,它的類型就是四元數。Unity有提供對應的方式來進行四元數的處理,比如Quaternion.Euler函數,和Quaternion.eulerAngles參數,它們基本可以滿足絕大多數的四元數旋轉變換。

而陀螺儀也因此可以很好地對旋轉進行處理,比如在Update裡面可以寫這麼一句:

transform.rotation = Quaternion.Slerp(transform.rotation, Input.gyro.attitude, 5.0F);

Quaternion.Slerp?

docs.unity3d.com圖標

順帶一提,如果讀者需要測試IOS遊戲,那麼則需要在Xcode開發環境進行編譯輸出。


推薦閱讀:
相关文章