본문 바로가기

언리얼엔진

14. Draw 애니메이션 / AttachActorToComponent / 인터페이스

등에 있는 칼을 뽑는 애니메이션 Draw 애니메이션을 추가해줄 것이다.

- Draw1 : 등에 있는 칼 잡는 애니메이션

- Draw2 : 잡은 칼을 꺼내는 애니메이션

 

Draw 애니메이션 만들기

우선 캐릭터 등에 칼이 있을 적절한 위치를 잡아줄 것이다.

먼저 Draw1 애니메이션 화면에서 등에 있는 칼을 잡았을 때의 프레임을 보고 칼의 위치를 예상해보자.

Draw 1 애니메이션 화면


※ 애니메이션 키 추가하여 자세 수정하기

만약 애니메이션의 자세를 수정해주고 싶다면 키 추가를 통해서 자세를 잡아줄 수 있다.

먼저 Draw 1 애니메이션을 보면 오른쪽 팔이 움직이는 애니메이션이므로 upperarm_r / lowerarm_r / hand_r들의 bone을

건들여주면될 것이다.

upperarm_r / lowerarm_r / hand_r bone에 키+ 버튼으로 키 추가하기

 

그러면 뷰포트 화면 밑에 추가해준 키가 애디티브 레이어 트랙에 추가된 것이 보일 것이다. 

 

이렇게 추가한 상태에서 변경하고자 하는 프레임에서 upperarm_r / lowerarm_r / hand_r bone들을 원하는 회전만큼

조정해주면 된다.(위치를 바꿔버리면 애니메이션이 이상해질 수도 있다.)

그리고 각 bone마다 key + 추가를 해주면 위와같이 다른 색상의 선들이 생기는 것을 볼 수 있다.

이렇게 하여 프레임 0부터 지정한 프레임까지의 보간이 된 것이다.


Draw_1이 등에 있는 칼을 잡는다면 Draw_2는 등에 있는 칼을 뽑는 동작이므로 두 개의 애니메이션을 연결해줄 것이다.

콘텐츠 브라우저에서 콘텐츠/Meshes/Mannequin/Animation/Sword 경로 안에 있는 Draw_1 애니메이션을 우클릭 - 

생성 - 애님컴포짓 생성으로 Draw_Composite 애니메이션을 만들어준다.

Draw_1 우클릭 - 생성 - 애님컴포짓 생성

 

이렇게 만들어준 Draw_Composite 에서 Draw_1과 Draw_2 애니메이션을 이어서 하나로 만들어주는 것이다.

재생해보면 자연스럽게 애니메이션이 이어지는 것을 볼 수 있다.

Draw_Composite 화면에서 Draw_1과 Draw_2를 붙혀줌

 

이제 칼을 뽑기 전에 캐릭터의 등에 Sword가 위치하고 있을 건데, 여기서 어느 위치에 있을 것인지 찾아줄 것이다.

Draw_1 애니메이션의 제일 마지막 프레임을 보면 잡아줄 수 있는데, 그때 Sword의 위치와 가장 가까운 spine_03 bone에소켓을 추가해준다.(소켓 : spine_03_weapon)

그리고 spine_03_weapon 소켓에 프리뷰 애셋 추가 : SK_Sword를 추가해주어 현재 애니메이션에서 Sword의 위치에 맞게spine_03_weapon  소켓의 트랜스폼을 맞춰준다.

spine_03 밑에 spine_03_weapon 소켓 추가(프리뷰 애셋 추가)

 

이런 식으로 spine_03_weapon 소켓의 위치를 현재 프레임의 Sword와 완전히 겹치게 조정


플레이 시 Sword를 소켓에 위치시키기

이렇게 소켓의 위치를 조정해준 뒤, 플레이 시 칼을 해당 소켓에 위치하도록 해볼 것이다.

칼의 생성을 BP_Character에서 하였으므로 생성됨과 동시에 칼을 위치를 잡아주도록 하겠다.

 

BP_Character 이벤트그래프에서 마지막 ADD 노드에서 이어줄 AttachActorToComponent 노드를 연결해준다.


● AttachActorToComponent : Actor를 Componenet에 붙임

AttachActorToComponent

- 타깃 : 여기서 타깃은 우리가 플레이 시 스폰하는 Sword 액터를 말하므로 스폰 액터의 Return Value값을 받아온다.

- Parent : 타깃이 붙을 Scene 컴포넌트 / BP_Character의 Mesh 컴포넌트를 연결시켜준다(SkeletalMesh에 있는 소켓)

- Socket Name : 타깃 안에 있는 소켓의 이름 / 방금 만들었던 spine_03_weapon 소켓 입력

                  ㄴ Name의 특성 : 편집이 불가능 / 대소문자 구분하지 않음

- Location Rule : 위치 규칙

- Rotation Rule : 회전 규칙

- Scale Rule : 크기 규칙

 

ㅇ규칙의 종류        

      ㄴKeep Relative : 현재 값을 상대 값으로 가져다 씀(스폰(자식) 트랜스폼 * 소켓(부모) 트랜스폼)

      ㄴKeep World : World에 스폰될 때의 내용을 그대로 유지하여 씀(스폰(자식) 트랜스폼)

      ㄴSnap to Target : 스폰 트랜스폼은 무시하고 붙을 타겟(소켓)에 맞게 그대로 적용됨(소켓(부모) 트랜스폼)

 

따라서 이와같은 연결이 될 것이다.

 

이후 컴파일 하고 실행해보면 Sword가 무사히 spine_03_weapon 소켓의 위치에 스폰되있는 것을 볼 수 있다.

 

나중에 이런식으로 Sword를 붙혀줄 것이다 라는 것을 설명하기 위해 BP_Character 이벤트그래프에서

AttachActorToComponent를 보여준 것이므로 실제로는 BP_Character에서 작동하진 않을 것이기 때문에 지워버리자.


Sword를 Draw하기 위한 키 설정

플레이 시 등에 있는 무기를 꺼내는 동작을 하기 위해서 먼저 키 설정을 해준다.

편집 - 프로젝트 세팅 - 입력 탭에서 액션 매핑으로 키를 추가해줄 것이다.

나중에 두 가지의 무기를 사용할 것이기 때문에 WeaponA키와 WeaponB키를 미리 만들어준다.

(매핑의 이름은 중립적으로 지어주는 것이 좋다.)

- WeaponA : Q

- WeaponB : E

프로젝트 세팅에서 액션 매핑으로 WeaponA / WeaponB 키를 추가해줌

 

이제 이런 키 입력 처리는 BP_PlayerController에서 했기에 BP_PlayerController 블루프린트에서 추가해줄 것이다.

BP_PlayerController 이벤트그래프에서 WeaponA / WeaponB 입력 액션 노드를 추가해준다.

그리고 Controller가 조종할 Pawn의 정보를 가져오기 위해 Get Controlled Pawn노드도 사용할 것이다.

3개의 노드를 사용할 예정


블루프린트 인터페이스

콘텐츠 브라우저에서 콘텐츠 - Blueprints 폴더에 우클릭 - 블루프린트 - 블루프린트 인터페이스를 추가해준다.

(BP_CharacterInterface)

블루프린트 인터페이스 추가

-인터페이스 : 상속을 위한 클래스

 

※ 인터페이스 특징

- 스토리지가 있으면 안됨(멤버변수를 가질 수 없다)

- 모든 함수가 순수가상함수일 것

- 단순 상속용 클래스(cpp에서는 다중 상속용으로 사용한다)

 

이렇게 만든 BP_CharacterInterface 블루프린트에 들어오면 이런 화면이 나온다.

BP_CharacterInterface 블루프린트 화면

 

여기에선 인터페이스의 특징 상 함수만 만들 수 있다.

BP_CharacterInterface에서 2개의 함수 WeaponA와 WeaponB를 추가해주고 컴파일해준다.

WeaponA와 WeaponB 함수를 추가


인터페이스 상속

이제 상속을 통해서 BP_CharacterInterface를 사용해보도록 하자.

BP_Character 클래스 세팅에서 구현한 BP_CharacterInterface 인터페이스를 추가해줄 것이다.

BP_Character 클래스 세팅 - BP_CharacterInterface를 추가하면 내 블루프린트 탭에 만들었던 인터페이스 함수가 나온다.

 

BP_Character에서 Event WeaponA / WeaponB 노드를 추가하여 잘 호출되는지부터 확인해본다.

각각 Print String 노드를 사용하여 확인했다.

Event WeaponA / Event WeaponB의 호출 테스트

 

이렇게 BP_Character에서 함수의 정의만 해주고, BP_PlayerController에서 정의한 두 함수를 호출해주면 된다.

컴파일 후 실행해서 매핑해주었던 Q, E키를 눌러보면 잘 출력되는 것을 확인할 수 있었다.