새소식

Unreal Engine/이론 | 로직 | 연습

[UE4/Theory] 004.캐릭터에게 생명을(공격, 점프 구현)

  • -

!!! NOTICE !!!
이 글은 언리얼의 기본 이론 등을 다루고 있습니다!
학습한 정보를 제가 기억하고 추후에도 사용해두기 위해 기록해둔 내용입니다!
이 점 유의하고 봐주세요!


Mixamo나 마켓플레이스에서 3D모델을 FBX 파일로 가져오면
언리얼에서 그대로 사용할 수 있다.
애니메이션 역시 사용이 가능하다.

이번에 해볼 것은 Import한 3D 모델과 애니메이션을 이용하여
공격과 점프를 구현할 것이다.

참고로 공격은 애니메이션만 구현할 것이다.
적을 공격하고 데미지를 주는 메커니즘은 다루지 않는다.


캐릭터(플레이어) 공격

캐릭터 공격 애니메이션을 사용하기 위해서 애니메이션 몽타주를 사용할 것이다.  

애니메이션 몽타주는 하나의 애셋에 들어있는 애니메이션을 합쳐
선택적으로 재생할 수 있도록 해주는 유연한 툴이다.

출처: 언리얼 엔진 문서
https://docs.unrealengine.com/ko/Engine/Animation/AnimMontage/index.html

 

애니메이션 몽타주

Animation Montage, 애니메이션 몽타주는 하나의 애셋에 들어있는 애니메이션을 합쳐 선택적으로 재생할 수 있도록 해주는 유연한 툴입니다.

docs.unrealengine.com

몽타주의 사전적 의미를 보면
'복수(複數)의 상(像)이나 장면을 합성(合成)하여 하나의 화면으로 만드는 일'이라고 한다.

예를 들어, 현재 캐릭터는 스테이트 머신(State Machine)을 통해
서있는 애니메이션 ~ 뛰는 애니메이션으로 흘러가도록 구성되어 있다. (앞게시글 확인)
이때, 플레이어가 공격버튼을 클릭하면 공격하는 애니메이션이 실행되어야 한다.

이때, 스테이트 머신에 스테이트를 추가하지 않고 공격하는 애니메이션이 실행되게 하려면
그 애니메이션은 애니메이션 몽타주 형태이어야 한다.
그러면 마치 애니메이션 클립처럼 자연스럽게 실행될 것이다.

우리는 앞에서 임포트한 애니메이션 클립들로 몽타주를 사용해 볼 것이다.
콘텐츠 브라우저에서 기존 캐릭터의 공격 애니메이션을 찾아 우클릭으로 애니메이션 몽타주를 만들어보자.
경로 : Content/Mesh/Animations/sword_and_shield_slash

상단의 필터에서 검색하면 빠르게 찾을 수 있다.
해당 애니메이션 마우스 우클릭/Create/Create AnimMontage 클릭으로 몽타주 생성
생성된 애니메이션 몽타주. *표시가 떴다면 저장이 안됬다는 의미.
애니메이션 몽타주를 열어보면 몽타주 그룹 명이 DefaultGroup으로 되어있는 걸 확인할 수 있다.

이제 인게임에서 마우스 좌클릭 할 때마다 생성된 애니메이션 몽타주를 실행하도록
블루프린트를 만들어 줄 것이다.

기존에 만들어 두었던 MoveCharBP 블루프린트를 열어서
Left Mouse Button 노드, Play Anim Montage 노드를 통해
애니메이션 몽타주가 실행되도록 노드를 이어주자.

Content / Blueprint / MoveCharBP 더블클릭
Play Anim Montage 노드의 Anim Montage 속성을 할당해주어야 애니메이션 몽타주가 플레이 된다.

이렇게 노드를 생성하고 실행해보면 애니메이션이 실행되지 않은 것을 확인할 수 있다.
해당 캐릭터의 애니메이션 블루프린트(Anim Blueprint)에도 만들어 두었던 애니메이션 몽타주를 할당해주어야
애니메이션 몽타주를 실행할 수 있다.

기존에 생성된 애니메이션 블루프린트 CharAnimBP를 열어,
Anim Graph 상에 세팅된 노드 사이에 defaultSlot 노드를 생성하여 가운데 끼워주자.

defaultSlot 노드는 위에서 만들었던 애니메이션 몽타주를 가리킨다.
사진을 확인하면 defaultGroup 안에 defaultSlot 이 생성되어 있는 걸 확인할 수 있다.

Content / Blueprint / Animations / CharAnimBP
New State Machine 노드와 Final Animation Pose 사이에 DefaultSlot 을 연결하자.

이렇게 세팅하면 공격 애니메이션이 재생되는 걸 확인할 수 있다.

여담으로 현재까지의 애니메이션을 보면 캐릭터의 움직임이 자연스럽게 연결되는 걸 알 수 있는데,
이런 연결을 애니메이션 블렌딩 처리라고한다.

애니메이션 몽타주 내에서 블렌딩이 처리되는 시간을 정할 수 있는데,
이 시간이 애니메이션 시간보다 길면 실행되지 않는 문제가 발생한다.

 

공격 애니메이션이 실행된다! 라는 건 확인했지만 사실 문제가 있다.
클릭할 때마다 공격 애니메이션이 실행된다는 점이다.
이번엔 이점을 해결해보자.

bool형 변수를 만들어서 변수가 false 일때만 애니메이션을 실행하도록 노드를 구성해볼 것이다.
우선 MoveCharBP 블루프린트를 열고, 왼쪽에 Variables 에서 bool형 변수를 생성하자.

생성된 isAttacking 변수.
변수 자료형은 Boolean.

다음은 위에서 만들었던 Left Mouse Button 노드를 수정해주자.
(get) isAttacking 노드, (set) isAttacking 노드, Branch 노드를 추가로 사용할 것이다.

Branch 노드는 bool형 값을 받아 true, false 분기를 나누어 프로그램이 진행되도록 하는 노드이다.
이 노드에 (get)isAttacking 노드를 연결하고,
Branch의 false 부분을 (set)isAttacking 노드에 연결하여 isAttacking 값을 true로 바꾸자.

이러면 isAttacking 변수가 false 일때만 실행될 것이다.

이번엔 만들었던 애니메이션 몽타주에 노티파이를 추가해 줄 것이다.
노티파이(Notify)유니티의 이벤트키와 유사한 개념으로, 애니메이션의 흐름을 감지하는 기능이다.

애니메이션 흐름 중간에 노티파이를 생성해두고 실행한 다음,
애니메이션 흐름이 노티파이에 다다를때
블루프린트에선 노티파이를 감지해 이벤트 발생처럼 특정 기능을 실행할 수 있다.

생성했던 몽타주를 열고, 다음과 같이 임의의 프레임에 노티파이를 생성하자.
이름은 OnAnimEnd_Attack로 설정할 것.

원하는 프레임을 선택하고(빨간색 표시), 노티파이 속성을 우클릭해서(초록색 표시) 노티파이를 생성하자.
생성된 OnAnimEnd_Attack 노티파이.

이렇게 생성하면 이 애니메이션 몽타주를 사용하고 있는 CharAnimBP 블루프린트에서
해당 노티파이를 사용할 수 있다.

그전에, CharAnimBP가 MoveCharBP의 isAttacking 변수를 false로 할당하도록
커스텀이벤트(Custom Event)를 생성할 것이다.

Event BeginPlay, Event Tick 노드들처럼 언리얼에서 제공하고 있는 이벤트 말고도
사용자가 직접 이벤트를 만들어 호출하도록 할 수 있는데, 이를 커스텀이벤트 라고 한다.

MoveCharBP를 열고, 우클릭으로 커스텀 이벤트 노드를 생성하자.
이름은 아까와 똑같이 OnAnimEnd_Attack. 꼭 똑같지 않아도 된다.

커스텀 이벤트 생성
생성된 커스텀 이벤트.

이번엔 CharAnimBP를 열고 애니메이션 몽타주가 노티파이를 발생하면
위에서 생성했던 MoveCharBP의 커스텀 이벤트를 호출하는 노드를 만들것이다.

CharAnimBP의 Event Graph에서 OnAnimEnd_Attack 노티파이 노드와
Try Get Pawn Owner 노드,
Cast To MoveCharBP 노드,
MoveCharBP의 AnimEnd_Attack 이벤트 노드를 꺼내고, 다음과 같이 연결하자.

노티파이가 발생하면 MoveCharBP 안의 AnimEnd_Attack 이벤트를 호출하는 노드. MoveCharBP의 On Anim End Attack 노드는 Cast To MoveCharBP 노드의 output을 끌어다 놓으면 확인할 수 있다.

MoveCharBP로 돌아와서 만들어 두었던 커스텀 이벤트 노드에 (set)isAttacking 노드를 연결해
isAttacking 노드를 false로 만들자.

문제가 해결된걸 알 수 있다.

여담으로 위에서 Try Get Pawn Owner 노드를 사용했는데,
해당 애니메이션을 할당받은 객체(Pawn타입)을 찾는 노드이다.

유니티의 모든 오브젝트가 GameObject로 이루어져 있다면,
언리얼의 모든 오브젝트는 Actor와 Pawn으로 이루어져 있다.

Actor는 게임 상에 배치하는 오브젝트들을 의미하며,
Pawn은 게임 상의 오브젝트 중 컨트롤러 입력을 받는 오브젝트를 의미한다.
최상위 클래스인 Actor의 특성을 하위 클래스 Pawn이 상속받은 개념이다.
추가로 Character는 애니메이션 등을 처리할 수 있는 클래스로 Pawn을 상속받았다.

따라서 CharAnimBP를 할당받은 Pawn을 Cast To MoveCharBP 노드에 넣어주면
MoveCharBP를 찾을 수 있다.

다른 유니티와 언리얼의 차이에 대해선 아래 링크를 참조하자.
https://orcacode.tistory.com/entry/%EC%96%B8%EB%A6%AC%EC%96%BC-%EC%97%94-Actor%EC%99%80-Pawn%EA%B3%BC-Character%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90

 

언리얼 엔진 Actor와 Pawn과 Character의 차이점

언리얼 엔진을 사용해보기 시작하면서 가장 불편했던 점은 첫째로 자료가 거의 대부분 블루프린트 샘플들 위주이고 구성 요소들이 유니티와 뭔가 비슷하면서도 다른 느낌을 받았기 때문이다. 나와 같은 사람들을..

orcacode.tistory.com

 

또 하나의 문제가 존재한다.
공격을 하는 도중에 이동이 가능하다.
이번엔 이 문제를 고쳐보자.

MoveCharBP에 만들어 주었던 움직이는 노드를 수정해주자.
(get)isAttacking, Branch 노드를 사용해서 이전에 만들었던 IsAttacking 변수가 false 일때만 움직이게 하자.

생각보다 간단하다

추가로, 노드의 핀 연결을 제거하는 방법은
핀을 우클릭해서 Break link to ~ 버튼을 눌러주면 된다.


캐릭터(플레이어) 점프

스페이스 바를 누르면 캐릭터를 점프시켜보자.
사실 점프를 해주는 물리 노드가 존재해서, 점프 자체는 어렵지 않다.

MoveCharBP를 열고 노드를 구성하는데,
pace Bar 노드와 Jump 노드, StopJump 노드를 사용한다.

스페이스를 누르면 계속해서 캐릭터가 점프하는 노드

점프와 관련해서 노드 작업은 여기서 크게 벗어나지 않는다.
나머지 수치 조절 관련해서는 Character Movement 의 수치값 조절로 끝난다.
여러 예를 확인해보자.

우선 수치값을 바꾸기 위해서는
MoveCharBP 좌측에 Components 탭 중 CharacterMovement 를 선택한다.
그러면 Detail에서 해당 블루프린트의 CharacterMovement와 관련된 수치값을 볼 수 있다.

이걸 선택하면..
캐릭터 움직임과 관련한 수치값들을 볼 수 있다.

점프력을 키우기 위해서는
Character Movement: Jumping / Jump Z Velocity 값을 조절하면 된다.

점프력 조절

중력값을 조절하기 위해서는
Character Movement (General Settings) / Gravity Scale 값을 조절하면 된다.

중력값 조절

공중에서도 조금 움직이게 하려면
Character Movement: Falling / Air Control 값을 조절하면 된다.

에어 컨트롤 조절

 

이번엔 점프 애니메이션을 적용해보자.

점프 애니메이션 역시 앞서 임포트 했던 애니메이션 중에서
점프 애니메이션을 몽타주로 만들어서
점프를 실행할 때 Play Anim Montage 노드로 실행해주자.

Content / Mesh / Animations / sword_and_shield_jump 로 몽타주 생성!
전에 만든 Jump 노드에 Play Anim Montage 노드를 추가하자!

추가로 이 애니메이션 속 캐릭터는 이동이 자유분방하다.
sword_and_shield_jump 를 열어 다음의 속성 두개를 설정해주자. (몽타주 아님!)

Root Motion Root Lock : 루트 모션의 루트 본 위치를 고정하는 방법.
Anim First Frame 으로 애니메이션 첫 프레임의 위치를 고정하게 하자.

Force Root Lock : 루트 모션이 활성화되지 않아도 루트 본의 위치가 고정되게 함.

Root Motion 속성

 

현재 점프 애니메이션엔 세가지 문제가 있다.
1. 땅에 착지하고 나서도 점프 애니메이션이 끝나지 않음.
2. 점프 애니메이션이 점프키 누를때마다 재생됨.
3. 공격 도중에 점프됨.

우선 1번 문제는 MoveCharBP에서 수정해주어야 한다.
Event On Landed 노드는 액터가 땅에 착지했을때 호출되는 이벤트다.
이를 통해 문제를 고쳐보자.

땅에 닿았을때 애니메이션 정지.

2번 문제는 MoveCharBP 의 Jump 쪽 노드를 수정해주어야 한다.
Character Movement 에는 떨어지고 있는지 여부를 알려주는 Is Falling 노드가 존재한다.
이 노드와 Branch 노드를 사용해 지상에 서있을때만 점프가 되도록 문제를 고쳐보자.

떨어지는 중이 아닌 즉, 지상에 서있는 상태일때만 점프.

3번 문제는 방금 수정한 노드에서
isAttacking 변수, Branch 노드를 하나씩 더 추가해 해결이 가능하다.
다음의 사진을 확인해서 Branch와 Jump 노드 사이를 수정하고 문제를 고쳐보자.

공격중이 아닐때만 점프

 

작업한 내용

https://youtu.be/JhfE2x7_hok


다음의 링크는 구글링 하다가 찾은 언리얼 관련 자료이다.
감사하면서 확인하자...

https://www.slideshare.net/MrDustinLee/ss-77943037

 

레퍼런스만 알면 언리얼 엔진이 제대로 보인다

언리얼 엔진을 처음 사용하는 분들을 위한 행사 시작해요! 언리얼 2017에서 발표한 자료입니다.

www.slideshare.net

 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.