更新說明下:今天我發現本文中設計的代碼有些bug,關於按下和擡起狀態的檢測只能監聽一次,關於解決方案,我會盡快補上,謝謝。php
使用暴風魔鏡作安卓VR開發,本身嘗試弄了一天,發現效果太差,主要是手柄輸入函數檢測不到,或者檢測的不靈敏。次日纔想起來百度,而後才發現暴風魔鏡官方已經提供了手柄SDK。連接地址http://bbs.open.mojing.cn/forum.php?mod=viewthread&tid=48&extra=page%3D1。html
好,以上就是原生的SDK,關於相機我就不說了,最要緊是把手柄函數給找到。開發文檔大概介紹了一下,在BaoFengZeemoteManager.cs中提供了按鍵的獲取事件,可以獲取到鍵按下和按鍵擡起的事件。算法
通過測試,阿亮發現瞭如下缺點:函數
1,提供的方法很差用,或者說根本沒有像Input輸入檢測那樣的函數:沒有實際意義的按下,一直按,擡起的直接獲取函數測試
2,不能同時多個按鍵的檢測(例如只能單方向行走,走的時候不能開火等)url
3,擡起鍵的檢測很差,例如同時按下了多個鍵,只能檢測其中一個是否擡起spa
其餘的不說,基本的按鍵事件不能正常使用,這個函數無異於雞肋。OK,既然原開發者不走心,那咱就走點心吧。設計
首先,要明確需求,就是爲了解決上面提到的三個問題。code
在解決這個問題以前,先來看看BaoFengZeemoteManager.cs是怎麼跑起來的,ZeemoteManager.cs是獲取事件的,而後把事件處理的結果傳遞個BaoFengZeemoteManager.cs,它主要有兩個函數,一個是獲取按下事件,另外一個是擡起事件。htm
public void ZeemoteUpBtn(string currentButton)//擡起的按鍵名稱 { state = "Button up: " + currentButton; //Message = currentButton; switch (currentButton) { case "OK": break; case "BACK": break; case "MENU": break; case "LEFT_BUTTON": break; case "RIGHT_BUTTON": break; case "UP_BUTTON": break; case "DOWN_BUTTON": break; case "CENTER_POSITION": break; case "A": break; case "B": break; case "C": break; case "D": break; }
}
public void ZeemoteDownBtn(string currentBtn)//按下的按鍵名稱 { state = "Button down: " + currentBtn; switch (currentBtn) { case "OK": break; case "BACK": break; case "MENU": break; case "LEFT_BUTTON": break; case "RIGHT_BUTTON": break; case "UP_BUTTON": break; case "DOWN_BUTTON": break; case "CENTER_POSITION": break; //如下爲老遙控器(一代遙控器)特有按鍵; case "A": break; case "B": break; case "C": break; case "D": break; }
}
OK,拿到這兩個函數怎麼用呢,直接用很難用,你總不能把輸入邏輯的處理放到這裏面來吧?還有,像Input.GetButton(name),Input.GetButtonDown(name),Input.GetButtonUp(name)的檢測輸入性函數也是沒有的,如何豐富這個雞肋呢?
算法這東西須要你分析邏輯關係的,咱們來看看如何處理這個邏輯:他們每次接收一個參數數值,同時更新掉上一個。針對同一個按鍵,這兩個函數是互斥的。
根據這個條件,以及咱們的需求,而後我想到了這個方案:一個按鍵有三個狀態:按下,一直按,擡起。用一個hashtable將按鍵和狀態存起來,執行ZeemoteDownBtn(string currentBtn)和ZeemoteUpBtn(string currentButton)時去調整狀態。其餘類調用檢測輸入時,去哈希表中去查它對應的狀態就好了。
更改以上的兩個函數以下:
public void ZeemoteUpBtn(string currentButton) { state = "Button up: " + currentButton; //Message = currentButton; switch (currentButton) { case "OK": break; case "BACK": break; case "MENU": break; case "LEFT_BUTTON": break; case "RIGHT_BUTTON": break; case "UP_BUTTON": break; case "DOWN_BUTTON": break; case "CENTER_POSITION": break; case "A": break; case "B": break; case "C": break; case "D": break; } SetAxis(currentButton,false);//調整按鍵的狀態 } private void SetAxis(string buttonName,bool isPress) {//擡起鍵和按下,一直按的事件是互斥的 ((Hashtable)table[buttonName])["up"] = !isPress; ((Hashtable)table[buttonName])["down"] = isPress; ((Hashtable)table[buttonName])["press"] = isPress; } private Hashtable table = new Hashtable(); public void ZeemoteDownBtn(string currentBtn) { state = "Button down: " + currentBtn; switch (currentBtn) { case "OK": break; case "BACK": break; case "MENU": break; case "LEFT_BUTTON": break; case "RIGHT_BUTTON": break; case "UP_BUTTON": break; case "DOWN_BUTTON": break; case "CENTER_POSITION": break; //如下爲老遙控器(一代遙控器)特有按鍵; case "A": break; case "B": break; case "C": break; case "D": break; } if ((bool)((Hashtable)table[currentBtn])["down"]==false) {//按下事件是一次性的,因此只有當down爲false時再更新 SetAxis(currentBtn, true); } if (currentBtn == AndroidInput.CENTER_POSITION.ToString())//這個是軸歸零時函數 { SetAxis(AndroidInput.LEFT_BUTTON.ToString(), false); SetAxis(AndroidInput.RIGHT_BUTTON.ToString(), false); SetAxis(AndroidInput.UP_BUTTON.ToString(), false); SetAxis(AndroidInput.DOWN_BUTTON.ToString(), false); } }
好,函數改好了,看看怎麼用:
public bool GetButton(string button) {//一直按狀態 return (bool)(((Hashtable)table[button])["down"]); } public bool GetButtonDown(string button)//按下的檢測 { bool isPress = (bool)(((Hashtable)table[button])["press"]); if (isPress && (bool)(((Hashtable)table[button])["down"])) { ((Hashtable)table[button])["press"] = false;//檢測過按下事件後,將其狀態清零 return true; } return false; } public bool GetButtonUp(string button)//檢測擡起按鍵事件 { bool isUp = (bool)(((Hashtable)table[button])["up"]); if (isUp) { ((Hashtable)table[button])["up"] = false;//檢測事後清零 return true; } return false; }
修改完畢,手柄能用了!
例如,按下MENU鍵,直接調用:
BaoFengZeemoteManager.Instance.GetButtonDown(AndroidInput.MENU.ToString());
一直按:
BaoFengZeemoteManager.Instance.GetButton(AndroidInput.MENU.ToString());
擡起:
BaoFengZeemoteManager.Instance.GetButtonUp(AndroidInput.MENU.ToString())
結尾來談一下第一人稱控制器,不要說這個多簡單,unity自帶什麼的,我知道,但是那是基於PC端有鼠標鍵盤的狀況,怎樣用手柄控制呢?
我爲何提出這個問題--相機。在PC端,用鼠標移動控制相機還有角色旋轉,這是最簡單不過了,但是,暴風魔鏡的相機旋轉是陀螺儀控制的,角色怎麼跟着旋轉呢?由於第一人稱的MouseLook是經過計算鼠標的XY偏移量來肯定角色的方位的,若是方位不正確,那麼角色的移動就不會以相機的正前方爲方向移動了。
我開始用相機的角度,來調整角色的旋轉角度,可是問題又來了:相機是基於角色的,旋轉角色,相機又跟着轉,好吧,具體的問題,你們能夠試試。
我解決了?那是固然。來看看圖吧。
最後是一個演示demo的apk,有暴風魔鏡的小夥伴們能夠試試,Menu鍵切換武器。OK鍵發射。連接: http://pan.baidu.com/s/1hqhFKCO 密碼: mf7q
原文連接http://www.cnblogs.com/jqg-aliang/p/4615029.html 轉載請申明出處,謝謝!
遊戲已更新:連接:http://pan.baidu.com/s/1dD8Q8RB 密碼:adwf,歡迎測試!