Notice
Recent Posts
Recent Comments
Link
12-25 13:16
«   2024/12   »
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
Tags
more
Archives
Today
Total
관리 메뉴

킹머핀의 제작 일지

VR) 유니티 XR Interaction Toolkit 응용 버그 수정 본문

Unity

VR) 유니티 XR Interaction Toolkit 응용 버그 수정

KingMUffin 2021. 5. 19. 17:59
 

VR) 유니티 XR Interaction Toolkit 응용 탐구

VR) 유니티 XR Interaction Toolkit 클래스 탐구 VR) 유니티 XR Interaction Toolkit 기본 탐구 VR) 유니티에서 오큘러스 퀘스트 샘플 씬 탐구 (feat. MacOS' tears) 우선 조작이 가능해서 탐구를 하든말든 하므로..

kingmuffin.tistory.com

버그가 생겼다. 드디어 완성한 줄 알았는데. 망할 쉽게 해결되어주질 않는다. ㅎㅎㅎ 됐고, 바로 고쳐보자.

  1. Snap turn 후 Fast Move 시 시작 위치가 달라지는 문제. 정방향을 기준으로 시작 위치를 계산한 문제로 추정.
  2. 오큘러스 퀘스트에 빌드 시 HMD를 기울여도 카메라 각도가 초기화되는 문제. 최대 프레임보다 낮은 프레임으로 초기화되고 있어서 HMD 기울기는 정상적으로 입력됨을 알 수 있음. 원인을 추정하지 못 함.

일단 2번부터 시도해보자. 그냥 내가 썼던 코드만 조금씩 지워보면 되니까. 머리 쓰는 건 이다음에.


내가 알기로는 내가 Fast Move와 Smooth Move 코드를 작성할 때 이용한 클래스가 모두 HMD가 아닌 컨트롤러 조작에만 관련이 있다. 그런데 어째서 HMD 회전 입력이 초기화되는 것일까.

우선 내 코드를 모두 비활성화하고 기존 코드로 대체해 다시 빌드 후 실행해보았다 그래도 해결되지 않았다. 음? 그럼 내 코드가 문제가 아니란 말인가? 내 코드 말고 추가했던 건.. XR Device Simulator 뿐이다. 하긴.. 이게 입력 처리를 한다면 오큘러스로 실행했을 땐 중복 입력일 테니 정상적으로 작동하지 않을 만하다.

그래서 저 프리팹을 제거하고 다시 테스트하니 문제가 사라졌다. 아니.. 그럼 메뉴얼에다가 적어놔야 할거 아냐..

{해결}


이제 오큘러스는 다시 벗어던지고, 다시 XR Device Simulator을 활성화해서 1번 문제를 해결해보자. (Shift 키를 누르고 A, D를 누르면 Snap turn이 가능하다.)

Snap turn은 (이제야) 처음 시도해보는데, 카메라가 아니라 최상위 오브젝트인 XRRig에 적용된다. 이 오브젝트가 회전하고, 자식 오브젝트인 카메라가 XRRig을 중심 축으로 회전했으므로 Snap turn 이전과 같은 (월드)좌표로 보정하기 위한 XRRig의 좌표를 계산해 적용한다.

Locomotion에서 카메라에 적용되는 위치나 각도는 없는 듯. 그렇다면 Snap turn 후에도 시작 위치가 같으려면 Snap turn으로 무엇을 계산했는지 알아야 한다.

/// 출처 : Unity XR Interaction Toolkit - XRRig.cs
/// 이 기능은 카메라를 원하는 WorldLocation에서 제공하는 세계 위치로 이동합니다.
/// 카메라의 세계 위치가 원하는 세계 위치와 일치하도록 리그 객체를 이동하여 이 작업을 수행합니다.
/// 카메라를 이동해야 하는 세계 공간에서의 위치
/// 이동이 수행된 경우 true를 반환합니다. 그렇지 않으면 false를 반환합니다.

public bool MoveCameraToWorldLocation(Vector3 desiredWorldLocation)
{
      if (m_CameraGameObject == null)
      {
      		return false;
      }

      var rot = Matrix4x4.Rotate(cameraGameObject.transform.rotation);
      var delta = rot.MultiplyPoint3x4(rigInCameraSpacePos);
      m_RigBaseGameObject.transform.position = delta + desiredWorldLocation;

      return true;
}

XRRig의 이동 함수에서도 카메라 각도로 매트릭스 계산을 해서 목표 지점에 더하는 코드를 볼 수 있다. 그렇다면 시작 위치를 이 코드와 똑같이 계산하면 해결되겠지만, 저 정체불명의 Matrix4x4 클래스를 찾을 수가 없......는 줄 알았는데 있다. UnityEngine 네임스페이스에 있는 struct다.

아니 그럼 왜 저 스크립트에서 볼 땐 아무 표시도 안 뜨는거야?! 또 패키지 폴더 어딘가에 숨어있는 스크립트라서 표시를 못 하는 줄 알았잖아! 패키지 폴더에 있는 스크립트는 UnityEngine 정보를 불러올 수 없나? 거 참 불편하네. 왜 자꾸 오해를 불러일으키는 거야. (맥에서만 이러나?)

그래도 매트릭스 계산을 내가 이해할 필요가 없어서 다행이다.

Vector3 startPoint = xrRig.rig.transform.position;
var rot = Matrix4x4.Rotate(xrRig.cameraGameObject.transform.rotation);
var delta = rot.MultiplyPoint3x4(xrRig.rigInCameraSpacePos);
startPoint = delta + startPoint;

이전 글에서 xrRig.rig.transform.position에다가 xrRig.cameraInRigSpacePos을 더했는데, 이제 카메라에 대한 좌표 계산을 저 복붙한 코드에 처리해줄 것이므로 지웠다. 잘 되는지 확인해보자!

안 된다. 뭐가 문제지? 아 생각해보니 MoveCameraToWorldLocation 함수의 인수로 보내면 똑같은 계산을 또 하는구나.

아 이번엔 startPoint랑 delta를 더하지 말고 빼볼까? (근본 없는 발상)

startPoint = startPoint - delta;

그랬더니 된다.

ㅋㅋㅋㅋ 이번엔 또 왜 됐지? 아 생각해보니 똑같은 계산을 한다면 그리고 그 계산 때문에 시작 지점이 달라진다면, 인수로 보내기 전엔 빼주고 보낸 후엔 더해주면 계산을 안 한 셈이 되잖아?

그렇게 해결. 이제 정말 문제 없겠지.

저렇게 중심축 회전 좌표를 계산하는 방법은 예전부터 궁금했는데, 나중에 알아보려고 이미 메모장에도 올려놨다. &