오-개) XR Interaction Toolkit Input

astray36·2021년 6월 14일
0

오늘의 개발

목록 보기
3/10

아직도 햇갈리는 부분이 있다. 인풋 시스템이 XR Interaction Toolkit Input에서 가져다 쓰는 건지 Open XR인지는 좀 더 알아봐야겠지만 어쨋든 인풋을 가져다 쓸때 아직 정규화된 인풋을 가져다 쓰는것은 어려운 것 같다. 결국 커스텀을 해서 써야할 듯 하다.

몇 가지 방법을 써보려고 시도중이다. 일단 기본적인 사용법은 이렇다.

inputDevice.TryGetFeatureValue(CommonUsages.secondaryButton, out bool buttonValue

저 inputDevice는 XRController 컴포넌트에서 가져오던지 Device컴포넌트에서 가져오던지 할 수 있는것 처럼 보인다. 어쨋든 업데이트 문에서 If문을 걸러 buttonValue를 디버깅해보면 프레임마다 눌렀을때 True, 땟을때 False 계속 반환한다. 그래서 결국 Input.GetButtonDown과 같은 기능을 편하게 사용하려면 코딩을 해야한다.

private XRController xrController;

bool rightHandLastState = false;
// Start is called before the first frame update
void Start()
{
    DontDestroyOnLoad(gameObject);
    rightHandLastState = false; // Assumed not held when starting game, while also initializing the value

    xrController = GameObject.Find("XR Rig").transform.GetChild(0).GetChild(2).GetComponent<XRController>();

}

// Update is called once per frame
void Update()
{

    if (xrController.inputDevice.TryGetFeatureValue(CommonUsages.secondaryButton, out bool buttonValue))
    {
        if (buttonValue != rightHandLastState)
        {
            // Button was pressed or released this frame
            // Do something with it here...
            // ... then make sure to set the last known state of it for reference next Update()
            if(rightHandLastState) // 버튼 때기
            {

            }
            else // 버튼 누르기 
            {
                LoadNextScene();
            }
            Debug.Log(rightHandLastState +  "Press!");

            rightHandLastState = buttonValue;
        }
    }
}

예시 코드인데 버튼을 누를 때마다 씬전환을 하는 코드이다.

어떻게든 하나만 누르면 되는 코드면 이렇게 쓰면되겠지만 전체적인 깔끔인 Input 관리를 하려면

using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.XR;
using UnityEngine.XR.Interaction.Toolkit;

public class XRInput : MonoBehaviour
{
#pragma warning disable 0649
    [SerializeField] XRController controller;
    [SerializeField] XRBinding[] bindings;
#pragma warning restore 0649

    private void Update()
    {
        foreach (var binding in bindings)
            binding.Update(controller.inputDevice);
    }
}

[Serializable]
public class XRBinding
{
#pragma warning disable 0649
    [SerializeField] XRButton button;
    [SerializeField] PressType pressType;
    [SerializeField] UnityEvent OnActive;
#pragma warning restore 0649

    bool isPressed;
    bool wasPressed;

    public void Update(InputDevice device)
    {
        device.TryGetFeatureValue(XRStatics.GetFeature(button), out isPressed);
        bool active = false;

        switch (pressType)
        {
            case PressType.Continuous: active = isPressed; break;
            case PressType.Begin: active = isPressed && !wasPressed; break;
            case PressType.End: active = !isPressed && wasPressed; break;
        }

        if (active) OnActive.Invoke();
        wasPressed = isPressed;
    }
}

public enum XRButton
{
    Trigger,
    Grip,
    Primary,
    PrimaryTouch,
    Secondary,
    SecondaryTouch,
    Primary2DAxisClick,
    Primary2DAxisTouch
}

public enum PressType
{
    Begin,
    End,
    Continuous
}

public static class XRStatics
{
    public static InputFeatureUsage<bool> GetFeature(XRButton button)
    {
        switch (button)
        {
            case XRButton.Trigger: return CommonUsages.triggerButton;
            case XRButton.Grip: return CommonUsages.gripButton;
            case XRButton.Primary: return CommonUsages.primaryButton;
            case XRButton.PrimaryTouch: return CommonUsages.primaryTouch;
            case XRButton.Secondary: return CommonUsages.secondaryButton;
            case XRButton.SecondaryTouch: return CommonUsages.secondaryTouch;
            case XRButton.Primary2DAxisClick: return CommonUsages.primary2DAxisClick;
            case XRButton.Primary2DAxisTouch: return CommonUsages.primary2DAxisTouch;
            default: Debug.LogError("button " + button + " not found"); return CommonUsages.triggerButton;
        }
    }
}

이런식의 코드를 사용해도 좋아보인다.

구글링하다 찾은 코드인데 사용해보고 사용성이 괜찮은지 확인해봐야겠다.

몇 가지 영상을 더 찾아보고 제일 좋은걸로 올려놓겠다.

profile
한줄로는 어렵다

0개의 댓글