Unity PIco事件封装

发布时间 2023-12-06 13:41:09作者: SummerTrainnn
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.XR;
public interface IPicoKey<T>
{
    public void TryGetKey(PicoKeyEvent<T> picoKseyEvent, InputFeatureUsage<T> inputFeature);
}
public class PicoKeyEvent<T> 
{
    public UnityEvent<T> KeyDownEvent = new UnityEvent<T>();
    public UnityEvent<T> KeyPressingEvent = new UnityEvent<T>();
    public UnityEvent<bool> KeyUpEvent = new UnityEvent<bool>();

    public UnityEvent<bool> KeyAxisUpEvent = new UnityEvent<bool>();
    public UnityEvent<bool> KeyAxisDownEvent = new UnityEvent<bool>();
    public UnityEvent<bool> KeyAxisLeftEvent = new UnityEvent<bool>();
    public UnityEvent<bool> KeyAxisRightEvent = new UnityEvent<bool>();
    private XRNode m_node;
    private InputDevice m_InputDevide;

    private InputFeatureUsage<T> m_InputFeatureUsageValue;
    public  T m_Value;


    private bool Axis_2D = false;


    
    public bool isPressDown = false;
    public bool isPressing = false;


    public bool isUpPressDown = false;
    public bool isUpPressing = false;

    public bool isDownPressDown = false;
    public bool isDownPressing = false;
    public PicoKeyEvent(XRNode node, InputFeatureUsage<T> inputFeatureUsage)
    {
        m_node = node;
        m_InputDevide = InputDevices.GetDeviceAtXRNode(node);
        m_InputFeatureUsageValue = inputFeatureUsage;
        m_Value = default(T);
        Axis_2D = !m_Value.GetType().Equals(typeof(bool));
    }



    public void RegistButton()
    {

    }

    public InputFeatureUsage<T> GetFeatureUsage()
    {
        return m_InputFeatureUsageValue;
    }
    

    public XRNode GetXRNode()
    {
        return m_node;
    }

    public InputDevice GetInputDevide()
    {
        return m_InputDevide; 
    }

    public ref T GetRefValue()
    {
        return ref m_Value; 
    }

    public T GetValue()
    {
        return m_Value;
    }

以上是PIco事件基本的结构

 

 

using Pico.Platform.Models;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Resources;
using TMPro;
using Unity.VisualScripting;
using Unity.XR.CoreUtils;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UIElements;
using UnityEngine.XR;
using UnityEngine.XR.Interaction.Toolkit;
using static UnityEngine.XR.Interaction.Toolkit.XRRayInteractor;

[SerializeField]
public enum PicoSwapType
{
    North,
    South,
    West,
    East,
    None
}

public interface ISceneSetting
{
    public void LimitMoveAndTurnSnap(bool limitMove,bool limitSnapTurn);
}
public class GameManager : MonoBehaviour, IPicoKey<bool>, IPicoKey<Vector2>
{


    #region PicoEvent
    //=====================RIGHT HAND KEY EVENT=============
    public PicoKeyEvent<bool> R_GripBtn;
    public PicoKeyEvent<bool> R_TriggerBtn;
    public PicoKeyEvent<bool> R_PrimaryBtn;    public PicoKeyEvent<bool> R_SecondaryBtn;
    public PicoKeyEvent<Vector2> R_primary2DAxisBtn;
    public Action<PicoSwapType> R_OnSwapEvent;
    //=======================================================

    //=====================LEFT HAND KEY EVENT=============
    public PicoKeyEvent<bool> L_GripBtn;
    public PicoKeyEvent<bool> L_TriggerBtn;
    public PicoKeyEvent<bool> L_PrimaryBtn;
    public PicoKeyEvent<bool> L_SecondaryBtn;
    public PicoKeyEvent<Vector2> L_primary2DAxisBtn;
    public Action<PicoSwapType> L_OnSwapEvent;
    //=======================================================


    #endregion

    
    private void Awake()
    {
        InitPicoKeyEvent();
}
    void Update()
{
          UpdateCheckPicoKeyEvent();
}
    /// <summary>
    /// 更新事件状态
    /// </summary>
    public void UpdateCheckPicoKeyEvent()
    {

        TryGetKey(R_SecondaryBtn, CommonUsages.secondaryButton);
        TryGetKey(R_PrimaryBtn, CommonUsages.primaryButton);
        TryGetKey(R_GripBtn, CommonUsages.gripButton);
        TryGetKey(R_TriggerBtn, CommonUsages.triggerButton);
        TryGetKey(R_primary2DAxisBtn, CommonUsages.primary2DAxis);

        TryGetKey(L_SecondaryBtn, CommonUsages.secondaryButton);
        TryGetKey(L_PrimaryBtn, CommonUsages.primaryButton);
        TryGetKey(L_GripBtn, CommonUsages.gripButton);
        TryGetKey(L_TriggerBtn, CommonUsages.triggerButton);
        TryGetKey(L_primary2DAxisBtn, CommonUsages.primary2DAxis);
    }

    public void TryGetKey(PicoKeyEvent<bool> picoKseyEvent, InputFeatureUsage<bool> inputFeature)
    {
        if (picoKseyEvent.GetInputDevide().TryGetFeatureValue(inputFeature, out picoKseyEvent.GetRefValue()))
        {
            if (picoKseyEvent.GetValue())
            {
                if (!picoKseyEvent.isPressDown)
                {
                    picoKseyEvent.isPressDown = true;
                    picoKseyEvent.KeyDownEvent?.Invoke(true);
                }
                else
                {
                    picoKseyEvent.isPressing = true;
                    picoKseyEvent.KeyPressingEvent?.Invoke(true);
                }
            }
            else
            {
                picoKseyEvent.KeyUpEvent?.Invoke(true);
                picoKseyEvent.isPressDown = false;
                picoKseyEvent.isPressing = false;
            }
        }
        else if (!picoKseyEvent.GetValue() && (picoKseyEvent.isPressDown || picoKseyEvent.isPressing))
        {
            picoKseyEvent.KeyUpEvent?.Invoke(true);
        }
    }

    public void TryGetKey(PicoKeyEvent<Vector2> picoKseyEvent, InputFeatureUsage<Vector2> inputFeature)
    {
        if (picoKseyEvent.GetInputDevide().TryGetFeatureValue(inputFeature, out picoKseyEvent.GetRefValue()))
        {
            if (picoKseyEvent.GetValue() != Vector2.zero)
            {
                if (!picoKseyEvent.isPressDown)
                {
                    picoKseyEvent.isPressDown = true;
                    picoKseyEvent.KeyDownEvent?.Invoke(picoKseyEvent.GetValue());
                }
                else
                {
                    picoKseyEvent.isPressing = true;
                    picoKseyEvent.KeyPressingEvent?.Invoke(picoKseyEvent.GetValue());
                }
            }
            else
            {
                picoKseyEvent.KeyUpEvent?.Invoke(true);
                picoKseyEvent.isPressDown = false;
                picoKseyEvent.isPressing = false;
            }
        }
        else if (picoKseyEvent.GetValue() == Vector2.zero && (picoKseyEvent.isPressDown || picoKseyEvent.isPressing))
        {
            picoKseyEvent.KeyUpEvent?.Invoke(true);
        }
    }

    /// <summary>
    /// 初始化pico的按钮事件
    /// </summary>
    private void InitPicoKeyEvent()
    {
        R_primary2DAxisBtn = new PicoKeyEvent<Vector2>(XRNode.RightHand, CommonUsages.primary2DAxis);
        R_SecondaryBtn = new PicoKeyEvent<bool>(XRNode.RightHand, CommonUsages.secondaryButton);
        R_PrimaryBtn = new PicoKeyEvent<bool>(XRNode.RightHand, CommonUsages.primaryButton);
        R_GripBtn = new PicoKeyEvent<bool>(XRNode.RightHand, CommonUsages.gripButton);
        R_TriggerBtn = new PicoKeyEvent<bool>(XRNode.RightHand, CommonUsages.triggerButton);

        L_primary2DAxisBtn = new PicoKeyEvent<Vector2>(XRNode.LeftHand, CommonUsages.primary2DAxis);
        L_SecondaryBtn = new PicoKeyEvent<bool>(XRNode.LeftHand, CommonUsages.secondaryButton);
        L_PrimaryBtn = new PicoKeyEvent<bool>(XRNode.LeftHand, CommonUsages.primaryButton);
        L_GripBtn = new PicoKeyEvent<bool>(XRNode.LeftHand, CommonUsages.gripButton);
        L_TriggerBtn = new PicoKeyEvent<bool>(XRNode.LeftHand, CommonUsages.triggerButton);
    }