暴風魔鏡安卓手柄輸入檢測接口

  更新說明下:今天我發現本文中設計的代碼有些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,歡迎測試!

相關文章
相關標籤/搜索