오늘은 언리얼엔진5 or 4 에서 오브젝트를 회전시키는 방법에 대해서 알아보고자한다.
(이거 할려고 상당히 애먹었다)
<구현 픽쳐>
1. 한번에 N' 각도만큼 움직일 수 있는 오브젝트를 만든다.
2. 해당 오브젝트는 누군가와 충돌하거나, 누군가에게 피격당하거나, 무언가가 와서 부딛히거나 등의 다양한 조건을 줄 수 있다.
3. 해당 기능을 활용하여 기믹을 만든다. (이건 심화버전으로, 다른 글에서 연결해서 다루겠다/업데이트 됐다면 링크를 달아두겠다)
1. 블루프린트 액터를 생성한다.
- 만들어둔 부모 클래스는 없을것이므로 일반 액터 생성 버튼을 눌린다.
2. 이름은 아무거나 지어준다. (난 로테이션액터라고 지었다)
3. 블루프린트를 연다.
4. 액터에 큐브를 추가해넣는다.
5. 머티리얼을 기본을 사용해도 된다.
6. 이벤트 그래프로 이동한다.
7. 자, 첫 설계를 시작해야한다. 대부분 조건부터 설계를 시작할텐데, 필자는 아래의 흐름으로 설계를 하는걸 좋다고 생각한다.
- 머리속으로만 조건을 결정한다.
- 그래프는 먼저 "기능" 부터 만든다.
- 기능이 다 완료가 되면, 머리속으로 생각했던 조건들을 붙인다.
- 이후, 데이터 주도형 블루프린트로 설계할 수 있게 각종 변수들을 설정한다. (이건 기능 만드는단계에서 해도 좋다)
8. 그래서 우리는 Beginplay event 에서부터 시작한다. 이 액터가 게임에서 스폰되면 우리가 정한 "기능"을 바로 작동하도록 수정 할 예정이다.
들어가기 앞서 아래의 내용을 보고 기본 지식을 꼭꼭 씹고 만들면 좋다. (안다면 이 표를 쭉 넘기고 아래로 이동하라) |
대부분 로테이션을 시키려다 실수하는 현상
(복잡한 설명은 하지 않겠다)
1. Actor 의 Rotation 의 경우에는, 다른 Transform 값과는 다르게 음수가 존재하는 값이다.
- 360' 기준이 아니라, 양수180' + 음수 180' 로 구성되어있다.
2. 따라서, 다른 Transform 값들과 똑같이, 더해주거나, 빼주거나 하면서 만들면 아래와 같은 문제에 봉착한다.
- 0도에서 시작한 액터가 계속 값을 받으며 180도까지 달려간다
- 180도에 도달한 Rotation 의 값은 그 다음값이 -180' 로 바뀐다. (왜그런진 설명하지 않아도 될것같으니 궁금한 분은 찾아봐라. 아니면 그냥 그렇구나 하고 외우면 된다)
- 따라서, +주기만 하면 180' 를 찍고 뒤로 돌아서 내가 왔던 로테이션 경로를 다시 역행하는 현상이 생긴다.
3. 따라서 우리는 "선형 보간" 이라는 개념을 이용해서 해당 Actor 의 Rotatio 을 돌려야 한다.
- 이 정도의 개념만 알고 있으면, 나중에 위와 비슷한 현상을 발견하면 원인을 파악하기 쉬울거다.
4. 자 그럼 만들러 가보자.
9. 액터 Cube 의 상위 중점 씬 컴포넌트를 하나 만들어서 붙여준다.
10. Cube 가 가지고 있던 트랜스폼 정보를 전부 초기화 해준다.
11. 설치했던 씬 컴포넌트를 이벤트 그래프에 내려놓고, 컴포넌트의 월드 좌표를 구해온다.
12. 변해야 하는 축과, 변하지 말아야 하는 축을 구분하는데 사용할 예정이다.
13. 이제 씬 컴포넌트에서 가져온 Rotation 값을 담을 변수를 만든다.
14. 만든 변수를 set 할 수 있게 내려놓고, 똑같이 구조체 핀 분할을 해준다.
15. get 한 씬 로테이션(x,y,z) 과 가져온 Current Rotation 값(x,y,z 를 연결한다)
- 게임이 시작되어, 해당 액터가 스폰되면 이 BP 에 Scene Rotation 값을 Courrent Rotation 에 담는다.
16. 자 이제, 커스텀 이벤트를 하나 만들고, BeginPlay 이벤트 노드 흐름 마지막에 연결해준다.
17. 로테이션 값을 담을 수 있는 "로테이터" 변수 하나를 추가로 생성한다.
18. 사용하기 위해 배치한다.
19. 이제 이벤트 노드에서, Combine Rotators 라는 함수를 쓸 예정이다.
- 함수를 꺼내고, 아래와 같이 연결해준다.
20. 아래와 같이 연결한다.
- B값은 구조체 분리를 해줬다.
- 구조체 분리된 B값 중 X와 Y 값은 Get World Rotation 에서 가져온 값을 연결해줬다
- 난 z를 돌릴 예정이므로, z는 "일단 45' 로 설정했다"
- 이렇게 함수에서 리턴된 값을 17 에서 만들었던 Target Rotation 에 연결해줬다.
21. 자 이제 기본적으로 "돌릴 대상" 에 대한 값을 구해오는 작업은 끝났다. 이제 "시간" 에 따라 돌리는 노드를 추가해야 한다.
22. 타임라인을 추가해서, 이름을 아무렇게나 지어준다. (나는 "돌리자" 로 했다.)
(타임라인이 뭔지 모른다면, 타임라인 | 언리얼 엔진 문서 (unrealengine.com) 를 참고하자. 인자값 설명은 다되어있다.)
23. 타임라인을 열어서, Float 트랙을 추가해준다.
24. 아래와 같이 트랙 설정을 해준다. (시간은 빠르게 확인하기 위해 2초로 했다. )
25. 아래와 같이 노드를 설정해준다.
- 1번은 타임라인이 업데이트 될 때마다 Set World Rotation 을 갱신해주는 역할을 한다.
- 2번은 "보간" 함수이다. a값에서 b 값까지 alpha 값을 따라서 보간해준다.
- 3번은 타임라인이 끝날때, Curren Rotation(시작값) 을 Target Rotation(목표값)으로 설정해주며 마무리한다.
26. 플레이해보자.
- 설정 해둔 z 값 45' 로 정확하게 돈다.
여기까지 기본적으로 "목표 위치" 까지 보간하여 돌리는 행위는 끝났다.
다음은 "사용자 인터페이스 구성" 으로 심화 과정이다. 더 보고 싶다면 아래 게시글로 이동하자.