AR/VR/MR

VRTK 4.0 TouchPad 按下时怎么判断上下左右键?

2021-12-08  本文已影响0人  雨落随风

前言:

玩 VR 游戏时发现 Touch Pad 上下左右分别按下开启不同的功能的体验还真不错。
目前为止好像 VRTK 4.0 还没有整理这个上下左右按下的事件?
算了,考虑人家有没有整的空挡,都够自己整一个了,如下:


代码

using System;
using System.Linq;
using Tilia.Input.UnityInputManager;
using UnityEngine;
using UnityEngine.Events;
public enum TouchPadDirection
{
    Up = 0,
    Bottom = 2,
    Left = 1,
    Right = 3,
    None = 4, 
}
/// <summary>
/// 脚本用于判断你按下HTC vive TouchPad(上下左右)的哪一个区域了
/// </summary>
public class TouchPadClickEventDispatcher : MonoBehaviour
{
    [Header("Touch Pad 点击事件")]
    public TouchPadClickEvent OnTouchPadClicked = new TouchPadClickEvent();

    private void Start()
    {
        buttonAction.Activated.AddListener(OnButtonActionActived);
        //当按键抬起时报告 None 
        buttonAction.Deactivated.AddListener(v=>OnTouchPadClicked.Invoke( TouchPadDirection.None));
    }

    private void OnButtonActionActived(bool arg0)
    {
        var angle = Vector2.SignedAngle(new Vector2(1, 1), new Vector2(hr.Value, vt.Value));
        //带符号角度转换为 0°~360°
        angle += angle < 0 ? 360 : 0;
        //每 90° 的刻度划分一个方向,逆时针进行
        var dir = (TouchPadDirection)Mathf.FloorToInt(angle / 90);
        OnTouchPadClicked.Invoke(dir);
    }

    private void Reset()
    {
        var bts = GetComponentsInChildren<UnityInputManagerButtonAction>();
        var _1ds = GetComponentsInChildren<UnityInputManagerAxis1DAction>();
        buttonAction = bts.FirstOrDefault(v => v.name.Contains("Trackpad_Press"));
        hr = _1ds.FirstOrDefault(v => v.name.Contains("Trackpad_HorizontalAxis"));
        vt = _1ds.FirstOrDefault(v => v.name.Contains("Trackpad_VerticalAxis"));
        if (!buttonAction || !hr || !vt)
        {
            Debug.LogError("TouchPadClickEventDispatcher  挂载失败 \n 请挂载在 Input.UnityInputManager.OpenVR.RightController 或者 Input.UnityInputManager.OpenVR.LeftController");
            DestroyImmediate(this);
        }
        else
        {
#if UNITY_EDITOR
            UnityEditor.EditorUtility.SetDirty(this);
#endif
        }
    }
    [SerializeField, HideInInspector]
    UnityInputManagerButtonAction buttonAction;
    [SerializeField, HideInInspector]
    UnityInputManagerAxis1DAction hr;
    [SerializeField, HideInInspector]
    UnityInputManagerAxis1DAction vt;
    [Serializable]
    public class TouchPadClickEvent : UnityEvent<TouchPadDirection> { }
}

以下为测试事件的代码,挂载在场景任意空物体中,赋值即可测试使用

using UnityEngine;
public class TouchPadClickEventReceiver : MonoBehaviour
{
    [SerializeField]
    TouchPadClickEventDispatcher dispatcher;
    private void Start() => dispatcher.OnTouchPadClicked.AddListener(OnTouchPadClicked);
    private void OnTouchPadClicked(TouchPadDirection arg0)
    {
        switch (arg0)
        {
            case TouchPadDirection.Up:
                Debug.Log($"{nameof(TouchPadClickEventReceiver)}:  上 ");
                break;
            case TouchPadDirection.Bottom:
                Debug.Log($"{nameof(TouchPadClickEventReceiver)}:  下 ");
                break;
            case TouchPadDirection.Right:
                Debug.Log($"{nameof(TouchPadClickEventReceiver)}:  右 ");
                break;
            case TouchPadDirection.Left:
                Debug.Log($"{nameof(TouchPadClickEventReceiver)}:  左 ");
                break;
            default:
                 Debug.Log($"{nameof(TouchPadClickEventReceiver)}:  TouchPad 按钮松开了");
                break;
        }
    }
}

结语

上一篇 下一篇

猜你喜欢

热点阅读