일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Oculus
- meta
- 유니티 GUI
- 개발일지
- Photon Fusion
- 가상현실
- 멀티플레이
- 유니티 UI
- 연습
- HAPTIC
- ChatGPT
- 팀프로젝트
- VR
- input system
- 오큘러스
- 길건너 친구들
- 드래곤 플라이트
- CGV
- 오브젝트 풀링
- 포트폴리오
- 유니티 Json 데이터 연동
- 앱 배포
- 모작
- OVR
- XR
- meta xr
- 개발
- 팀 프로젝트
- 드래곤 플라이트 모작
- 유니티
- Today
- Total
EasyCastleUNITY
CGV 개발일지 4 (OVR Grab을 통해 잡은 물체를 통해 다른 물체 치기) 본문
CGV 개발일지 4 (OVR Grab을 통해 잡은 물체를 통해 다른 물체 치기)
EasyCastleT 2023. 11. 25. 12:37여태까지는, OVR에서 제공하는 기본적인 기능들을 사용하여 테스트를 했습니다.
이번 포스트에서는, OVR 을 활용하여, 조금 다른 기능을 구현해 보도록 하겠습니다.
바로 집은 물체를 통해, 다른 물체를 치는 기능 입니다. (ex 날아오는 공을 치는 야구방망이와 같은 기능)
OVR에서는 아주 기본적인 상호작용인, 잡는 것에 대한 기능은 충실히 구현되어 있습니다.
하지만, 그 잡은 물건이 다른 물체들과 상호작용 하는 것에 대한 기능은 거의 존재하지 않습니다.
이와 같은 경우, 이런 경우는 개발자가 직접 만들어야 하는 데 이 방법에 대한 R&D 과정과 해결 방법에 대해 작성해 보겠습니다.
R&D 이유
저희 프로젝트에서, 거인은 주변에 있는 나무나 돌을, 집어 인간측을 공격하거나, 인간측의 공격을 막습니다.
그러므로, 집은 물건을 통해 다른 물체를 치는 기능이 필요합니다. 하지만 ovr을 통해 Grab을 하면, 잡은 물체는 Kinemetic으로 움직이게 됩니다. 따라서, 잡은 물체로 다른 물체를 쳐도, 쳐지지 않고, 설령 리지드 바디의 Kinemetic이 비활성화상태라고 하여도 잡고 휘두르는 순간, 잡은 물체가 다른 물체를 그냥 통과하는 현상이 발생합니다. (터널링 현상)
그래서 이 기능에 대해 R&D 할 필요성을 느껴 해보게 되었습니다.
문제 파악
총 R&D 기간은 5일이었습니다.
그 중 문제 파악에 총 4일 정도를 할애하게 되었습니다.
1일차
1일차에는 미리 만들어 놓은 VR 환경에서 여러번 실행을 해보았습니다.
그 결과 잡은 물체가 빠르게 움직이는 순간 물체를 통과하는 것을 알 수 있었습니다.
<<통과하는 모습>>
위 동영상에서, 잡은 물체를 통해 다른 물체를 치려고 했을 때, 이렇게 통과하는 모습을 볼 수 있습니다.
1일차에는 빠르게 움직이면, 통과된다는 것을 알고 종료했습니다.
2일차
2일차에는 얼마나 빠른 속도로 움직이면, 물체를 통과하는 지와, 왜 빨라지면 통과하는 가에 대해 탐구하였습니다.
<<속도 느리게 하고 충돌 하는 모습>>
위 동영상에서,
1. 느리게 하면 제대로 충돌작용을 하며 물체가 밀려나는 모습을 볼 수 있습니다. (정상적인 충돌)
2. 하지만, 빨라지는 순간 충돌하지 않고, 그대로 통과하는 모습을 볼 수 있습니다. (비정상적)
3. 또한 공중에 떠있는 책상또한 콜라이더를 가지고 있는데, 잡은 물체는 그 물체와 물리적인 충돌작용을 하지 않고, 그대로 통과하는 모습을 보입니다. (잡는 물체가 isKinemetic 오브젝트처럼 취급대는 모습을 확인)
위의 3가지 특징에서 3번째 특징은, isKinemetic이기에 부딫치는 물체에도 리지드바디와 콜라이더가 있어야 한다는 점을 확인 할 수 있습니다.
그리고 왜 빨라지면 통과하는지 여러 번 직접 해보면서 탐구했지만, 이동방식 자체의 문제점이라고 어렴풋이 짐작할 뿐, 왜 이런 현상이 발생하는 지에 대한 근본적인 문제는 파악하지 못했습니다.
3일차
Auto Hand를 참고해 보기로 하였습니다. 1,2일차에서 만든 것들은 OVR SDK를 이용하여 만든 것입니다.
Auto Hand는 위에서 발생한 문제가 발생하지 않는 것을 확인하였습니다. 그리고, OVR SDK를 통해 만든 씬도 가지고 있기에 Auto Hand에서는 물체를 잡고 어떤 일이 벌어지는지에 대해 확인해보기로 하였습니다.
<<Auto Hand를 사용하여 잡고 치는 모습>>
위 동영상을 보면
1. 잡는 순간 Physics Material(No Friction, 마찰없음) 이 부착된다.
2. isKinemetic 처리가 되지 않는다.
3. 빠르게 움직여도, 제대로 물체를 치고 지나간다.
착안한 점은, OVR SDK의 Grabbable을 Auto Hand의 Grabbable로 대체한것 뿐임에도, 완전히 다르게 동작을 한다는 점이었습니다. 그래서, 잡는 순간 잡은 물체에 변화가 생기는 것이 아닐까 하는 생각을 하게 되어, 확인해본 결과,
콜라이더에 Physics Material이 붙는 것과, RigidBody의 Mass, Drag, Angular Drag가 변하는 모습을 확인했습니다.
그래서, 가장 큰 변화라고 할 수 있는 No Friction Physics Material을 만들어, 전에 만들어둔 잡는 물체에 부여했습니다.
위 사진과 같은 Physics Material을 만들어 휘두르는 물체에 부착하였습니다.
전과 비교하면, 물체를 통과하는 빈도가 줄어들었지만, 여전히 통과하는 문제가 발생하였습니다.
그래서, Rigidbody의 속성들의 수치도 조절하였지만, 똑같이 통과하는 문제는 계속 발생했습니다.
이렇게 AutoHand에서 변화되는 요소를 모두 적용해보았지만, 안 되는 모습에 많이 당황했습니다.
바뀐것은 Grabbable 하나임에도, 나오는 결과는 너무나도 달랐기 때문입니다.
그래서, 생각한 것이 바로, OVR SDK의 Grabbable과 Auto Hand의 Grabbable은 잡은 물체를 움직이는 방식이 다르다고 생각했습니다.
그래서, 확인 결과 OVR SDK의 Grabbable은 Lerp를 사용하고, Auto Hand의 Grabbable은 리지드 바디의 AddForce와 AddTorque를 사용하여 움직인다는 것을 알 수 있었습니다. 이 이동방식의 차이점을 염두해 두고 다음 4일차로 넘어갔습니다.
4일차
4일차에는 조금 관점을 바꾸어 보았습니다. 이렇게 물체를 통과하는 일이 가상현실에서만 일어나는 가?에 대한 것이었습니다. 그래서 기본적인 세팅을 가상현실이 아닌, 그냥 씬에서 돌아가도록 만들고 시험해보았습니다.
<<Rotate를 이용하여 물체 회전>>
위 영상은 Rotate를 활용하여, 회전한 물체가 물체를 쳐보는 모습을 확인해본 영상입니다.
위 영상처럼, 쳐지기는 하지만, 통과되는 것도 많다는 것을 확인할 수 있습니다.
그래서, 이 통과하는 현상이 가상현실에서만 생기는 것이 아닌, 유니티 자체적으로 생기는 문제라는 것을 알 수 있었습니다.
그래서 이런 현상을 구글링 해본 결과 터널링이라는 현상이라는 것을 알 수 있었습니다.
https://docs.unity3d.com/kr/2021.3/Manual/ContinuousCollisionDetection.html
위 두 링크를 참고하여 문제가 생기는 원인에 대해 알아보았습니다.
CCD에서 리지드바디의 Collision Detection 속성을 변경하는 방식으로 터널링을 해결할 수 있다고 하여 시도해보았습니다.
하지만, 가상현실 환경일 경우, 해결이 되지 않았기에 다른 방법을 찾아보았습니다.
다른 방법으로 보편적으로 터널링을 해결하는 방식이라고 나온 방법들을 시도해보았습니다.
터널링을 해결하는 방법으로는 이동함수를 호출하는 것을 FixedUpdate로 바꾸거나,
프로젝트 세팅의 Fixed Timestep을 감소하는 방법이 있습니다. 하지만, 위 두 방법 모두 가상현실에서 해보니 해결이 되지 않았기에, 새로운 방법을 찾아보기로 하고 4일차를 종료했습니다.
5일차
이동방식이 문제라는 것을 파악했기에, 이 이동방식을 변경할 방법에 대해 생각했습니다.
유니티에서는 오브젝트를 이동하는 것에 크게 2가지 방식으로 나뉘어집니다.
그 중 한가지 방식이 바로 Translate나 Rotate였습니다. 이 이동방식들은 우리 눈으로 보이기에는 연속적으로 움직이는 것처럼 보이지만, 현재 위치에서 이동할 위치로 순간이동하는 방식이었습니다. (프레임 사이에서)
그렇기에 빨리 움직이는 물체일 경우, 사이의 콜라이더가 있더라도 그냥 통과하게 되는 터널링 현상이 발생합니다.
다른 한 가지 방법으로 RigidBody의 Move 메서드를 활용하는 방법이 있습니다.
이 이동방법은 Translate와 Rotate와는 다르게, 현재 위치에서 이동할 위치로 빠르게 직접 이동하는 원리 입니다.
그렇기에 현재 위치와 이동할 위치 사이에, 콜라이더가 존재한다면 필연적으로 부딫치게 됩니다.
위 동영상은 리지드바디의 MoveRotation 메서드를 사용한 결과입니다. 좀 더 위의 다른 영상인 Rotate를 사용하여 회전한 결과와 차이가 크다는 것을 볼 수 있습니다.
따라서 해결방법은 이동방식을 리지드바디의 Move 메서드를 사용하면 된 다는 것을 알 수있었습니다.
하지만 문제가 있었습니다. 바로 이동하는 방식이 OVR SDK에서 제공하는 방식이라는 것이 문제였습니다.
따라서, 이 ovr sdk에 있는 이동방식을 직접 수정하는 방식은 좀 무리가 있었습니다.
그래서 생각한 방법이 바로, 이동하는 물체를 따라가는 리지드바디 Move로 움직이는 콜라이더를 만들어, 잡아서 이동하는 물체의 좌표와 회전 값을 받아, 이 콜라이더가 따라오게 하는 방법이었습니다.
이렇게 하면, 집어서 이동하는 물체를 콜라이더가 따라오게 되며, 이 따라오는 콜라이더가 물체를 치는 역할을 수행합니다.
아래 동영상은 잘 쳐지는 결과영상입니다.
이렇게 OVR Grab을 통해 물체를 치는 방법에 대해 알아 보았습니다.
'CGV(Castle Giant Virtual) 프로젝트 일지' 카테고리의 다른 글
CGV 개발일지 6 (멀티, 랜덤한 방 번호 만들기) (1) | 2023.11.29 |
---|---|
CGV 개발일지 5 (Throw Object 개선 하기) (0) | 2023.11.25 |
CGV 개발일지 3 (OVR 기능 활용하여 테스트) (1) | 2023.11.25 |
CGV 개발일지 2 (프로젝트 세팅) (1) | 2023.11.25 |
CGV 개발일지 1 (프로젝트 시나리오 설명) (1) | 2023.11.22 |