XR Interaction ToolKit Teleportation, Grab 분리

2022. 6. 26. 23:57Unity/VR

XR Interaction Toolkit에서 XRController의 컴포넌트 속성은 이렇게 된다.

여기서 우리가 지금 중점적으로 봐야하는 속성이 Select Usage이다.

 

왜 이 Select Usage가 문제냐면 이 속성이 Teleport시스템과 Grab시스템 두개에 적용되어서 어떠한 물체를 잡으려고 했을 때 Teleport가 동시에 발생되어 의도치않은 이동이 발생한다는 것이다. 

 

이 문제를 해결하는 방법은  내부 시스템을 다량 분석해 Select Usage와 Teleport 스크립트, XR Grab interactable 스크립트등을 고치는 것이 있다.

 

하지만 위의 방법은 너무 방대해 나는 다른 방법을 사용했다. 

 

생각해보면 나름 간단한 시스템이다. 코드를 한번 봐보자

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

public class XR_Interact_GrapAndMove_Support : MonoBehaviour
{
    private XRController left_Controller;
    private XRRayInteractor left_Interactor;
    private XRInteractorLineVisual left_InteractorLineVisual;
    // Start is called before the first frame update
    void Start()
    {
        left_Controller = GetComponent<XRController>();
        left_Interactor = GetComponent<XRRayInteractor>();
        left_InteractorLineVisual = GetComponent<XRInteractorLineVisual>();
    }

    // Update is called once per frame
    void Update()
    {    
        if (left_Controller.inputDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out Vector2 primary2D_TargetL))
        {
            if(primary2D_TargetL.y > 0.5f)
            {
                left_Controller.selectUsage = InputHelpers.Button.PrimaryAxis2DUp;

                left_Interactor.lineType = XRRayInteractor.LineType.ProjectileCurve;
                left_Interactor.velocity = 8;

                left_InteractorLineVisual.enabled = true;

                left_Interactor.raycastMask = 1 << LayerMask.NameToLayer("Terrain");


            }
            if(primary2D_TargetL.y == 0)
            {
                left_Controller.selectUsage = InputHelpers.Button.Grip;

                left_Interactor.lineType = XRRayInteractor.LineType.StraightLine;
                left_Interactor.maxRaycastDistance = 1;

                left_InteractorLineVisual.enabled = false;

                left_Interactor.raycastMask = 1 <<  LayerMask.NameToLayer("GrabAble");
            }
        }
        
    }
}

먼저 이동시스템은 Primary2DAxisUp으로 설정하고 그랩은 Grip으로 설정하려 했다.

 

 if(primary2D_TargetL.y > 0.5f)
            {
                left_Controller.selectUsage = InputHelpers.Button.PrimaryAxis2DUp;

                left_Interactor.lineType = XRRayInteractor.LineType.ProjectileCurve;
                left_Interactor.velocity = 8;

                left_InteractorLineVisual.enabled = true;

                left_Interactor.raycastMask = 1 << LayerMask.NameToLayer("Terrain");


            }

위의 코드의 내용은 이제 이동을 위해 Primary2DAxis의 상승이 감지 되면 이제 selectUsage가 PrimaryAxisUp으로 변환되어 해당 버튼으로도 텔레포트가 될 수 있도록 하게 했다. 부차적으로 원할한 이동을위해 라인타입도 커브로 변환해주고 거리또한 적당하게 설정해 주었다. 

또 이동지점을 보기위해 LineVisual도 켜주었다. 

 

레이어 마스크 부분은 PrimaryAxisUp이 감지될때 이동만 감지해야하는데 마침 Ray경로상에 다른물체가 있으면 그 물체를 잡아버릴테니 LayerMask를 Terrain만으로 할당해준 모습이다.

 

참고로 selectUsage의 Key할당은 이번에 내부 스크립트를 뜯어보면서 알게 되었는데  InputHelpers.Button.PrimaryAxis2DUp 이렇게 InputHelpers에서 거의 모든키를 관장하고 있었다. 그렇기에 오큘러스에 있는 버튼들을 할당할때에는 위 처럼 작성하면 된다.

 

if(primary2D_TargetL.y == 0)
 {
     left_Controller.selectUsage = InputHelpers.Button.Grip;

      left_Interactor.lineType = XRRayInteractor.LineType.StraightLine;
      left_Interactor.maxRaycastDistance = 1;

      left_InteractorLineVisual.enabled = false;

      left_Interactor.raycastMask = 1 <<  LayerMask.NameToLayer("GrabAble");
 }

위 코드또한 같은 맥락인데 primary2D가 감지안되었을 때에는 기본적으로 Grip으로 Grab을 담당해야하니 SelectUsage에 Grip을 할당하고 Grab을 하는데 적절한 속성을 넣어주었다. 물론 레이어마스크 할당도 같은 맥락이다.

 


시연

 

 

'Unity > VR' 카테고리의 다른 글

XR Interaction toolKit IndexTouch 인식 이슈  (0) 2022.06.30
Unity Shader 적용된 Material Property Runtime변경  (0) 2022.06.28
VR 캐주얼 FPS제작  (0) 2022.06.26
Unity 스킬 확장  (0) 2022.02.22
Unity 스킬 피격 처리  (0) 2022.01.15