저번 시간에는 텔레포트를 구현해 보았습니다. 이번 시간에는 드디어 VR 게임 개발의 기본이 되는 오브젝트의 물리적 상호작용에 대해서 배워보겠습니다.
물리적 상호작용이라고 말했지만 물건을 잡고 놓는 것, 던지는 것, 충돌하는 것 등 당연히 적용되어야 하는 기본적인 것들을 오늘 해볼 것입니다.
우선 시작하기 전, 지난 시간엔 광선을 활용한 텔레포팅을 구현했습니다. 하지만 이 광선은 항상 켜져있기에 이번 시간에서 진행할 오브젝트와의 상호작용에 살짝 거슬릴 수도 있습니다. 따라서 광선을 필요할 때에만 눈에 보이도록 해주는 기능이 필요합니다.
저는 트리거 버튼 ( 텔레포트 할때 누르는 버튼 )을 누르고 있을 때 광선을 활성화시키고, 뗄 때 이동시키는 방식으로 만들어보겠습니다.
우선 그것을 위해 컴포넌트를 하나 만들어주어야 합니다.
하이라키의 XR Origin 오브젝트에 Add Component - New Script를 생성해주세요.
저는 이름을 Activate Ray로 바꾸어주었습니다.
자 그럼 이제 스크립트 안으로 들어가 코드를 짜보겠습니다.
먼저 활성화를 시킬 오브젝트를 public 변수로 받아야 합니다. ( 지금의 경우에는 광선이 되겠죠 )
그리고 오른쪽 트리거를 입력했는지 확인하는 방법이 필요한데, 아두이노의 아날로그 센서처럼 VR 컨트롤러에서 입력이 들어오면 값이 증가하는 변수를 만들 수 있습니다.
이 경우에는 InputActionProperty라는 유형의 변수를 사용할 수 있습니다.
메인 코드는 간단합니다.
만약 오른쪽 트리거 버튼이 눌렸는지 확인했다면, 광선을 활성화해주기만 하면 되는 것입니다.
SetActive함수를 통해 활성화시켜줄 수 있습니다. 마찬가지로 버튼을 뗄 때는 값이 0이 되므로, 자동으로 꺼집니다.
이것은 유니티만의 Update() 함수 안에서 코드를 작성하기에 가능한 일입니다.
그리고 반드시 XR Interaction Toolkit과 InpuSystem을 참조하는 것을 기억하셔야 합니다.
그럼 순서도를 작성해보겠습니다.
유니티만의 Update 함수의 특성 때문에 순서도를 어떻게 작성해야할지 잘 모르겠네요.. 우선은 이렇습니다.
코드를 보시면 이해가 되실겁니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit; // XR 인터렉션 툴킷을 사용합니다.
using UnityEngine.InputSystem; // 퍼블릭 변수 입력을 위한 입력관리 시스템을 사용합니다.
public class ActivateRay : MonoBehaviour
{
public GameObject RightTP; // 광선 오브젝트를 퍼블릭 변수로 입력받습니다.
public InputActionProperty RightActivate; // 오른쪽 트리거 버튼 입력을 받고 값을 읽기 위한 변수
// Update is called once per frame
void Update()
{
RightTP.SetActive(RightActivate.action.ReadValue<float>()> 0.1f); // 오른쪽 트리거 버튼의 입력값이 0.1f보다 크다면 오른쪽 텔레포트 광선 활성화
}
}
많아보이지만 제가 실제로 작성한 코드는 고작 다섯 줄입니다.
가장 처음 XR Interaction Toolkit과 InputSystem을 사용한다고 표시해주시고,
퍼블릭변수 2개를 받습니다.
다음 RightActive.action( 오른쪽 트리거 액션 )의 값이 0.1f( = 0.1 ) 보다 크다면 광선을 활성화해주면 됩니다.
이렇게 코드를 작성하셨으면 퍼블릭변수에 각각 해당하는 오브젝트를 넣어주시면 됩니다.
코드를 작성하시면 스크립트 밑에 퍼블릭변수 입력창이 이렇게 나오는데, Game Object 라고 쓰여져 있는 창에는
광선 오브젝트 ( Right Teleportation Ray )를 넣어주시고, InputActionProperty 즉 액션을 넣는 창과 똑같이 생긴 변수 창은
Use Reference를 활성화해주신 다음 나타나는 창의 오른쪽 동그라미 버튼을 눌러 " XRI RightHand Interaction/Activate " 를 선택해주시면 됩니다.
그럼 이제 잘 작동하는지 확인해보겠습니다.
원하는 대로 완성이 된 것 같습니다.
자 이제 본격적으로 오브젝트의 물리적 상호작용을 다루어 보겠습니다.
저희가 해야 할 것을 큰 순서로 나누면
- Interactor & Interactable 각각 설정하고 닿으면 색깔이 바뀌는 물체 제작
- Grab Interaction과 3가지 Movement Type에 대해 알아보기
부터 우선 해보겠습니다.
1. Object Interactor 설정하기
유니티에서 상호작용을 하기 위해서는 크게 Interactor와 Interactable의 2가지 개념이 필요합니다.
Interactor는 우리가 특정 오브젝트와 어떤 종류의 상호작용을 할 수 있게 도와주는 기능이고, Interactable은 개체가 상호작용할 수 있게 도와주고, 어떤 방법으로 응답할지 설정해주는 기능입니다.
우리가 했던 Teleporation으로 예를 들어 보면, Ray Interacor가 Interactor에 해당하고, Interactable은 Teleportation Area와 Teleportation Anchor에 해당합니다.
이번에도 역시 오브젝트와 상호작용하기 위해 오른쪽 컨트롤러와 왼쪽 컨트롤러에 XR Direct Interactor 컴포넌트를 추가해 주어야 합니다.
XR Direct Interactor는 우리 손 주변에 어떤 구역을 정해주면, 그 구역 안으로 들어온 오브젝트와 상호작용을 할 수 있도록 해주는 기능입니다.
우선 하이라키 창에서 Left Hand와 Right Hand를 동시에 선택해주시고, Add Component - XR Direct Interactor 컴포넌트를 추가하여 줍니다.
그 후 상호작용할 수 있는 구역을 결정해주기 위해 Add Component - Sphere Colider 컴포넌트를 추가해 주시고, 반경을 0.1로 설정합니다.
또한 이 콜라이더가 실제 오브젝트와 물리적 상호작용 ( 충돌 ) 을 일으키면 안되므로 Is Trigger을 체크하여 반경 안으로 들어왔을 때 신호만 보내주게 합니다.
설정을 마친 화면은 다음과 같습니다.
이제 잘 작동하는지 확인하기 위해서 Interactable( 상호 작용 가능한 개체 )을 만들어야 합니다.
간단하게 색깔이 변하는 큐브를 만들어 보겠습니다.
먼저 책상을 만들어 주기 위해 큐브를 하나 생성하고 , 적당하게 사이즈를 조절해 주세요.
또 Meterial을 하나 만들어 주어 색깔을 입히겠습니다.
다음으로 작은 큐브를 만들어 책상 위에 올리고, 마찬가지로 Meterial을 만들어 다른 색상으로 색을 입혀 줍니다.
저는 주황색으로 해보겠습니다.
또, 물리적 효과를 적용해야 하기 때문에 Rigidbody 컴포넌트를 추가해주세요.
그 후, Interactable을 추가해 주어야 합니다. Add Component - XR Simple Interactable 컴포넌트를 추가해 주세요.
이후 Interactable Events를 클릭하면 각 상호작용별로 취할 수 있는 이벤트들이 있습니다.
우선 Hover Entered / Hover Exited / Select를 눌렀을 때 액션에 +를 눌러서 추가하고 NoFunction을 Meshrenderer.meterial로 바꾸어 주세요.
이 동작의 의미는 Hover ( 콜라이더가 닿았을 때 / 나갔을 때 ) , Select ( 선택 버튼을 눌렀을 때 ) 가 행해졌을 때 지정한 Meterial로 바꾼다는 의미입니다.
저희의 경우는 Meterial을 바꾸어 색깔을 바꿔주는 것이므로, Hover Entered ( 콜라이더가 닿았을 때 ) / Hover Exited ( 콜라이더가 닿지 않았을 때 ) / Select ( 선택 버튼을 눌렀을 때 ) 의 색깔을 각각 지정하여 넣어주세요.
저는 각각 하얀색 / 주황색 / 하늘색으로 설정하였습니다.
그럼 실행시켜서 잘 작동하는지 확인해보겠습니다.
잘 작동하는 모습을 확인할 수 있습니다.
2. Grab Interaction
Grab Interaction ( 그랩 인터랙션 ) 은 말 그대로 잡는 상호작용을 의미합니다.
Unity VR에서는 매우 간단하게 그랩 인터랙션을 구현할 수 있습니다.
먼저 앞과 같이 큐브를 만들고, Add Component - Grab Interactable 컴포넌트를 추가해 줍니다.
아까 전의 Simple Interactable은 상호작용의 종류가 간단한 함수들이었다면, Grab Interactable은 잡는 것이 상호작용의 종류입니다.
이제 잘 작동하는지 확인해 보겠습니다.
이렇게 잡기는 매우 간단하게 구현할 수 있습니다.
하지만 하나 더 잡기에서 굉장히 중요한 요소가 있는데요, 바로 Movement Type입니다.
Movement Type은 말 그대로 물체를 잡고 있을 때, Rigidbody ( 물리 ) 시스템과 콜라이더를 어떻게 이동시킬지에 대한 종류입니다.
Movement Type에는 다음과 같은 3가지 종류가 있습니다.
Instantaneous | 프레임마다 오브젝트의 위치와 회전을 설정하고 업데이트하여 Interactable 개체를 이동하는 방식으로, 끊김 ( 렉 ) 을 방지하기 위해 사용하기 좋다. 그러나 물체가 Interactor에 의해 이동할 때 Rigidbody 없이 다른 콜라이더를 따라 이동할 수 있다는 단점이 있다. ( = 물리 시스템이 적용이 안될 수 있다 ) |
Kinematic | 운동학적으로 Rigidbody를 대상의 위치 및 방향으로 이동하는 방식으로 Interactable 개체를 이동시킨다. 시각적으로 오브젝트의 물리 시스템이 동기화된다. 그러나 물체가 Interactor에 의해 이동할 때 Rigidbody 없이 다른 콜라이더를 따라 이동할 수 있다는 단점이 있다. |
Velocity Tracking | Rigidbody의 속도와 각속도를 설정하여 추적하는 방식으로 Interactable 개체를 이동시킨다. 또, Velocity Tracking 모드의 장점은 Interactor에 의해 이동할 때에도 Rigidbody가 다른 콜라이더를 따라 이동할 수 없으며, 여전히 다른 요소와 상호작용한다. |
쉽게 말해 Instantaneous는 단순 물체의 위치와 회전 정보를 전달함으로써 콜라이더를 이동시키므로 물리적 효과의 적용이 느릴 수 있습니다. 또한, 손 ( Interactor ) 에 의해 이동할 때에도 다른 물체에 물리적 영향을 주지 않습니다.
Kinematic은 Rigidbody를 이동시킴으로써 한 물체가 이동할 때 다른 물체에 물리적 영향을 주지만, 손에 의해 이동할 때, Rigidbody가 없이 다른 콜라이더를 따라 이동할 수 있습니다.
Velocity Tracking은 Rigidbody의 속도와 각속도를 주고, Interactable을 추적하게 하여 모든 물체에 대해 물리적 상호작용이 가능합니다.
아직까지도 와닿는 차이를 느끼시지 못할 수 있습니다. 말이 정말 어려운데, 직접 작동을 확인해보며 차이를 알아보겠습니다.
우선 3종류의 큐브를 만들고, Movement Type을 각각 Instantaneous / Kinematic / Velocity Tracking으로 설정해줍니다. 구분을 위해 저는 각각의 색깔을 빨간색 / 노란색 / 파란색으로 설정하였습니다.
어떤 차이가 있나 확인해보도록 하겠습니다.
편집이 상당히 재밌네요
영상에 나온 대로, 물리적 상호작용의 질에 대해 차이가 있음을 알 수 있었습니다.
물리적 상호작용 1부는 여기서 마치고, Attach point부터 2부로 돌아오겠습니다.
5월 정융탐 과제는 이것으로 마치겠습니다.
감사합니다.
'정보융합탐구' 카테고리의 다른 글
[ Unity VR & 정보융합탐구 ] 05. 오브젝트의 물리적 상호작용 - (2) (3) | 2023.06.06 |
---|---|
정융탐 ] Diffusion Model과 GAN의 비교 (1) | 2023.05.30 |
정융탐 ] 3. 이공계체험학습 내용 정리 및 후기 (4) | 2023.05.16 |
정융탐 ] 2. 행렬곱 ( Matrix Multiplication ) (0) | 2023.05.11 |
[ 정융탐 ] 02. 손을 만들어보자 (1) | 2023.04.11 |