当前位置:   article > 正文

【Unity XR Input 获取Quest和Pico各个按键状态,按下、抬起、按下中】_unity picotrigger按下

unity picotrigger按下

Unity XR Input 获取Quest和Pico各个按键状态,按下、抬起、按下中

测试使用的是Unity2021.3.8和Quest2,只需绑定事件即可获取Quest各个按键状态,按下,抬起,按下中··

参考文档:
https://docs.unity3d.com/cn/current/Manual/xr_input.html
https://blog.csdn.net/Q540670228/article/details/123139150

使用以上代码时碰到些小问题(调试时获取不到设备,按钮冲突),部分内容做了修改

实现效果
在这里插入图片描述

全部代码
MonoSingleton.cs

using UnityEngine;

namespace Common
{
    ///<summary>
    ///脚本单例类,负责为唯一脚本创建实例
    ///<summary>
    public class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T> //注意此约束为T必须为其本身或子类
    {
        /*
        相较于直接在需要唯一创建的脚本中创建实例,Awake初始化的过程需要解决的问题
        1.代码重复
        2.在Awake里面初始化,其它脚本在Awake中调用其可能会为Null的异常情况
         */

        //解决1:使用泛型创建实例   解决2:使用按需加载(即有其它脚本调用时在get中加载)

        private static T instance; //创建私有对象记录取值,可只赋值一次避免多次赋值

        public static T Instance
        {
            //实现按需加载
            get
            {
                //当已经赋值,则直接返回即可
                if (instance != null) return instance;

                instance = FindObjectOfType<T>();

                //为了防止脚本还未挂到物体上,找不到的异常情况,可以自行创建空物体挂上去
                if (instance == null)
                {
                    //如果创建对象,则会在创建时调用其身上脚本的Awake即调用T的Awake(T的Awake实际上是继承的父类的)
                    //所以此时无需为instance赋值,其会在Awake中赋值,自然也会初始化所以无需init()
                    /*instance = */
                    new GameObject("Singleton of " + typeof(T)).AddComponent<T>();
                }

                return instance;

            }
        }

        private void Awake()
        {
            //若无其它脚本在Awake中调用此实例,则可在Awake中自行初始化instance
            instance = this as T;
            //初始化
            //Init();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

InputEvent.cs
//示例中此代码放到了XR Origin上面

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
/// <summary>
/// 提供各种输入事件
/// </summary>
public class InputEvent : Common.MonoSingleton<InputEvent>
{
    //*************输入设别**************************
    InputDevice leftHandController;
    InputDevice rightHandController;
    InputDevice headController;

    //**************对外提供公开事件******************
    #region public event

    public Action onLeftTriggerEnter;
    public Action onLeftTriggerDown;
    public Action onLeftTriggerUp;

    public Action onRightTriggerEnter;
    public Action onRightTriggerDown;
    public Action onRightTriggerUp;

    public Action onLeftGripEnter;
    public Action onLeftGripDown;
    public Action onLeftGripUp;

    public Action onRightGripEnter;
    public Action onRightGripDown;
    public Action onRightGripUp;

    public Action onLeftAppButtonEnter;
    public Action onLeftAppButtonDown;
    public Action onLeftAppButtonUp;

    public Action onRightAppButtonEnter;
    public Action onRightAppButtonDown;
    public Action onRightAppButtonUp;

    public Action onLeftJoyStickEnter;
    public Action onLeftJoyStickDown;
    public Action onLeftJoyStickUp;

    public Action onRightJoyStickEnter;
    public Action onRightJoyStickDown;
    public Action onRightJoyStickUp;

    public Action<Vector2> onLeftJoyStickMove;
    public Action<Vector2> onRightJoyStickMove;

    public Action onLeftAXButtonEnter;
    public Action onLeftAXButtonDown;
    public Action onLeftAXButtonUp;

    public Action onLeftBYButtonEnter;
    public Action onLeftBYButtonDown;
    public Action onLeftBYButonUp;

    public Action onRightAXButtonEnter;
    public Action onRightAXButtonDown;
    public Action onRightAXButtonUp;

    public Action onRightBYButtonEnter;
    public Action onRightBYButtonDown;
    public Action onRightBYButtonUp;

    #endregion

    //提供状态字典独立记录各个feature的状态
    Dictionary<string, bool> stateDic;

    private void Init()
    {
        if (!leftHandController.isValid)
        {
            leftHandController = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
        }
        if (!rightHandController.isValid)
        {
            rightHandController = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
        }
        if (!headController.isValid)
        {
            headController = InputDevices.GetDeviceAtXRNode(XRNode.Head);
        }
        stateDic = new Dictionary<string, bool>();

    }

    //*******************事件源的触发**************************
    /// <summary>
    /// 按钮事件源触发模板
    /// </summary>
    /// <param name="device">设备</param>
    /// <param name="usage">功能特征</param>
    /// <param name="btnEnter">开始按下按钮事件</param>
    /// <param name="btnDown">按下按钮事件</param>
    /// <param name="btnUp">抬起按钮事件</param>
    private void ButtonDispatchModel(InputDevice device, InputFeatureUsage<bool> usage, Action btnEnter, Action btnDown, Action btnUp)
    {
        //Debug.Log("usage:" + usage.name);
        //为首次执行的feature添加bool状态 -- 用以判断Enter和Up状态
        string featureKey = device.characteristics + usage.name;
        if (!stateDic.ContainsKey(featureKey))
        {
            stateDic.Add(featureKey, false);
        }

        bool isDown;
        if (device.TryGetFeatureValue(usage, out isDown) && isDown)
        {
            //Debug.Log("device:" + device.characteristics + "usage:" + usage.name);
            if (!stateDic[featureKey])
            {
                stateDic[featureKey] = true;
                btnEnter?.Invoke();
            }
            btnDown?.Invoke();
        }
        else
        {
            if (stateDic[featureKey])
            {
                btnUp?.Invoke();
                stateDic[featureKey] = false;
            }
        }
    }

    /// <summary>
    /// 摇杆事件源触发模板
    /// </summary>
    /// <param name="device">设备</param>
    /// <param name="usage">功能特征</param>
    /// <param name="joyStickMove">移动摇杆事件</param>
    private void JoyStickDispatchModel(InputDevice device, InputFeatureUsage<Vector2> usage, Action<Vector2> joyStickMove)
    {
        Vector2 axis;
        if (device.TryGetFeatureValue(usage, out axis) && !axis.Equals(Vector2.zero))
        {
            if (joyStickMove != null)
                joyStickMove(axis);
        }
    }

    //******************每帧轮询监听事件***********************
    private void Update()
    {
        if (leftHandController.isValid)
        {
            ButtonDispatchModel(leftHandController, CommonUsages.triggerButton, onLeftTriggerEnter, onLeftTriggerDown, onLeftTriggerUp);
            ButtonDispatchModel(leftHandController, CommonUsages.gripButton, onLeftGripEnter, onLeftGripDown, onLeftGripUp);
            ButtonDispatchModel(leftHandController, CommonUsages.primaryButton, onLeftAXButtonEnter, onLeftAXButtonDown, onLeftAXButtonUp);
            ButtonDispatchModel(leftHandController, CommonUsages.secondaryButton, onLeftBYButtonEnter, onLeftBYButtonDown, onLeftBYButonUp);
            ButtonDispatchModel(leftHandController, CommonUsages.primary2DAxisClick, onLeftJoyStickEnter, onLeftJoyStickDown, onLeftJoyStickUp);
            ButtonDispatchModel(leftHandController, CommonUsages.menuButton, onLeftAppButtonEnter, onLeftAppButtonDown, onLeftAppButtonUp);
            //JoyStickDispatchModel(leftHandController, CommonUsages.primary2DAxis, onLeftJoyStickMove);
        }
        else
        {
            Init();
        }
        if (rightHandController.isValid)
        {
            ButtonDispatchModel(rightHandController, CommonUsages.triggerButton, onRightTriggerEnter, onRightTriggerDown, onRightTriggerUp);
            ButtonDispatchModel(rightHandController, CommonUsages.gripButton, onRightGripEnter, onRightGripDown, onRightGripUp);
            ButtonDispatchModel(rightHandController, CommonUsages.primaryButton, onRightAXButtonEnter, onRightAXButtonDown, onRightAXButtonUp);
            ButtonDispatchModel(rightHandController, CommonUsages.secondaryButton, onRightBYButtonEnter, onRightBYButtonDown, onRightBYButtonUp);
            ButtonDispatchModel(rightHandController, CommonUsages.primary2DAxisClick, onRightJoyStickEnter, onRightJoyStickDown, onRightJoyStickUp);
            ButtonDispatchModel(rightHandController, CommonUsages.menuButton, onRightAppButtonEnter, onRightAppButtonDown, onRightAppButtonUp);
            //JoyStickDispatchModel(rightHandController, CommonUsages.primary2DAxis, onRightJoyStickMove);
        }
        else
        {
            Init();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180

使用示例
LeftHandButton.cs
//示例中此代码放到了LeftHand Controller上面

using UnityEngine;

public class LeftHandButton : MonoBehaviour
{
    private void Awake()
    {
        InputEvent.Instance.onLeftAXButtonUp += LeftAXButtonUp;
        InputEvent.Instance.onLeftAXButtonEnter += LeftAXButtonEnter;
        InputEvent.Instance.onLeftAXButtonDown += LeftAXButtonDown;
    }
    void LeftAXButtonDown()
    {
        print("左手柄A键按下中···");
    }
    void LeftAXButtonEnter()
    {
        print("按下左手柄A键");
    }
    void LeftAXButtonUp()
    {
        print("抬起左手柄A键");
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/779347
推荐阅读
相关标签
  

闽ICP备14008679号