관리 메뉴

caLAB

[Htc Vive] VR 컨트롤러 binding / grab 인터렉션 본문

Unity/유니티VR

[Htc Vive] VR 컨트롤러 binding / grab 인터렉션

도이(doi) 2020. 6. 10. 11:32
728x90

Window > SteamVR Input에서 Grab키를 생성해주고

Open binding UI를 눌러서 설정을 아래와 같이 해줍니다.

 

인터렉션 스크립트를 작성합니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR;

public class grabInteraction : MonoBehaviour
{
    public SteamVR_Input_Sources handType;
    public SteamVR_Behaviour_Pose controllerPose; // controller info
    public SteamVR_Action_Boolean grabAction;

    private GameObject collidingObject;
    private GameObject objectInHand;

    private void Update()
    {
        //trigger 버튼을 누를 때
        if(grabAction.GetLastStateDown(handType))
        {
            if(collidingObject)
            {
                GrabObject();
            }
        }

        //tirgger 버튼을 놓을 때
        if(grabAction.GetLastStateUp(handType))
        {
            if(objectInHand)
            {
                RelaseObject();
            }
        }
    }

    public void OnTriggerEnter(Collider other)
    {
        SetCollidingObject(other);
    }

    public void OnTriggerStay(Collider other)
    {
        SetCollidingObject(other);
    }

    public void OnTriggerExit(Collider other)
    {
        if (!collidingObject)
            return;
        collidingObject = null;
    }

    //충돌 중인 개체로 체크 
    private void SetCollidingObject(Collider col)
    {
        //이미 충돌 중이거나 rigidbody를 가지고 있지 않은 경우 예외처리
        if (collidingObject || !col.GetComponent<Rigidbody>())
            return;
        collidingObject = col.gameObject;
    }

    //잡기
    private void GrabObject()
    {
        objectInHand = collidingObject;
        collidingObject = null;

        var joint = AddFixedJoint();
        joint.connectedBody = objectInHand.GetComponent<Rigidbody>();
    }
    //joint 추가
    private FixedJoint AddFixedJoint()
    {
        FixedJoint joint = gameObject.AddComponent<FixedJoint>();
        joint.breakForce = 20000;
        joint.breakTorque = 20000;
        return joint;
    }
    //놓기
    private void RelaseObject()
    {
        if(GetComponent<FixedJoint>())
        {
            GetComponent<FixedJoint>().connectedBody = null;
            Destroy(GetComponent<FixedJoint>());

            objectInHand.GetComponent<Rigidbody>().velocity =
                controllerPose.GetVelocity();
            objectInHand.GetComponent<Rigidbody>().angularVelocity =
                controllerPose.GetAngularVelocity();
        }
        objectInHand = null;
    }
}

 

스크립트를 cameraRig 하위에 있는 Controller(right / left)에 부착시켜줍니다.

그리고 handType은 각각 손 방향에 맞게 설정하고 나머지는 아래와 같이 세팅해줍니다.

그 후에 controller(right / left)의 컴포넌트로 rigidbody와 boxCollider를 아래와 같이 생성해줍니다.

rigidbody는 use gravity를 체크 해제, isKinematic 체크

BoxCollider는 Is Trigger 체크

그 후 인터렉션 할 GameObject에도 Rigidbody와 Collider를 추가해줍니다.

Collider는 Is Trigger의 체크를 해제하고

Rigidbody는 Is Kinematic을 해제해주세요.

Use Gravity는 중력의 물리를 사용하고 싶으면 사용하도록 합니다.

 

728x90
반응형
Comments