Programming/UnrealEngine

[UnrealEngine5] F-18 전투기 날리기(1)-전투기 움직임 구현(Feat. TOPGUN:MAVERICK)

stein 2022. 7. 29. 00:34

프로젝트 게시글
[UnrealEngine5] F-18 전투기 날리기(1)-전투기 움직임 구현(Feat. TOPGUN:MAVERICK)🚩
[UnrealEngine5] F-18 전투기 날리기(2)-전투기 모델 적용하기(Feat. TOPGUN:MAVERICK)

[UnrealEngine5] F-18 전투기 날리기(3)-전투기 UI 구성하기(Feat. TOPGUN:MAVERICK)
[UnrealEngine5] F-18 전투기 날리기(4)(完)-미션 생성하기(Feat. TOPGUN:MAVERICK)

서론

 평소처럼 여기저기 치여 살던 나는, 친구의 강력한 추천으로, 탑건 1, 탑건:매버릭(이하 탑건 2)을 하루만에 다 보았다.

큰 기대를 하지 않았는데, 생각보다 담백하게 재밌는 탑건 1과, ScreenX에서 관람한 화려한 공중 액션신이 가득한 탑건 2는 예상외로 너~무 재밌었다.

탑건: 매버릭. 톰 형 왜 안늙어요

영화 내용중에 수행하기 매우 어려운 작전이 등장하는데(저고도, 시간제한, 정밀타격), 정말 관객이 이해하기도 쉽고, 영화에서 보여주기 좋은 난이도의 작전이라고 생각하면서, '저 작전을 게임(시뮬레이션)으로 만들 수 있지 않을까..?'라는 상상을 멈출 수가 없었다.

그리고 머리속을 문득 지나치는 unreal engine market store의 전투기 모델.

이게 무료라니. 애니메이션(리깅)까지 존재한다.

 이렇게 좋은게 있는데 안하고 지나가면 매우 섭섭하다. 시작해보자.

계획

1. Cube로 비행 움직임 구현(controller까지 받음)

    - 힘 방향 계산

    - 힘 적용

2. 움직임에 맞게, 기체의 rotation구현

3. cube를 F-18모델로 변경

4. F-18모델의 애니메이션을 추가(활성화)

 

진행

1. Cube로 비행 움직임 구현(controller)

- 힘 방향 계산

OpenWorld map. 능선도 보이고 좋다.

우선 조작할 대상을 cube로 생성하고, 추후 실제 모델로 교체하는 방식으로 진행한다.

 이 때, cube의 blueprint를 actor로 설정할지, pawn으로 설정할지 고민을 많이 했었다. 

당연히 조작할 actor니까 pawn으로 해야하지 않냐? 라고 생각이 들겠지만.. pawn에는 pitch각도 제한이 있기에 전투기의 화려한 기동을 못보여줄까 걱정이 되어, actor로 처음부터 구현과 pawn사이에서 고민중이었다. (물론 아직 unreal engine을 깊게 이해하지 못해서 생기는 고민일 수 있다.) 하지만 이번에는 add force를 이용하여, 정말로 물체에 힘을 전달하는 방식으로 이동할 예정이므로 사용이 좀 더 편한 pawn으로 결정했다!

 

이제 여기에 이동기능을 넣을 텐데, 일반적으로 add movement를 쓰는 것이 아니라 add Force를 사용하여, 진짜 시뮬레이션처럼 진행할 것이다.

이 친구의 존재를 최근에야 알게 되었다. (매번 구현했음..)

 위 컴포넌트를 쓰려면 Force(힘의 크기, 방향)과 Location(World 기준 좌표Target 기준 상대 좌표)가 필요하다. 기체의 각 부분에 힘이 발생할 수 있게 고려한다면 좀 더 사실적이겠지만, 우선 기체 중심에만 힘점이 존재하고, 이를 통해 상,하, 좌, 우, 그리고 앞쪽으로 이동하는 형태로 구현해보자.

 

 먼저 힘의 크기와 방향을 정해보자. 기체가 뒤로가는 힘을 받지는 않으므로, 기체 앞쪽으로 forwarding vector가 기본적으로 존재하고, 해당 벡터가 위/아래(pitch), 좌/우(yaw)로 각도가 틀어질 수 있음을 생각하면 되겠다. 힘을 나타낼 forwarding vector를 시각적으로 확인하기 위해서 arrow를 추가해주자.

귀엽다

그리고 wasd를 이용하여, 해당 벡터의 rotation을 변경시켜보자.

wasd로 움직이는 arrow
up(w), left(a)의 blueprint와 event tick마다 arrow rotate 코드

wasd를 누르면, forceUnitVector라는 roatator를 회전시키고, 이 벡터event tick마다 arrow를 roate하는 벡터가 된다.

그리고 위 gif에서 볼 수 있듯이, 현재 forwarding arrow가 뒤쪽으로도 넘어가기 때문에 각도에 제한을 주자.

 

빨리 C++코드로 짜고싶다..

블루프린트로 로직을 짜려니까 개인적으로는 너무 더럽다... 빠른 느낌도 있지만, 이럴 때는 답답함을 지울 수 없다.

우선 이제 rotation으로 인한 범위 에러는 모두 처리되었다. 이제 해당 벡터에 맞는 force를 추가해보자.

 

- 힘 적용

forwarding arrow로 부터 나온 vector로 cube에 force를 추가

add force at loctaion 컴포넌트로 cube에 힘을 추가할 수 있다.(add force at location local을 사용하면 cube가 빙글빙글 돌기만 한다)

날아간다~!

자 이제 움직이기 시작한다. 하지만 rotation이 없기 때문에 아무리 애를 써도 직진밖에 할 수 없는 상태이다.

이제 rotation을 추가해 기동범위를 늘리고 사실감을 추가해보자.

 

2. 움직임에 맞게, 기체의 rotation구현

- add relative rotation과 add force at location local을 이용한 기체 rotation

rotation은 힘 방향에 맞게 기체를 돌려주면 된다.

arrow의 y(가로)는 기체의 roll을, arrow의 z(높이)는 기체의 pitch를 변경한다.
조작이 꽤 어렵다. 그리고 set relative rotation의 pitch range에 걸리게 된다.

앞서 말했듯이, 아쉽게도 set relative는 pitch angle 제한이 걸려있다. 그래서 이 간단한 방법을 쓸 수가 없다..!

조작이 어려운.. 게 아니라 문제가아아아악

음.. 문제가 많다. 처음에 잘 기동하는가 싶더니, 조종자체가 불가능해진다. 그래서 이후로 이것저것 테스트 하기 위해서 force를 껐다 켤수 있게 만들었다.

엔진을 끄고 켤 수 있다.

~테스트 진행~

발견한 문제들

1. add force at location on local은 world 좌표계가 아니라 target을 기준으로 하는 relative 좌표를 넣어야한다.

2. 공기저항이 없어서 방향 전환시, 관성이 너무 엄청나다. 따라서 damping을 넣어 주었다.

3. pitch만 (add)set rotation으로 설정하기 힘드니, roll은 (add)set rotation을 사용해도 된다!

 

위 사항들을 통해 아래와 같은 코드를 만들었다.

기체의 회전을 담당하는 코드. Pitch는 add force at location local로, Roll은 add relative rotation으로 설정하였다.
(마찰)공기저항과 비슷하게 현상을 구현하는 damping

그리고 아무런 조작을 하지 않는다면, 기체가 현재 방향으로 계속 진행할 수 있도록, arrow의 rotation을 (0,0,0)으로 끌어당기는 코드를 추가하였다.

상/하, 좌/우 는 분리되어서 감쇄되어야 하므로 따로 구현해준다. 그리고 isXXXKeyPressed는 input action 부분에 set 함수를 추가해 주었다.

위의 코드들을 적용하고 기체를 조종해보았다!

상하(pitch) 회전, 좌우(roll) 회전
배면 비행 및 곡예 기동. 유후

꽤 잘 되고, 손맛도 적당하다! damping이나 엔진의 출력(Magnitude of Force)를 조금씩 수정할 필요는 있겠지만, 일단은 만족스럽다.

 

다음 단계들인

3. cube를 F-18모델로 변경
4. F-18모델의 애니메이션을 추가(활성화)

들은 디자인에 가까운 작업들이므로 다음 게시글에 이어서 작성하겠다.