먼저 input을 설정하기 전에 Sample로 가서 어떻게 인풋을 받는지 확인해보자.
특정 인풋이 IA(인풋 액션) 에셋들에 묶여있고, 이런 IA 에셋들이 IMC에 묶여있는 것을 확인할 수 있다.
기기별로 들어오는 입력을 어떤 인풋 액션에 대응되는지 매핑 시켜준 것을 확인할 수 있다.
이렇게 구분지어 놓은 이유? 플랫폼마다 동일한 동작을 서로 다른 버튼을 눌러서 실행할 수 있으며, 똑같은 버튼이라고 하더라도 상황에 따라서 다른 액션을 실행하는 경우도 있어 이러한 인풋 액션들을 통합해서 관리하기 위해 Enhanced Input이라는 방식을 사용한다.
IA(인풋 액션)도 살펴보자
위와 같이 Value Type으로 입력에 따른 반환 값을 지정해 줄 수 있는데 입력 여부에 따른 두 가지 상태만 있는 것이 Boolean이고 입력 정도(조이 스틱이 움직인 정도)에 따라 -1에서 1사이의 값을 주는 것이 float이다.
Modifiers로 입력 값을 조정해 줄 수도 있다. 대표적으로 Deadzone의 경우 원하는 범위안의 입력만 받고 나머지 입력은 모두 받지 않는 기능을 구현할 수 있다.
현재 IA Move에서는 조이스틱을 움직인 정도가 0.7 ~ 1.0 사이로 움직여야만 입력의 반환 값을 받는다. 즉, 조이 스틱을 약하게 움직이면 IA_Move는 작동하지 않는다.
원래는 코드로 구현했던 부분을 이제 입력과 관련된 부분으로 통합시켜 관리할 수 있도록 해주었다.
이 BP는 기본 제공되는 에셋이 아님을 확인할 수 있는데 input 폴더에서 해당 에셋을 찾아서 어떤 기능을 하는지 확인해보자.
입력 값으로 부터 X를 0부터 1까지 Clamp 시킨 후 반환 시킨는 함수임을 알 수 있다. 즉, X를 Positive Only, 양수로만 넘겨주겠다는 함수임을 알 수 있다.
뒤로 이동하지 못하도록 X를 제한 두었다는 것을 알 수 있다. 실제로 VR Template에서의 텔레포트 방식의 이동은 뒤로 갈 수 없다.!
이러한 IMC가 여러개 존재함으로써 어떤 상황에는 Default를, 내가 무기를 꼈을 때는 어떻게 입력을, 내가 메뉴창을 켰을때는 어떻게 입력을 처리할지를 분리시켜 관리할 수가 있다.
기본 상태에서 조이스틱은 움직임(텔레포트)와 관련된 동작을 수행하는데, 메뉴를 키면 조이스틱은 커서를 움직이는 역할을 하게 된다.
VRPawn으로 가면 Add Mapping Context로 내가 진짜 사용할 시트를 정해주고 있는것을 확인할 수 있다. VRPawn의 begin play에서 IMC_Default와 IMC_Hands의 인풋 방식을 사용하고 있음을 알 수 있다.
이제 이런 방식을 사용하는 이유에 대해서 어느정도 이해했으리라 생각하는데, 게임이 커질 수록 어떤 상황에 어떤 입력을 어떤 기능에 매핑 시켜야하는지를 각각 매핑 시키면서 통합하여 관리함으로써 굉장히 편리하고 신속하게 인풋 액션을 변경할 수 있다는 장점이 생기는 것을 확인할 수 있다.
자세한 설명은 공식 문서를 참고하자
이제 분석한 정보를 토대로 Input을 한번 생성해보자. IA_VR_Move와 IA_VR_Turn 액션을 만들어준 후 초기 속성을 설정해준다.
이제 위에서 만든 액션들을 매핑 시켜주기 위해 IMC를 만들어보자. IMC_VR_Default라는 이름으로 IMC를 하나 만들어준다.
아래 사진과 같이 오큘러스 조이 스틱에 매핑 시켜주었다.
이제 BP_Pawn에 해당 IMC를 연결시켜보자.
시퀀스의 0번 핀이 위와 같이 Add Mapping Context 노드에 연결되어 IA_VR_Move와 IA_VR_Turn이 활성화 될 것이다. 이후에는 기존의 이벤트를 받아서 활용하는 방법과 동일하다.
W를 추가로 매핑시켜서 VR을 착용하지 않고 입력이 잘 되는지 테스트를 해볼 수 있다.
Started 떴다가 Trigger이 계속 뜨다가 땔 때 Completed가 뜨는 것을 확인할 수 있다.
이제 IMC 매핑이 정상적으로 잘 이루어졌고 입력 또한 정상적으로 들어온다는 것을 확인했으므로 입력에 따른 동작을 추가해보자.
Add Movement Input은 바로 노드를 움직이게 해주는 노드가 아니라, 내가 움직이고 싶다는 의사를 표기하고 저장해주는 노드이다. 실제로 움직이고 싶다면 Movement 컴포넌트를 추가해주어야한다. 따라서 FloatingPawnMovement를 추가해준다.
그러면 이제 우리가 넣어준 값을 Movement 컴포넌트에서 Consume 해서 가지고 온 다음에 해당 값을 Normalize해서 단위 벡터로 만든 후에 델타 T를 곱해주는 작업을 모두 수행해준다. (스피드도 Movement 컴포넌트에서 관리한다.)
좌표를 반환하는 기능을 하는 노드들에서 Relative라는 용어가 들어있지 않으면 월드 기준, 즉 글로벌 좌표이다.
이렇게 Add Movement Input와 Movement 컴포넌트를 이용한 이동의 구현은 추후에 카메라에 따른 이동을 구현하는데 있어서 굉장히 편리하게 구현할 수 있고, 굳이 직접 단위 벡터를 구하고 속도를 구하고 델타 T를 곱해주는 과정을 생략할 수 있다는 장점이 있다. 정말 쉽고 편리하고 빠르게 캐릭터의 이동을 구현할 수 있다.
이제 VR로 플레이를 하고 조이스틱을 작동하면 폰이 정상적으로 움직이는 것을 확인할 수 있다.