본문 바로가기
IT

[유니티/VR 콘텐츠 제작] 3. VR Controller와 상호작용 물체 만들기 + physics 개선하기 + URP Shader 기초 (움직이는 텍스처 만들기) + 물체끼리 상호작용 만들기

by 배애앰이 좋아 2024. 2. 6.
반응형

 

목표 : 유니티 VR 콘텐츠 제작하는 방법에 대해 알아봅시다.

 

https://www.youtube.com/watch?v=pm9W7r9BGiA&list=PLpEoiloH-4eM-fykn_3_QcJ-A_MIJF5B9&index=3

영상을 기반으로 작성된 글입니다.

사용한 유니티 버전 : 2022.3.16f
사용한 VR 기기 : meta quest 3

 

 

1. VR Controller와 상호작용 물체 만들기

 

아래 주소에 있는 오브젝트를 왼쪽, 오른쪽 controller 안에 넣고 충돌 크기를 조절합니다.

해당 오브젝트는 controller의 grab interaction 에 대해 제공합니다.

 

+ 그리고 테스트 중 scene 에 보이는 빛 같은 아이콘을 줄이고 싶다면 아래 버튼을 눌려서 3D icon slider bar를 줄여주면 됩니다.

 

그 다음, 상호작용할 cube prefab 을 한 개 꺼내고 다음과 같은 컴포넌트를 추가해줍니다.

 

그 이후 테스트 해보면, grab 할 때 해당 큐브 오브젝트가 잡히는 것을 확인할 수 있습니다.

 

아래 부분을 체크하게 되면 잡을 때 손 모양이 더 자연스러워집니다.

 

다만 테스트 해보면 충돌 처리와 물리적인 상호작용이 부자연스러운 것을 확인할 수 있습니다.

또한, 큐브를 잡고 테이블을 내리치면 뚫리는 것을 확인할 수 있습니다.

이를 개선해주기 위해 아래 부분처럼 바꿔줍니다.

 

 

2. physics 개선하기

 

collision Detection -> continue : 충돌 체크를 실시간 해줍니다.

movement type : velocity tracking : 마찬가지로 충돌에 대해 체크를 더 정밀히 해주도록 도와줍니다.

 

project setting -> time 을 영상에서는 90fps에 맞춰서 0.0111 로 설정해주었습니다.

 

project setting -> physics 에서 아래와 같이 바꿔줍니다.

 

테스트 해보면 전보다 더 자연스럽고 테이블에 안 뚫리는 것을 확인할 수 있습니다.

 

 

3. URP Shader 기초 (움직이는 텍스처 만들기) 

 

추가적인 상호작용 물체를 아래와 같이 만들어줍니다. 

 

위 우주 쓰레기를 담을 휴지통도 추가해줍니다.

 

아까 추가한 쓰레기 오브젝트도 위에서 상호작용 설정한 것과 같이 해줍니다.

 

너무 비어보이는 휴지통을 위해 빨려들어가는 효과를 추가해볼려고 합니다. 

아래와 같이 3d object quad 를 생성한 후 크기를 아래와 같이 맞춰줍니다.

 

아래 경로를 통해 shader graph을 추가해면,

 

아래와 아이콘이 뜨고 클릭 시, 아래 화면과 같이 뜹니다.

 

빈 화면에 오른쪽 키를 누르면 create node를 할 수 있고,

 

아래와 같은 이름을 검색해서 만들어줍니다.

 

아래 그림에 따라 create node 한 후 검색해서 만들어서 연결해줍니다. 

설정은 다음과 같습니다.

 

저장을 한 후, 해당 shader를 담은 material 를 생성한 후 아까 추가한 quad 오브젝트에 넣어주고

확인해보면 휴지통 그림이 바뀐 것을 확인할 수 있습니다.

 

아직 애니메이션이 없음으로 시간에 따라 움직이게 만들어봅시다.

마찬가지로 create node -> float 를 하며 아래와 같이 뜨는데,

 

해당 노드 위에서 오른쪽 마우스 키를 누르고 convert to > property 를 클릭해주면,

 

아래와 같이 매개변수처럼 만들어줄 수 있습니다. (왼쪽 상단에도 생성됨)

 

다음과 그림과 같이 수정해주고 연결해줍니다.

 

저장 후, 해당 material 을 보면 위에서 만든 매개변수가 나타나는 것을 확인할 수 있습니다.

 

+ 만약 애니메이션이 끊겨 보인다면 다은 버튼을 통해 always refresh 를 클릭해주면 테스트할 때 프레임이 안 끊겨 보입니다.

 

매개변수로 색깔 또한 받기 위해 아래와 같이 설정해줍니다.

 

마찬가지로 material 에서 수정할 수 있게 되고 색깔이 잘 바뀐 것을 확인할 수 있습니다.

 

여기서 안 끝내고 이미지의 가에 부분을 투명하게 만들어 봅시다.

아래와 같이 surface type 을 바꿔주면 아래와 같이 alpha 가 생성됩니다.

 

여기에 아래와 같이 설정해주고 (이미지는 직접 넣어줘야 합니다. )

 

확인해보면 옅어진 것을 확인할 수 있습니다. 

 

하지만 너무 옅어졌기에 이 알파 값 또한 조정하기 위해 아래처럼 만들어줍니다.

 

그럼 마찬가지로 material 에서 임의로 값을 바꾸면 테스트할 수 있습니다.

 

 

4. 물체끼리 상호작용 만들기

 

마지막으로 물체끼리 상호작용하게 만듭니다. 상호작용 방식은 쓰레기 통에 쓰레기를 버리면 없어지도록 할 것입니다. 먼저 쓰레기 통에 캡슐 오브젝트를 만들어주고 mesh 없애고 collider is Trigger 를 체크해줍니다.

 

그리고 아래와 같은 스크립트를 만들어 붙여줍니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class TriggerZone : MonoBehaviour
{
    public string targetTag;
    public UnityEvent<GameObject> OnEnterEvent;

    private void OnTriggerEnter(Collider other){
        if(other.gameObject.tag == targetTag){
            OnEnterEvent.Invoke(other.gameObject);
        }
    }
}

 

그 다음에 상호작용할 수 있게 우주 쓰레기 오브젝트에 태그를 변경해줍니다.

 

다시 쓰레기 통에 다음과 같은 스크립트를 생성하고 붙여줍니다.

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

public class TrashCan : MonoBehaviour
{
    private void Start(){
        GetComponent<TriggerZone>().OnEnterEvent.AddListener(InsideTrash);
    }

    public void InsideTrash(GameObject go){
        go.SetActive(false);
    }
}

 

그럼 총 2개의 스크립트가 붙여있습니다.

 

여기까지하면 쓰레기 통과 쓰레기의 상호작용은 끝났습니다. 

다만, 현재 오브젝트를 잡으면 현재 기계 손과 오브젝트가 같이 보여 던지기 불편합니다. 그래서 오브젝트를 집었을 경우, 기계 손이 안 보이도록 설정해줍니다.

 

아래와 같은 스크립트를 제작하는데 오류 뜨는 것을 살펴보면 어떤 매개변수를 받는지 확인할 수 있습니다.

 

최종 스크립트입니다.

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

public class DisableGrabbingHandModel : MonoBehaviour
{
    public GameObject leftHandModel;
    public GameObject rightHandModel;

    // Start is called before the first frame update
    void Start()
    {
        XRGrabInteractable grabInteractable = GetComponent<XRGrabInteractable>();
        // 객체를 잡을 때 이벤트 호출
        grabInteractable.selectEntered.AddListener(HideGrabbinghand);
        // 객체를 잡은 것을 놓을 때 호출
        grabInteractable.selectExited.AddListener(ShowGrabbingHand);
    }

    public void HideGrabbinghand(SelectEnterEventArgs args){
        if(args.interactorObject.transform.tag == "Left Hand"){
            leftHandModel.SetActive(false);
        }else if(args.interactorObject.transform.tag == "Right Hand"){
            rightHandModel.SetActive(false);
        }
    }

    public void ShowGrabbingHand(SelectExitEventArgs args){
        if(args.interactorObject.transform.tag == "Left Hand"){
            leftHandModel.SetActive(true);
        }else if(args.interactorObject.transform.tag == "Right Hand"){
            rightHandModel.SetActive(true);
        }
    }
}

 

위의 스크립트는 만들어 놓은 쓰레기 오브젝트에 붙인 후 각 오른쪽, 왼쪽 controller 를 아래처럼 넣어줍니다.

 

참고 아래 노란색 친 오브젝트들의 태그를 맞게 바꿔줍니다. (Right Hand or Left Hand)

 

그럼 테스트 결과, 오브젝트를 집으면 손이 없어지고 오브젝트를 손에서 떼면 잘 생성되는 것을 확인할 수 있습니다.

 

 

반응형

댓글