zoukankan      html  css  js  c++  java
  • 暴风魔镜安卓手柄输入检测接口

      更新说明下:今天我发现本文中设计的代码有些bug,关于按下和抬起状态的检测只能监听一次,关于解决方案,我会尽快补上,谢谢。

      使用暴风魔镜做安卓VR开发,自己尝试弄了一天,发现效果太差,主要是手柄输入函数检测不到,或者检测的不灵敏。第二天才想起来百度,然后才发现暴风魔镜官方已经提供了手柄SDK。链接地址http://bbs.open.mojing.cn/forum.php?mod=viewthread&tid=48&extra=page%3D1。

      好,以上就是原生的SDK,关于相机我就不说了,最要紧是把手柄函数给找到。开发文档大概介绍了一下,在BaoFengZeemoteManager.cs中提供了按键的获取事件,能够获取到键按下和按键抬起的事件。

      经过测试,阿亮发现了以下缺点:

      1,提供的方法不好用,或者说根本没有像Input输入检测那样的函数:没有实际意义的按下,一直按,抬起的直接获取函数

      2,不能同时多个按键的检测(例如只能单方向行走,走的时候不能开火等)

      3,抬起键的检测不好,例如同时按下了多个键,只能检测其中一个是否抬起

     

      其他的不说,基本的按键事件不能正常使用,这个函数无异于鸡肋。OK,既然原开发者不走心,那咱就走点心吧。

      首先,要明确需求,就是为了解决上面提到的三个问题。

      在解决这个问题之前,先来看看BaoFengZeemoteManager.cs是怎么跑起来的,ZeemoteManager.cs是获取事件的,然后把事件处理的结果传递个BaoFengZeemoteManager.cs,它主要有两个函数,一个是获取按下事件,另一个是抬起事件。

      

    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,欢迎测试!

  • 相关阅读:
    mysql基础(三)存储引擎和锁
    为给定字符串生成MD5指纹
    区块链基本原理,Part-2:工作量证明和权益证明
    区块链基本原理,Part-1:拜占庭容错
    区块链挖矿 2.0
    以太坊 2.0 中的验证者经济模型,Part-2
    以太坊 2.0 中的验证者经济模型,Part-1
    Java归并排序之递归
    Python爬虫入门教程 64-100 反爬教科书级别的网站-汽车之家,字体反爬之二
    Java棋盘覆盖问题
  • 原文地址:https://www.cnblogs.com/jqg-aliang/p/4615029.html
Copyright © 2011-2022 走看看