본문 바로가기

유니티/VR

[ VR ] DistanceGrab (먼 물건 잡기)

[ 개요]

[ 사전 설정 ]

ray를 통해 interaction한 물체를 잡고 , 컨트롤러의 트리거를 당길 경우 손의 위치로 오게 하려한다 .

사전에 [ VR ] 오큘러스 Interaction SDK < 02 . Tutorials > - ui와 상호작용하기를 통해

ray를 사용하는 컨트롤러를 생성한다 . 

주의 ) 오큘러스에서 제공하는 샘플씬과는 원하는 기능이 달라 약간의 변형이 있는점을 참고하여 주시면 감사하겠습니다:)

[ 컨트롤러 설정 ]

[ DistanceGrabHand프리팹 추가 ]

=>Left/Right Hand의 Anchor에 DistanceGrabHandLeft.Right프리팹을 추가한다 .

=>추가하면 DistanceGrabHandLeft에는OVR Grabber만 있을것이다 . 여기에 DistanceGrabber를 추가하고 ,

Grip Transform / Controller/OVECameraRig등을 인스펙터에서 채워준다 .

=>이때 , Grab Object In Layer를 통해 잡고자하는 물체의 Layer를 정할 수 있다 . 현재는 DEfault 레이어를 잡을 수 있다.

이 외의 레이어는 잡지 못 할 것이다 

=>원래 예제에서는 잡을 수 있는 범위에 있는지를 GrabManager의 SpereCollider에 들어가는지로 체크하였다 .

필요한 방식은 레이저로 인터렉팅한 오브젝트와의 상호작용이 가능하게 하는 것이므로,해당 기능을 사용하지 않는다.

위의 방식이 필요하다면 출처의 도큐먼트를 자세히 살펴보면 좋을 것 같다 .

 

[ GrabChecker 가능 여부를 판단하는 타겟처리 ]

[ GrabChecker ]

=>해당 오브젝트가 그립 가능한지에 대한 체크를 컨트롤러가 쏘는 레이에 맞았을때로 하고자 한다.

이를 위해 컨트롤러가 쏘는 레이저 끝에 dot를 설정한다 .

 

=>앞서 추가한 레이저의 RaycasterCursorVisual에 BoxCollider와 GrabChecker를 추가해준다 .

주의할점은 isTrigger가 체크 되어 있어야 한다 .

public class GrabChecker : MonoBehaviour
    {
        void OnTriggerEnter(Collider otherCollider)
        {
            DistanceGrabbable dg = otherCollider.GetComponentInChildren<DistanceGrabbable>();
            if (dg)
                dg.InRange = true;
        }

        void OnTriggerExit(Collider otherCollider)
        {

            DistanceGrabbable dg = otherCollider.GetComponentInChildren<DistanceGrabbable>();
            if (dg)
                dg.InRange = false;
        }
    }
}

=>스크립트는 간단하다 .충돌이 일어난다면 해당 DistanceGrabbable의 InRange를 True로 바꾸어준다 .

 

[ 잡고자 하는 대상 처리 ]

 

[ 상호작용 하고자 하는 물체에 Ray Interactable 추가 ]

  1. 상호작용 하고자 하는 오브젝트에  Box Collider  Collider Surface 를 추가한다 .
  2. Collider SurfaceCollider 에 위에서 추가한 Box Collider를 추가한다 .
  3. RayInteractable 스크립트를 추가한다 .이제 Ray 닿으면 이를 감지합니다.
  4. RayInteractable 스크립트의 Surface에 위에서 추가한 Collider Surface를 넣어준다 .

이제 물체는 Ray가 닿음을 감지 할 수 있고 , 위에는 컨트롤러의 타겟팅 도트가 보일 것이다 .

 

[ Distance Grabble을 추가해 먼 거리에서 Grab이 가능하게 한다 ]

다만 , GrabManager를 사용하지 않기에 해당 부분 관련은 주석을 쳐주고 사용한다 .

이상의 것들을 마무리 하면 ray가 닿는 곳에서 Grab이 가능하다 .

 

=>이때 , Snap Offset에 Transform 값이 있는 프리팹을 넣어주어 물체가 어떤 회전값 , 어떤 포지션으로 손에 
잡힐지를 결정할 수 있다 .

 

[ 트리거 변경 ]

 

[ 트리거 손가락 변경 ]

도큐먼트 : 컨트롤러에 관하여

위의 사진은 오큘러스의 컨트롤러의 명칭을 보여준다 .

현재 Grab은 PrimaryHandTrigger를 트리거 버튼으로 사용하고 있다 . 이를 변경하려면

OVRGrabber.cs의 174번줄의 OVRInput.Get의 대상을 변경해준다 . (174번줄)

 

[강제로 물건 놓기 ]

[ 물건 놓기 ]

잡은 물건을 강제로 놓아야 할 때가 있다, 이때 사용하는 메서드는 다음과 같다 .

OVRGrabber.cs

OVRGrabber.cs에 있는 ForceRelese 메서드이다 . 해당 메서드의 호출로 강제로 놓을 수 있다.

 

주의할점은 해당 메서드의 호출 이후 OVRGrabbable.cs의 GrabEnd에서 물건의 Rigidbody가 아래 명시된 값으로 세팅된다는 점이다.

OVRGrabbable.cs
OVRGrabbable.cs

=>이와 같이 사용이 가능하다 .

 

출처

오큘러스 도큐먼트 - Map Controllers

오큘러스 도큐먼트 -DistanceGrab Sample Scene