XR Origin (Action-based) 오큘러스 입력 받기

VR/XR Interaction Toolkit 2024. 1. 18. 16:30
반응형

 

https://docs.unity.cn/kr/current/Manual/xr_input.html

 

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;

public class InputManager : MonoBehaviour
{
    public InputDevice LeftControllerInputDevice { get; private set; }
    public InputDevice RightControllerInputDevice { get; private set; }

    public static InputManager Instance;

    private void Awake()
    {
        if (Instance == null)
            Instance = this;

        DeviceConnected(new InputDevice());
    }

    private void OnEnable() => InputDevices.deviceConnected += DeviceConnected;

    private void OnDisable() => InputDevices.deviceConnected -= DeviceConnected;

    private void DeviceConnected(InputDevice device)
    {
        var devicesL = new List<InputDevice>();
        InputDevices.GetDevicesAtXRNode(XRNode.LeftHand, devicesL);
        if (devicesL.Count > 0 && devicesL[0] != null && devicesL[0].isValid)
            LeftControllerInputDevice = devicesL[0];

        var devicesR = new List<InputDevice>();
        InputDevices.GetDevicesAtXRNode(XRNode.RightHand, devicesR);
        if (devicesR.Count > 0 && devicesR[0] != null && devicesR[0].isValid)
            RightControllerInputDevice = devicesR[0];
    }

    private void OnDestroy()
    {
        if (Instance == this)
            Instance = null;
    }

    public bool GetButtonPressed(InputFeatureUsage<bool> usage, InputDevice device)
    {
        if (device.TryGetFeatureValue(usage, out bool pressed))
            return pressed;

        return false;
    }

    public Vector2 GetAxis(InputFeatureUsage<Vector2> usage, InputDevice device)
    {
        if (device.TryGetFeatureValue(usage, out Vector2 axisValue))
            return axisValue;

        return Vector2.zero;
    }

    public static void TryHaptics(uint channel, float amplitude, float duration, InputDevice device)
    {
        if (device.TryGetHapticCapabilities(out HapticCapabilities capabilities))
        {
            if (!capabilities.supportsImpulse)
                return;

            device.SendHapticImpulse(channel, amplitude, duration);
        }
    }

    public void SmallHapticsPulse(bool left)
    {
        if (!left)
            TryHaptics(0, 0.5f, 0.25f, RightControllerInputDevice);

        if (left)
            TryHaptics(0, 0.5f, 0.25f, LeftControllerInputDevice);
    }

    public void MediumHapticsPulse(bool left)
    {
        if (!left)
            TryHaptics(0, 0.75f, 0.5f, RightControllerInputDevice);

        if (left)
            TryHaptics(0, 0.75f, 0.5f, LeftControllerInputDevice);
    }

    public void LargeHapticsPulse(bool left)
    {
        if (!left)
            TryHaptics(0, 1f, 0.75f, RightControllerInputDevice);

        if (left)
            TryHaptics(0, 1f, 0.75f, LeftControllerInputDevice);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;

public class Main : MonoBehaviour
{
    [SerializeField] private InputManager inputManager;

    private enum ButtonState
    {
        Pressed,
        Released
    }

    // Button States
    private ButtonState rightPrimaryButtonState = ButtonState.Released;
    private ButtonState leftPrimaryButtonState = ButtonState.Released;
    private ButtonState rightSecondaryButtonState = ButtonState.Released;
    private ButtonState leftSecondaryButtonState = ButtonState.Released;
    private ButtonState rightGripButtonState = ButtonState.Released;
    private ButtonState leftGripButtonState = ButtonState.Released;
    private ButtonState rightTriggerButtonState = ButtonState.Released;
    private ButtonState leftTriggerButtonState = ButtonState.Released;

    // 2D Axis States
    private Vector2 lastRightPrimary2DAxis = Vector2.zero;
    private Vector2 lastLeftPrimary2DAxis = Vector2.zero;
    private Vector2 lastRightSecondary2DAxis = Vector2.zero;
    private Vector2 lastLeftSecondary2DAxis = Vector2.zero;

    // Threshold for detecting significant change in 2D axis
    private const float axisChangeThreshold = 0.1f;

    private void Update()
    {
        // Define all the buttons and axes
        InputFeatureUsage<bool> primaryButton = CommonUsages.primaryButton;
        InputFeatureUsage<bool> secondaryButton = CommonUsages.secondaryButton;
        InputFeatureUsage<bool> gripButton = CommonUsages.gripButton;
        InputFeatureUsage<bool> triggerButton = CommonUsages.triggerButton;
        InputFeatureUsage<Vector2> primary2DAxis = CommonUsages.primary2DAxis;
        InputFeatureUsage<Vector2> secondary2DAxis = CommonUsages.secondary2DAxis;

        // Process each button and axis...
        ProcessButton(primaryButton, ref rightPrimaryButtonState, ref leftPrimaryButtonState, "primary button");
        ProcessButton(secondaryButton, ref rightSecondaryButtonState, ref leftSecondaryButtonState, "secondary button");
        ProcessButton(gripButton, ref rightGripButtonState, ref leftGripButtonState, "grip button");
        ProcessButton(triggerButton, ref rightTriggerButtonState, ref leftTriggerButtonState, "trigger button");

        Process2DAxis(primary2DAxis, ref lastRightPrimary2DAxis, ref lastLeftPrimary2DAxis, "primary 2D axis");
        Process2DAxis(secondary2DAxis, ref lastRightSecondary2DAxis, ref lastLeftSecondary2DAxis, "secondary 2D axis");
    }

    private void ProcessButton(InputFeatureUsage<bool> buttonFeature, ref ButtonState rightState, ref ButtonState leftState, string buttonName)
    {
        bool isRightButtonPressed = inputManager.GetButtonPressed(buttonFeature, inputManager.RightControllerInputDevice);
        bool isLeftButtonPressed = inputManager.GetButtonPressed(buttonFeature, inputManager.LeftControllerInputDevice);

        // Right Controller
        if (!isRightButtonPressed && rightState == ButtonState.Pressed)
        {
            rightState = ButtonState.Released;
        }
        else if (isRightButtonPressed && rightState == ButtonState.Released)
        {
            Debug.Log($"Right {buttonName} was pressed.");
            rightState = ButtonState.Pressed;
        }

        // Left Controller
        if (!isLeftButtonPressed && leftState == ButtonState.Pressed)
        {
            leftState = ButtonState.Released;
        }
        else if (isLeftButtonPressed && leftState == ButtonState.Released)
        {
            Debug.Log($"Left {buttonName} was pressed.");
            leftState = ButtonState.Pressed;
        }
    }

    private void Process2DAxis(InputFeatureUsage<Vector2> axisFeature, ref Vector2 lastRightAxis, ref Vector2 lastLeftAxis, string axisName)
    {
        Vector2 rightAxis = inputManager.GetAxis(axisFeature, inputManager.RightControllerInputDevice);
        Vector2 leftAxis = inputManager.GetAxis(axisFeature, inputManager.LeftControllerInputDevice);

        if (Vector2.Distance(rightAxis, lastRightAxis) > axisChangeThreshold)
        {
            Debug.Log($"Significant change in right {axisName}: {rightAxis}");
            lastRightAxis = rightAxis;
        }

        if (Vector2.Distance(leftAxis, lastLeftAxis) > axisChangeThreshold)
        {
            Debug.Log($"Significant change in left {axisName}: {leftAxis}");
            lastLeftAxis = leftAxis;
        }
    }
}

반응형
: