이 시리즈는 이득우의 언리얼 C++ 게임 개발의 정석을 바탕으로 작성되었습니다.
언리얼 엔진에선 캐릭터의 다양한 애니메이션을 체계적으로 관리하는 도구인 애니메이션 블루프린트를 제공한다.
애님 인스턴스(Anim Instance)
애니메이션 블루프린트의 기반. 스켈레탈 메시를 소유한 폰의 정보를 받아 애님 그래프로 데이터를 전달.이벤트 그래프(Event Graph)
: 애니메이션 블루프린트가 가진 변수가 특정 조건을 만족하는지 등에 따라 애님 그래프에서 사용할 값을 계산하고 애니메이션 블루프린트를 업데이트하는 데 사용되는 이벤트 기반 그래프애님 그래프(Anim Graph)
: 애니메이션 시스템을 제작하는 시각적 도구. 애님 인스턴스의 변수 값에 따라 변화하는 애니메이션을 블루프린트를 이용해 실제로 설계하는 공간.애님 그래프를 이루는 모든 구성요소는 '노드'라고 칭한다. 애니메이션 블루프린트를 어떻게 활용하는지 [8. 폰 조종하기] 포스팅에서 다뤘던 삼인칭 샘플 프로젝트의 애니메이션 블루프린트를 분석해볼 것이다.
위에서 알아본 애니메이션 블루프린트의 각 구성 요소를 살펴보자.
클래스에서 애니메이션 블루프린트를 다루는 형태이다. 스켈레탈 메시 컴포넌트는 기본적으로 애니메이션 기능이 탑재되어 메시에 사용할 애니메이션 블루프린트를 지정한다. 클래스에서 사용하기 위해 애니메이션 블루프린트 클래스를 인스턴스화해야 하고, 이것이 애님 인스턴스다.
애님 인스턴스는 캐릭터 액터(메시 컴포넌트)의 [디테일 패널
- 애니메이션 섹션
- 애님 클래스 필드
]에서 변경할 수 있으며, C++ 스크립트로는 GetMesh()->SetAnimInstanceClass()
함수로 지정할 수 있다.
// ThirdCharacter.cpp
AThirdCharacter::AThirdCharacter()
{
GetMesh()->SetAnimationMode(EAnimationMode::AnimationBlueprint);
static ConstructorHelpers::FClassFinder<UAnimInstance> AnimInstance(TEXT("/Game/Characters/Mannequins/Animations/ABP_Manny.ABP_Manny_C"));
if (AnimInstance.Succeeded()) {
GetMesh()->SetAnimInstanceClass(AnimInstance.Class);
}
...
}
이처럼 코드를 작성하면
캐릭터 인스턴스가 생성되었을 때 즉, 레벨에 배치했을 때 애님 클래스가 변경되어 있는 것을 확인할 수 있다.
삼인칭 샘플 프로젝트 캐릭터의 애니메이션 블루프린트는 두 가지의 파트로 구분된 이벤트 그래프를 가진다. 먼저 애니메이션 블루프린트를 사용하기 위한 초기화 작업이 이루어진다.
Blueprint Initialize Animation 이벤트
노드는 애니메이션 블루프린트가 초기화될 때 1회 실행된다. Get Owning Actor
노드로 해당 애니메이션 블루프린트를 소유하고 있는 액터 정보를 가져올 수 있다. 이후 Character
타입으로 형변환하여 변수로 저장하고, 해당 액터의 캐릭터 무브먼트 컴포넌트
도 변수로 저장한다.
이러한 애니메이션 블루프린트의 변수는 [애니메이션 블루프린트 에디터
- 내 블루프린트 패널
]에서 확인할 수 있다.
캐릭터가 움직일 때 이동 애니메이션을, 점프할 때 점프 애니메이션을, 아무것도 하지 않을 땐 IDLE 애니메이션을 실행해야 할 것이다. 즉, 입력 등으로 캐릭터의 상태가 어떻게 변화했는지를 계속 읽어야 적절한 애니메이션을 실행할 수 있다.
Blueprint Update Animation 이벤트
노드는 매 프레임마다 실행되며, 해당 액터가 유효한지 즉, 월드에 존재하고 정상적으로 연결되어 있는지를 검사하고 시퀀스로 넘어간다.
시퀀스는 실행되면 연결된 모든 이벤트 시리즈를 실행한다. 위 사진의 시퀀스는 Then 0
, 1
, 2
로 총 3개의 출력이 있으며, 순서대로 모든 출력을 실행한다. 매 프레임 액터의 유효성을 검사하여 계속 시퀀스를 실행하므로 매 프레임 모든 노드가 계속 실행되는 것이다.
Then 0
시퀀스의 첫 번째 출력, Then 0
에 연결된 실행부이다. 앞선 초기화 과정에서 설정한 액터의 무브먼트 컴포넌트
에서 속도 정보를 가져와 Velocity
변수에 저장하고, 이 속도 벡터의 XY 성분 길이(크기)를 구하여 GroundSpeed
변수에 저장한다.
Then 1
앞서 시퀀스는 연결된 이벤트 시리즈를 순차적으로 실행한다고 했다. Then 1
의 출력에 연결된 구현부에는 무브먼트 컴포넌트
에서 캐릭터의 가속도(Acceleration)가 존재하고, Then 0
의 구현부에서 설정한 GroundSpeed
변수가 3.0 이상의 값을 즉, 속도 벡터의 XY 평면상의 길이가 3.0 이상일 때 캐릭터를 이동하고 있다고 보고 ShouldMove
변수를 설정해준다.
Then 2
시퀀스의 마지막 출력 Then 2
의 구현은 현재 캐릭터가 공중에 떠있는지의 여부를 알리는 것이다. 캐릭터 무브먼트 컴포넌트는 기본적으로 폰의 움직임을 파악하기 위해 다음의 함수를 제공한다.
IsFalling()
: 현재 공중에 떠있는지 알려준다.IsSwimming()
: 현재 수영 중인지 알려준다.IsCrouching()
: 현재 (쭈그리고) 앉아있는지 알려준다.IsMoveOnGround()
: 땅 위에서 이동 중인지 알려준다.굳이 새로 구현할 필요 없이 간단하게 제공하는 함수로 IsFalling
변수를 설정해 주었다.
실제 애니메이션을 선택하는 애님 그래프는 이동(Locomotion)과 메인 스테이트로 나뉜다. 각각은 스테이트 머신이라는 노드로 만들어져 있는데, 스테이트 머신 노드에 마우스를 올려보면 해당 스테이트 머신이 어떻게 연결되어 있는지 확인할 수 있다.
위 사진은 Locomotion
스테이트 머신의 구현 형태이다. 스테이트 머신이란 캐릭터가 반복해서 재생해야 할
해당 스테이트 머신에 진입하면 Entry
에 따라 애니메이션을 실행한다. Idle
, Walk / Run
은 각각의 스테이트 노드이다. 스테이트를 연결하는 화살표를 트랜지션, 언리얼 엔진의 용어로는 '룰'이라 하며, 스테이트를 변경하는 조건을 기재한다.
스테이트 머신을 구성하는 룰, 스테이트도 모두 작은 애님 그래프이다. 룰은 연결된 스테이트에서 룰에 구현된 조건을 만족하면 다음 스테이트로 이동하도록 트랜지션에 진입, 스테이트는 트랜지션으로부터 진입했을 때 지정된 시퀀스에 따라 애니메이션 포즈를 출력한다.
스테이트 머신과 마찬가지로 각 노드에 마우스 커서를 올리면 간략한 구현 형태를 확인할 수 있다. Locomotion
스테이트 머신은 ShouldMove
변수가 True
가 되었을 때 Walk / Run
스테이트를, False
가 되었을 때 Idle
스테이트를 실행한다.
Walk / Run
스테이트를 클릭해보면 새로운 형태의 노드를 마주할 수 있다. 블렌드 스페이스라는 형태의 애니메이션인데, 특정 변수 값의 변화에 따라 비슷한 형태의 애니메이션 중 하나를 선택하여 재생하는 애니메이션이다.
애니메이션 블루프린트 에디터의 애셋 브라우저 패널에서 노드의 이름인 BS_MM_WalkRun
애셋을 확인할 수 있고, 이를 클릭하면 다음과 같은 화면으로 에디터가 전환된다.
하단의 이 네모칸을 블렌드 스페이스라고 하며, Speed
라는 가중치에 따라 MM_Walk_InPlace
, MM_Walk_Fwd
, MM_Run_Fwd
애니메이션을 블렌딩하여 실행한다. 해당 BS_MM_WalkRun
블렌드 스페이스 애니메이션은 속도가 빨라질수록 제자리 걸음에서 앞으로 질주하는 애니메이션을 블렌딩하여 실행하도록 만들어져 있다.
앞서 이해가 쉽도록 블렌드 스페이스의 설명을 특정 변수 값에 따라 하나의 애니메이션을 실행한다고 하였는데, 가중치 값에 따라 인접한 두 애니메이션을 적절하게 블렌딩하여 자연스러운 애니메이션을 출력한다는 것이 더 정확한 설명이다.
그리고 이 블렌드 스페이스의 Speed
가중치는 Walk / Run
스테이트에서 GroundSpeed
변수 값을 입력으로 두어 GroundSpeed
가 빨라질수록 적절한 속도의 달리는 애니메이션이 실행된다.
이동에 관련된 Locomotion
스테이트 머신을 살펴보았으니, 나머지 하나인 Main States
스테이트 머신을 보자.
해당 스테이트 머신은 이동(Locomotion
), 점프, 착지를 조건에 맞게 연결하였다. 이때 각 스테이트 노드를 잘 살펴볼 필요가 있는데, 주의깊게 봐야 할 노드는 To Land
, To Falling
스테이트이다.
스테이트 에일리어스는 별도의 진입부 없이 조건을 만족하면 자동으로 접근하는 스테이트이다. 일반적인 스테이트의 동그라미 아이콘과 달리 양방향 화살표 아이콘을 가지며, 해당 스테이트를 선택하면 디테일 패널에서 해당 스테이트 머신 내의 모든 스테이트 목록을 확인할 수 있다. To Falling
스테이트는 똑같은 스테이트 에일리어스이기 때문에 목록에 나타나지 않는다.
해당 목록에서 체크된 스테이트가 실행 중일 때, 스테이트 에일리어스의 트랜지션 룰을 만족하였다면 직접적인 트랜지션 룰 없이도 스테이트 에일리어스의 트랜지션이 작동한다. 이것을 스테이트 에일리어싱(State Aliases)라 한다.
즉, 위 예시에서 To Land
스테이트 에일리어스는 Jump
, Fall Loop
로부터의 에일리어스가 설정되어 있다. 그리고 To Land
에서 Land
스테이트로의 트랜지션 조건은 IsFalling
변수가 False
로 설정되는 것이다. Jump
, Fall Loop
스테이트를 실행하던 캐릭터는 Land
스테이트로의 직접 트랜지션이 없지만 IsFalling
이 False
가 되는 순간 에일리어싱에 의해 To Land
스테이트 에일리어스로 이동하고, 즉시 Land
로트랜지션된다.
이는 애니메이션이 복잡해질수록 다양한 트랜지션 라인이 생겨 그래프가 복잡해지는 것을 막을 수 있는 매우 유용한 기술이다.
앞선 Locomotion
스테이트 머신이 어떠한 노드와 연결된 것을 확인할 수 있었다. 해당 노드는 연결된 스테이트 머신(포즈)를 캐시에 저장해 다른 곳에서 해당 노드를 참조할 수 있게 한다.
컴퓨터공학의 다른 분야에서 사용되는 캐싱과 똑같은 의미, 똑같은 역할을 한다.
Main States
의 Land
스테이트는 캐시 저장해놓은 Locomotion
베이스 애니메이션에 MM_Land
라는 애디티브 애니메이션을 가중치에 맞게 블렌딩하여 적절한 애니메이션을 재생한다. 이때 애디티브 적용
노드의 Additive
핀에 연결되는 애니메이션은 애디티브 애니메이션이어야 한다.
애디티브 애니메이션은 애니메이션 애셋을 열고 애셋 디테일
패널에서 설정할 수 있으며, 애디티브 애님 타입
필드가 No Additive
로 설정돼있는 것을 변경해주기만 하면 애디티브 설정이 완료된다.
이러한 애디티브 애니메이션은 그 자체로는 유용하지 않고 위와 같은 애디티브 적용 처리를 해주어야 완전하게 작동한다. 위 예시와 같이 이동 입력이 있는 상태에서 착지 애니메이션을 재생한다면 착지 애니메이션과 이동 애니메이션을 적절히 블렌딩하는, 혹은 무기를 휴대한 상태로 이동할 때 상체는 무기를 쥐고 있지만 하체는 이동하는 애니메이션을 블렌딩해야 할 때 애디티브 애니메이션을 활용할 수 있다.
Main States
스테이트 머신이 최종 애니메이션 포즈로 연결되기 전 DefaultSlot
이라는 이름의 슬롯에 연결된 것을 확인할 수 있다. 슬롯은 애님 몽타주를 염두에 두기 위한 노드로, 최종 애니메이션을 결정하기 전에 애님 몽타주를 평가하여 기본 애니메이션에 덮어 씌우거나, 블렌딩한다. 위 예시는 덮을 애님 몽타주를 만들지 않은 상태이기 때문에 블렌딩 등의 작업은 하지 않고 슬롯만 연결하여 추후 애님 몽타주 사용에 대비한 것으로 보인다.
그에 대한 증거로 이처럼 포즈 연결 상태를 변경해도 정상적인 애니메이션 실행을 확인할 수 있다.
애님 몽타주에 대한 내용은 추후 다른 포스팅에서 다룰 것인데, 일단은 일련의 애니메이션 시퀀스 중 일부를 자유롭게 조절할 수 있는 셋이라고 보면 된다. 여러 애니메이션을 순서대로 재생하도록 연결하고 필요에 따라 변수 값이나 입력을 확인하여 특정 애니메이션을 길게 혹은 반복 실행하거나 생략하고 다음 애니메이션으로 넘어가는 등의 조작이 가능하다.
그리고 이를 블렌딩하거나 씌울 때 어떤 릭을 사용할 것인지 컨트롤 릭으로 결정한다. 리깅, 컨트롤 릭에 대한 내용도 추후 다른 포스팅에서 다뤄 보겠다. 지금은 넘어가도 무방한 내용이다.
내용이 꽤 길어졌는데, 프로젝트 분석을 마쳤으니 다음 포스팅에선 앞서 다뤘던 UE5Practice 예제 프로젝트에서 애니메이션 블루프린트를 생성하고 다양한 애니메이션을 재생해볼 것이다.
▶ 언리얼 엔진 4.19 이상 버전 애니메이션 블루프린트 세팅 방법
▶ UE4 에서의 애디티브 애니메이션
▶ [UE Document] 라이라의 애니메이션
▶ [UE Document] 블렌드 스페이스 개요
정말 감사합니다 궁금했던 점이 많이 해소 되었습니다