[UE5][VR] Unreal Engine 5 VR Study (6)

suhan0304·2023년 12월 3일
0

Unreal Engine 5

목록 보기
6/10
post-thumbnail

시작하기에 앞서 기본 카메라의 높이를 높이기 위해 DrisedCameraHeight를 100으로 변경하고 시작하자.

Movement 수정

현재는 BP_Pawn을 기준으로 앞, 뒤로 움직이는데 실제로 우리가 바라보고 있는 방향, 즉 카메라를 기준으로 움직여야 자연스러울 것이다. 해당 로직을 수정해보자.

다음과 같이 카메라를 기준으로 Add Movement Input이 불러오도록 한다. 이렇게 하면 카메라를 기준으로 움직일 수 있게 된다.

z축 방향으로는 이동하고 싶지 않다. 즉, 카메라가 위를 보고 있다고 위로 이동하면 안 되므로 z축의 정보는 넘겨주지 않는다. ( 우클릭 후 split을 해주면 좌표를 하나씩 넘기고 받도록 할 수 있다.)


Grab 구현

이제 Grab을 하면 오브젝트가 잡히는 시스템을 구현해보자. 먼저 손에 잡히게 될 총 액터, BP_Gun을 만들어준 후 Skeletal Mesh를 하나 추가해준다. 그렇게 한 다음 Mesh Asset을 SK_FPGun으로 설정한다.

물건을 잡기 위해서는 두 가지가 먼저 필요하다.

1. 콜리전을 이용해 충돌 개념으로 물체가 있음을 인지(탐지)해야한다.
콜리전을 뭐를 선택하냐에 따라 효율성이 달라진다. 간단하게 Box Collision을 쓰면 아래 사진과 같이 단순하게 박스 형태로 Collision을 사용할 수 있으나, 박스 범위 안에만 들어가면 물건과 내가 접촉했다고 탐지하게 되므로 사실성은 좀 떨어진다. Mesh를 그대로 Collision으로 사용하게 되면 실제 Mesh 모양을 Collision이 만들어지지만 그러한 Collision을 만들고 사용하는데 필요한 연산량이 증가한다. 즉, 비효율적이다. 하지만 총에 내 손이 진짜로 접촉해야만 충돌했다고 탐지할 수 있으므로 사실성은 올라갈 것이다. 따라서 성능과 사실성을 잘 고려해서 Collision을 선택해야한다.

2. 물건을 잡을 때 손의 위치를 지정해줘야한다.
특정 물건의 경우에는 사용자가 어느 부분을 잡아도 손의 위치가 고정되도록 해줄 필요가 있다. 예를 들어 총이나 칼같은 오브젝트를 잡으면 손이 칼날을 잡고있거나, 총구를 잡고 있으면 부자연스러울 것이다. 자연스럽게 손이 총의 손잡이, 칼의 손잡이 부분을 잡도록 해야한다.

위의 두 가지 과정이 Grab의 과정에서 필요하다.


GrabComponent 생성

물체를 잡을 수 있다는 것을 어떻게 나타낼까? 정석적인 방법은 컴포넌트로 만들어서 이 컴포넌트를 가지고 있는 물건만 잡을 수 있다고 인지하는 방법이다. 그러므로 BP_Grab_Component라는 이름으로 Scene Component 블루프린트를 만들어준다.

부품 컴포넌트의 경우는 Actor Component와 Scene Comnponent가 있다.
Scene Component계층 구조를 가지는 컴포넌트
Actor Component기능만 가지는 컴포넌트이다.

BP_Grab_Component를 BP_Gun에 추가해주고 작업을 진행한다.

해당 컴포넌트의 위치를 조절해서 손의 위치를 지정해줄 수 있도록 구현할 예정이다.

그렇다면 어디서부터 그랩을 구현해야할까? 그랩이 언제 발생하는지부터 한 번 따라가 보자.

  • 가장 먼저 Grab 버튼을 누르면 Try Grab이 호출된다.

  • Try Grab에서 이제 손을 쥐는 애니메이션이 나온다.

이제 우리가 그랩을 구현할 위치를 찾았다고 할 수 있다. 그랩을 시도하는 TryGrab에서 물체를 잡으려고 시도를 할 때 작동이 되게끔 구현한다.


Grab 사전 설정

잡을 수 있는 물체를 찾는 함수를 만들어보자. 이때 이 함수는 결국 잡으려고 하는 물체의 BP_Grab_Component를 찾아야 하므로 반환 값도 BP_Grab_Component로 설정한다.

이 때 위에서 서술했던 Collision을 관리하기 위해 Project Settings > Collision에 Gimmick 채널을 새로 만들어준 후 Preset을 확인하면서 Trace Type을 적절히 수정한다.

  • GrabRadius의 초기값은 6으로 설정
  • BP_Gun의 SkeletalMesh는 Collision은 다음과 같이 설정

블루프린트에서 실제로 Gimmick 오브젝트에서 충돌 물체를 찾도록 구현했기 때문에 오브젝트 타입을 아까 만든 Gimmick으로 설정해야한다.

Generate Ovberlap Event : 두 물체가 충돌했을때 이벤트를 발생시킬지 말지 여부

  • 체크 해놓으면 추후에 해당 물체와 충돌 판정이 생겼을때 이벤트를 발생시켜 특정 기능을 실행 시킬 수 있다.

Grab BP

전체적인 모양

먼저 모션 컨트롤러의 월드 로케이션을 받아솨어 Local Grab Position이라는 지역변수에 저장해둔다.

해당 Grab Position을 기준으로 구체 형태로 탐색을 하는데 이 때 Gimmick 채널의 Collision을 가지고 있는 물체만 탐색을 한다. 반지름은 초기값 6으로 선언된 GrabRadius를 사용한다.

만약 충돌한 물체가 있다면 해당 물체에서 BP_Grab_component를 가져오고 만약 물체가 해당 컴포넌트를 가지고 있다면 해당 컴포넌트를 가져와서 LocalGrabComponent라는 변수에 저장해준다. 여기까지가 Pin 0 시퀀스 과정이다.

Pin 0 시퀀스 과정이 모두 끝나고 나면 LocalGrabComponent에는 Grab Component가 저장되어있으므로 해당 값을 리턴시켜준다.


TryGrab, TryRelease 이름 수정

TryGrab과 TryRelease의 이름을 HandleGrab과 HandleRelease로 바꿔준다. Grab 버튼을 누르면 핸들링만 진행하고 실제 try-grab, try-release는 grab_component 안에 넣어서 잡으려는 시도를 하는 기능을 구현하도록 한다.


HandleGrab BP

이제 핸들링을 시도를 했을때 물체 탐지를 가장 먼저 진행하도록 한다. 물체의 탐지여부를 Is Valid로 확인하고 물체가 탐지됐을때 Grab 과정을 해당 노드 다음 step에 구현하도록 한다.


Test

이제 BP_Gun을 배치해놓고 테스트 해보자

다음과 같이 Grab_Component가 있는 물체가 탐지되면 초록색으로 그려지고 없으면 붉은색으로 Trace Color가 그려진다.

만약 Trace 구체가 그려지지 않으면 Sphere Trace For Objects의 Draw Debug Type을 For Duration으로 바꾸도록 한다.

profile
Be Honest, Be Harder, Be Stronger

0개의 댓글