언리얼엔진/언리얼 C++

애니메이션

season97 2023. 10. 13. 18:33

▶ 애니메이션의 유형

 

1. 휴머노이드

 

ㆍ 머리, 팔2개, 몸통, 다리2개 즉 사람처럼 생긴 오브젝트 (캐릭터)

 

ㆍ 일반적으로 인간형으로 분류할 수 있으며 이는 인간형 오브젝트들이 리타겟팅을 이용해서 애니메이션을 서로 공유를 할 수 있다는 얘기가 된다.

 

※ 리타겟팅? - 똑같은 개체(인간형)끼리 애니메이션을 공유할 수 있는 기능

 

휴머노이드 예시

 

 

2. 제네릭

 

ㆍ 휴머노이드를 제외한 나머지 오브젝트들을 보통 제네릭으로 분류해서 처리한다.

 

ㆍ 특징은 리타겟팅을 통한 애니메이션을 원활하게 공유할 수는 없지만 상대적으로 휴머노이드 객체보다 코스트가 낮은 경우가 많다.

 

▶ 페르소나와 메카님

ㆍ 언리얼은 페르소나 유니티는 메카님으로 각각의 엔진에 특화된 기능을 가지고 있다

 

1. 페르소나

 

ㆍ 언리얼에서 사용하는 애니메이션 시스템

 

ㆍ 캐릭터의 움직임을 제어하며 애니메이션 클립, 블루프린트 등 다양한 요소와 결합하여 사용 가능하다.

 

ㆍ 상태 기반으로 작동하며 다양한 상태와 그 사이를 전환하는 로직 작성이 가능하다.

 

2. 메카님

 

ㆍ 유니티에서 사용하는 애니메이션 시스템

 

ㆍ 물리엔진과 연계하여 자연스러운 움직임을 생성할 수 있다

 

ㆍ 마찬가지로 상태기반이며 다른 상태로 전환하기 위한 로직을 설정할 수 있다.

 

◈ 공통점

 

ㆍ 기본적으로 게임 내 캐릭터의 애니메이션이 자연스럽게 이어지도록 하기 위해 '상태'라는 개념 중심으로 작동한다.

 

ㆍ 트렌지션 로직을 통해 다른 애니메이션 상태로 전이가 된다

 

장점 

 

ㆍ 같은 구조를 가진 모델들간에 공유 및 재사용이 가능하며 확장성이 좋고 이식성이 좋다. 다른프로젝트 혹은 플렛폼으로 쉽게 옮길 수 있다.

 

ㆍ 애니메이션의 상태를 연결하는 기능을 제공한다. 언리얼은 "블렌드 스페이스" 유니티는 "블렌트 트리" 라는 기능을 제공하며 이 기능은 여러 애니메이션을 혼합해 캐릭터의 움직임이 더 부드럽게 보일 수 있도록 한다.

 

※ 예를들어 공격을 하는 애니메이션 도중에 움직이는 명령을 주면 팔은 공격 모션을 계속 하고있지만 다리는 미리 걷는 모션을 재생시킨다. 

 

ㆍ 또한 트렌지션이라는 개념을 사용하기 때문에 FSM(유한 상태 머신) 을 사용해 움직임 및 설계를 할 수 있다.

 

 

▶ 언리얼에서 애니메이션을 사용하기 위해 알아야 할 주요 에디터와 컴포넌트

 

ㆍ AnimInstance

- 언리얼 엔진에서 애니메이션을 관리하는 기본 클래스로 이를 통해 파생된 클래스들은 각각의 캐릭터나 오브젝트에 특화된 애니메이션 로직을 구현할 수 있다. 아래는 AnimInstance를 통해 파생되는 친구들이다

 

1. 스켈레톤

 

ㆍ 3D 모델의 뼈대를 정의. 일반적으로 모델러가 작성하며 프로그래머가 수정할 일은 거의 없다.

 

ㆍ 만약 문제가 발생한다면 엔진레벨에서 수정하는 것이 좋다

 

2. 스켈레톤 메시

 

ㆍ 스켈레톤에 살을 입혀주는 3D메시

 

ㆍ 이 역시 일반적으로 아트팀에서 지작하고 프로그래머가 직접 다루는 경우는 드물다

 

3. 애니메이션

 

ㆍ 언리얼에서 지원하는 애니메이션으론 시퀀스, 몽타주, 블렌드 스페이스, 에임 오프셋, 컴포짓, 포즈 등이 있다.

 

4. 애니메이션 블루프린트

 

ㆍ 여러개의 상태와 그 사이를 전환하는 로직,조건 등을 그래픽 인터페이스로 구현할 수 있다.

 

5. 피직스

 

ㆍ 말 그대로 물리엔진. 게임내 객체들이 물리엔진과 자연스럽게 상호작용을 할 수 있게 해준다

 

ㆍ 언리얼은 자체적인 물리엔진인 PhysX를 사용해 충돌검출 및 물리시뮬레이션을 수행한다.

 

 

▶ 언리얼에서 직접 적용해보기

※ 준비물 : 휴머노이드 모델 FBX, 애니메이션을 가진 휴머노이드 모델 FBX

 

아리사.

ㆍ 미리 받아온 모델인 아리사 모델의 c++을 만들어주었다.

 

ㆍ c++기반 블루프린트까지 생성 해준 후 애니메이션 블루프린트를 만들어줬다.

 

애니메이션 블루프린트 만들기

ㆍ 스켈레톤을 선택하라고 나오는데 아리사를 선택해 주자. 이름은 BP_AnimArissa로 지어줬다.

 

ㆍ 애니메이션을 공유하는 기능을 사용해 보기 위해 다른 모델인 팔라딘의 애니메이션을 임포트 해줬다.

-> 스켈레톤을 아리사로 선택해줬다.

 

팔라딘 기반 아리사

ㆍ 아리사에 팔라딘 애니메이션이 잘 적용된 모습

 

상태를 하나 넣어보자
잘 나온다!

ㆍ BP_AnimArissa로 가서 idle상태를 드래그 해주니 잘 재생되는 모습이다.

 

 

c++기반 블프
기반 블프 옵션에 애님클래스 지정

 

ㆍ 실제 게임에서 사용할 객체에 적용시키기 위해 애님클래스를 아리사BP에 적용시켜주었다.

 

맵 배치된 모습

ㆍ 아주 잘 움직인다.

 

ㆍ 이제 충돌체가 필요할 것 같다 아리사cpp로 들어가보자.

헤더파일에 코드를 작성해주자.

※ 어딘가 구조가 익숙한 것 같다??

블프에서 이놈이랑 같았다!

ㆍ 우리가 사용하던 블루프린트에서 이 노드가 코드로 구현되면 저런 모습을 가지고있는거다

 

ㆍ 근데 여기서 _Implementation을 해준 이유가 뭘까??

 

ㆍ 블루프린트에선 CapsuleComponent로 들어와 있지만 코드에서는 다형성을 구현하기 위해 함수를 하나 더 만들어줬다. 어떤놈이 들어갈지 모르니까 매칭을 시켜줘야 한다....

 

-> 하지만 우리 코드에선 USphereComponent랑 딱봐도 매칭되겠다..

 

-> 근데 만약 갑자기 박스가 필요하다면?? 그럼 또 boxCollision에 대한 컴포넌트를 또 가져와서 함수를 따로 만들어야 한다.. 확장성이 너무 없다

 

-> 다형성을 위해 _Implementation을 써서 함수를 만들어주었다.

 

cpp생성자

ㆍ 생성자에서 필요한 수치들을 초기화 해주었다. 

 

ㆍ 블루프린트에서는 편하게 버튼으로 딸깍 하면 되던 것들이 코드로 오니 뭐가 많다...

코드가 말하는건결국 이거다.

ㆍ그럼에도 불구하고 코드와 함께 사용하는 이유는 압도적으로 메모리 효율이 c++이 좋다는점이다.

 

ㆍ 블루프린트는 사용자가 언제 추가할지 모르는 컴포넌트 정보들을 메모리상 어딘가에 다 담고있지만 C++코드는 딱 필요한 것만 가져와서 사용하기 때문에 메모리 효율면에서 압도적으로 좋다.

테스트하기

ㆍ 테스트를 위해 메세지박스를 찍어줬다.

 

※ 아리사에 관한것은 끝났으니 이제 플레이어 차례다

 

ㆍ 플레이어에게 애니메이션을 주기위해 팔라딘 애니메이션 파일을 모두 임포트 해줬다

 

많은 애니메이션이 들어온 모습

ㆍ 팔라딘 역시 애니메이션 블루프린트를 만들어 주었다.

 

ㆍ 플레이어기 때문에 프로젝트 세팅 입력탭에서 wasd에 대한 축 매핑을 해주었다.

 

ㆍ 어제 작성하던 코드가 있으니 스케일을 음수로 할당해 반대방향으로만 밀어주었다.

 

 

팔라딘 애니메이션 블프

 

ㆍ 추후 추가될 공격 모션을 위해 몽타주를 위한 default slot를 중앙애 연결해줬다.


※ 개념 설명

▶ 애니메이션 몽타주

ㆍ 애니메이션을 사용할때는 일반적으로 애니메이션 블루프린트를 만드는데
이 블루프린트의 규모가 AnimInstance라는 객체다.

ㆍ 쉽게 생각해서 한번쓰고 날아가는 애니메이션은 다 몽타주라 생각하자 

※ 개념 설명 끝


 

ㆍ move State를 더블클릭하자

연결 노드

ㆍ Idle과 Run상태를 전환하기 위해 선을 연동해주고 트렌지션 룰 버튼을 더블클릭하자

 

ㆍ 지금 보이는 이 노드가 유한 상태 머신(FSM)이다.

 


※ 개념 설명

유한 상태 머신?

 

ㆍ 애니메이션을 다루고 확장하기 위해서는 FSM을 이해하는게 중요하다.

ㆍ 기능이 따로 있는것이 아닌 설계에 의한 기법이다

ㆍ 특정한 상태를 정의하기 위한 개념적인 방법론

ㆍ FSM은 상태와 행동에 따라 독립적인 클래스로 제어와 교체가 가능하도록 하는 패턴을 의미한다.

ㆍ 유한한 상태를 정의하고 처리하는 구조로 작성이 되며 각 스테이트가 있고 그 스테이트를 정의시키기 위한 조건이 있는데 그것을 표현하는 방법

 

▶ 유한 상태 머신 개념

ㆍ 상태

- 정의된 하나, 혹은 여러가지 동작을 의미한다

ㆍ 전이 (트렌지션)

- 한 상태에서 다른 상태로 전이하는것을 의미한다

ㆍ 이벤트

- 상태 전이를 위한 조건. 조건이 만족하면 상태전이가 발생한다

ㆍ 행동

- 실제 행동을 실행한다.

※ 공통적으로 각 상태 로직은 외부 전이 조건에 의해 전이가 될 수 있다.

 

▶ 유한 상태 머신의 장단점

1. 장점 

ㆍ 직관성이 뛰어나고 이식성과 재생산성이 좋다

2. 단점

ㆍ 스테이트가 많아지면 진짜 복잡하다

ㆍ 스테이트가 많아질수록 확장성이 떨어지기 시작한다. (상태 전이를 관리하기가 복잡하다)

ㆍ 최초 설계가 까다롭고 수정이 용이하지 못한다.

 

단점 예시...

※ 정말 알아보기 힘들다 ㅠ

⊙ 애니메이터?

ㆍ 게임 오브젝트에 장착하는 특별한 유형의 애니메이션 컴포넌트

ㆍ 애니메이션 제어를 위한 정보가 들어 있기 때문에 애니메이션을 사용하려면
애니메이터 또한 사용을 해야한다.

ㆍ 언리얼에선 애니메이션 클래스에 캡슐화로 묶여있다.

※ 개념 설명 끝

 


 

노드를 다음과 같이 연결해주자.

ㆍ 속도가 0.1 이상이면 움직이는 상태로 판단해 run 애니메이션을 재생한다

 

ㆍ 반대의 상황인 run -> idle은 0.1 < 로 해주었다.

run상태 세팅

 

run상태 세팅

ㆍ  run상태를 다음과 같이 세팅해주었다. 루프를 위해 루프를 체크하고 뼈대의 위치가 흔들리는걸 막기 위해 루트 강제잠금을 체크해주었다. 

플레이어 블프 설정

 

ㆍ 이제 플레이어 블루프린트로 와서 애님클래스를 지정해준다. 

 

!!!

ㆍ 잘 움직이고 상태전환도 잘 된다. 이제 아까 몽타주를 위해 미리 설정해뒀던 공격 모션을 만들어야 한다

 

몽타주 생성

ㆍ 적당한 공격 애니메이션을 찾아 몽타주 생성을 누른다.

 

ㆍ 잘 생성되었다. 이제 플레이어의 C++코드로 가자

 

ㆍ몽타주를 매치해 주기 위해 프로퍼티를 어디서든 수정 가능하게 하고 노출시켜주었다.

 

공격함수
정의

 

ㆍ 공격을 위해 공격함수를 만들고  공격함수를 정의해줬다.

 

키 컴포넌트

ㆍ KeyPlayerAttack를 키에 바인드액션 해주었다.

프로젝트 세팅- 입력

ㆍ 입력탭에 액션을 매핑해주고..

 

플레이어 BP

ㆍ 플레이어 블루프린트에 slash를 매치시켜줬다!

아까나왔던 흐름

ㆍ 아까 해두었던 DefaultSlot으로 인해 몽타주 애니메이션이 실행되면 기존에 실행되던 애니메이션이 멈추고 공격모션이 재생된다 

 

※ 몽타주 애니메이션에 대한 예외처리가 되어있지 않은 상태라 마우스를 연타하면 후깋구히귀후깋기 한다... 추후에 예외처리 코드를 작성해야겠다. 

※ 트랜스폼으로 인한 위치 변환이 아니라 실제 플레이어의 위치값은 변하지 않을것이다...본에 의해 움직이는거 처럼 보이는 것일뿐.. 무기에 별도에 충돌체를 주고 닿았을때 적이 맞게끔 수정해야 할 것 같다

 

 

★ 메시 자체에 본이 심어져 있다. 
(로컬과 월드에 관한 location rotation scale값에 영향주는건 오로지 트랜스폼뿐이다.)
ㄴ 팔을 앞으로 내지르면 팔이 앞으로 나가는거처럼 보인다.
ㄴ 팔을 앞으로 내지르는 랜더링을 그려줘야 되기때문에 본이 심어져있어야 한다.
-> 본으로 인한 랜더링이 바뀌어서 팔을 내지른거 일 뿐 트랜스폼은 그대로다.

 

▶ 언리얼만 해당되는 "소켓"

ㆍ S스켈레탈 - IK - 소켓

ㆍ 정착 시키기 위한 개념

ㆍ 손에다 소켓을 뚫어두고 무기를 배치시키면 무기를 들게된다.

소켓이 있어야 할 자리

ㆍ 언리얼만을 위한 모델이 아니기때문에 기본적으로 소켓이 있지는 않지만 저 위치에 소켓이 들어간다

'언리얼엔진 > 언리얼 C++' 카테고리의 다른 글

Actor  (0) 2024.10.11
머태리얼  (0) 2024.10.10
UObject  (0) 2024.10.10
언리얼C++ 여러가지 기본팁  (2) 2024.10.09
C++ 기반 프로젝트 만들기와 계층구조, 코딩규약  (0) 2023.10.12