애님 그래프의 기본 구성
애니메이션 블루프린트의 이벤트 그래프와 애님 그래프를 구분하고 상태·블렌딩 노드로 최종 포즈를 구성합니다.
캐릭터가 레벨 안에서 움직이기 시작하면 곧 어색한 장면이 눈에 들어옵니다. 멈춰 있을 때와 달릴 때 같은 동작을 반복하거나, 점프하는 동안에도 걷는 발놀림을 그대로 이어 갑니다. 어떤 순간에 어떤 동작을 보여 줄지 정하고, 동작이 바뀔 때 두 동작을 자연스럽게 섞는 일이 필요한데, 언리얼 엔진에서는 이 일을 애니메이션 블루프린트(Animation Blueprint, 줄여서 애님 블루프린트)가 맡습니다.
이 장에서는 애님 블루프린트로 캐릭터의 움직임을 만드는 방법을 차례로 다룹니다. 이 글에서는 애님 블루프린트를 이루는 두 그래프의 역할을 나누고, 그중 포즈를 만드는 애님 그래프(AnimGraph)에 어떤 노드가 있는지 살펴본 뒤, Idle과 이동 두 상태를 가진 가장 작은 스테이트 머신을 연결해 봅니다.
애님 블루프린트의 두 그래프
애님 블루프린트는 스켈레탈 메시(Skeletal Mesh)에 애니메이션을 적용하고 제어하는 특별한 블루프린트입니다. 걷기, 달리기, 점프, 공격처럼 여러 동작을 자연스럽게 이어 붙이고, 게임의 상태에 맞는 동작을 재생하도록 로직을 만드는 곳입니다. 애님 블루프린트 안에는 하는 일이 다른 두 그래프가 있습니다.
이벤트 그래프(Event Graph)는 일반 블루프린트의 이벤트 그래프와 비슷한 그래프로, 캐릭터의 속도나 점프 여부 같은 게임플레이 값을 읽어 애니메이션에 필요한 변수로 계산해 둡니다. 공식 문서에 따르면 이 그래프의 Update Animation 이벤트는 매 프레임 실행되고, Delta Time X 핀으로 지난 갱신 뒤로 흐른 시간을 줍니다. 이벤트 그래프는 게임 스레드에서 실행되므로 공식 문서는 이곳의 계산을 가볍게 유지하라고 권합니다.
애님 그래프는 실제로 캐릭터의 포즈를 만드는 그래프입니다. 여러 애니메이션을 고르고 섞어(blending) 그 프레임의 최종 포즈를 결정하며, 이벤트 그래프가 계산해 둔 변수를 읽어 어떤 동작을 고를지 판단합니다. 이 글에서 주로 다루는 것은 이 애님 그래프입니다.
두 그래프는 연결 방식도 다릅니다. 이벤트 그래프는 흰 실행 선을 따라 노드를 차례로 실행하지만, 애님 그래프의 노드는 포즈 핀으로 이어지며 그 선을 따라 전달되는 것은 실행 신호가 아니라 포즈입니다. 애님 그래프는 매 프레임 평가되므로, 에디터에서 미리보기를 하는 동안 포즈 연결이 계속 움직이는 선으로 표시됩니다.
변수에서 포즈까지 이어지는 길
애님 그래프를 처음 읽을 때는 이벤트 그래프가 만든 변수와 애님 그래프가 만든 포즈가 어디서 만나는지를 먼저 잡아 두면 전체 구조가 선명해집니다.
GAMEPLAY DATA · ANIMATION POSE
이벤트 그래프는 값을 갱신하고 애님 그래프는 포즈를 만듭니다
지상 이동 예제에서 Event Graph가 유효한 소유 Pawn의 XY 속도로 Speed를 갱신합니다. State Machine의 전환 규칙과 상태 내부 Player는 그 값을 사용해 Output Pose를 구성합니다.
점선은 데이터 공급, 실선은 포즈 연결입니다. 일반 Blueprint 실행 선을 뜻하지 않습니다.
두 종류의 연결을 따로 읽습니다
변수는 상태 선택·블렌딩의 입력이고 포즈는 애니메이션 평가의 결과입니다. 모든 게임플레이 이벤트가 이 포즈 경로를 한 번씩 실행한다는 뜻은 아닙니다.
위 그림은 지상 이동 예제에서 값과 포즈가 흐르는 길을 두 종류의 선으로 나누어 보여 줍니다. 왼쪽의 Event Graph는 소유한 Pawn이 유효한지 확인한 뒤, 그 Pawn의 수평(XY) 속도로 Speed 변수를 갱신합니다. 가운데의 State Machine은 전환 규칙과 상태 안의 플레이어 노드에서 이 Speed를 읽어 포즈를 만들고, 그 포즈를 오른쪽의 Output Pose로 넘깁니다. 그림의 점선 두 개는 변수를 갱신하고 읽는 데이터 공급이고, 실선은 State Machine에서 최종 Output Pose로 전달되는 포즈입니다.
그림 아래의 설명처럼, 실선은 일반 블루프린트의 실행 선이 아닙니다. 변수는 상태를 고르고 블렌딩할 때 쓰는 입력이고, 포즈는 애니메이션을 평가한 결과입니다. 그래서 게임플레이 이벤트가 하나 일어날 때마다 이 포즈 경로가 한 번씩 실행된다고 읽으면 안 됩니다. 이벤트 그래프가 값을 갱신하는 일과 애님 그래프가 포즈를 평가하는 일은 각자의 시점에 일어나고, 둘은 변수를 통해서만 만납니다.
애님 그래프를 이루는 노드
애님 그래프는 여러 노드를 이어 캐릭터의 최종 포즈를 결정하는 파이프라인을 만듭니다. 자주 쓰는 노드와 에셋을 하나씩 살펴보겠습니다.
스테이트 머신
스테이트 머신(State Machine)은 Idle, Walk, Run, Jump, Attack처럼 캐릭터가 있을 수 있는 상태와, 상태 사이를 오가는 전환 규칙을 정의하는 노드입니다. 각 상태 안에는 그 상태에서 재생할 애니메이션이나 블렌딩 로직이 들어갑니다. 걷다가 달리기로 바뀌거나 점프에서 착지로 바뀌는 것처럼, 캐릭터의 행동이 바뀔 때 애니메이션도 자연스럽게 바꾸는 데 쓰며, 애님 그래프에서 가장 많이 쓰는 구성 요소입니다. 자세한 구성은 다음 글에서 다룹니다.
블렌드 스페이스
블렌드 스페이스(Blend Space)는 한 축 또는 두 축의 공간에 여러 애니메이션을 배치하고, 입력값에 따라 그 사이를 보간(interpolation)해 연속적인 애니메이션을 만드는 에셋입니다. 예를 들어 이동 속도 0에서 600 사이, 또는 Calculate Direction 노드가 돌려주는 -180도에서 180도 사이의 방향 값에 따라 걷기와 달리기를 부드럽게 섞습니다. 애님 그래프 안에서는 블렌드 스페이스 플레이어(Blend Space Player) 노드로 사용하며, 축과 샘플을 설정하는 방법은 블렌드 스페이스 기본 사용법에서 다룹니다.
애님 몽타주와 슬롯
애님 몽타주(Anim Montage)는 애니메이션 시퀀스(Animation Sequence) 여러 개를 시간 축에 배치해 하나의 복합 애니메이션으로 만드는 에셋입니다. 공격, 스킬 사용, 피격처럼 한 번 재생하고 끝나는 동작에 주로 씁니다. 평소에는 걷기와 달리기를 재생하다가 공격 버튼을 누르면 공격 몽타주를 재생해, 상체는 공격하고 하체는 이동 동작을 유지하는 식의 겹친 애니메이션을 만들 때 유용합니다.
몽타주가 애님 그래프의 포즈에 끼어들려면 몽타주가 쓰는 슬롯(Slot) 이름과 애님 그래프에 놓은 Slot 노드의 이름이 같아야 합니다. 상체에만 적용하려면 뒤에서 볼 Layered Blend Per Bone의 뼈 필터나 블렌드 마스크도 함께 설정합니다. 몽타주는 애님 몽타주와 노티파이의 기초에서 직접 만들어 봅니다.
포즈 블렌딩 노드
포즈 블렌딩 노드는 여러 포즈를 조합하거나 섞는 노드입니다. Blend Poses by bool은 불리언 값에 따라 두 포즈 중 하나로 전환하며, 점프 중인지 아닌지로 포즈를 바꾸는 경우가 한 예입니다. Blend Poses by int와 Blend Poses by enum은 정수나 열거형 값에 따라 여러 포즈 중 하나를 고르거나 섞으므로, 무기 종류에 따라 공격 포즈를 바꿀 때 쓸 수 있습니다.
Layered Blend Per Bone은 기준 포즈 위에 다른 포즈를 뼈별 가중치로 섞습니다. 브랜치 필터(Branch Filter)에 시작 뼈를 지정하면 그 뼈와 자손 뼈에만 섞을 포즈가 적용되고, 블렌드 마스크(Blend Mask)로 적용 부위를 정할 수도 있습니다. 하체는 걷고 상체는 총을 겨누는 동작이 대표적인 예입니다.
시퀀스 플레이어와 Output Pose
시퀀스 플레이어(Sequence Player)는 애니메이션 시퀀스 에셋 하나를 그대로 재생하는 노드로, 주로 스테이트 머신의 상태 안에서 씁니다. 애님 그래프의 모든 포즈 연결은 마지막에 Output Pose 노드로 모여야 합니다. 이 노드가 받은 최종 포즈가 매 프레임 스켈레탈 메시에 적용되어 캐릭터가 화면에 그려지며, Output Pose에 닿지 않은 포즈는 아무리 잘 만들어도 메시에 반영되지 않습니다. 언리얼 엔진 4에서는 이 노드를 Final Animation Pose라고 불렀지만, 5.8의 애님 그래프에서는 Output Pose로 표시됩니다.
Idle과 WalkRun 상태 머신 연결하기
가장 기본적인 애님 그래프는 상태 안의 Sequence Player나 Blend Space Player가 포즈를 만들고, State Machine이 지금 활성인 상태와 전환 중인 블렌드를 평가해 그 결과를 최종 Output Pose에 넘기는 구조입니다. 이 흐름을 Idle과 WalkRun 두 상태로 연결해 보겠습니다.
아래에 나오는 에셋 이름은 예시이며 프로젝트에 자동으로 생기는 이름이 아닙니다. 먼저 실제로 적용할 스켈레탈 메시와 호환되는 스켈레톤, Idle 시퀀스, 이동 시퀀스를 준비합니다. 아직 이동용 블렌드 스페이스가 없다면 다음 두 글에서 축과 샘플을 만든 뒤 이 연결을 완성해도 됩니다. 또 이 글에서는 연결을 읽기 쉽도록 속도 0을 기준으로 전환하지만, 다음 글의 실습은 아주 작은 속도를 멈춤으로 보기 위해 0.1을 기준으로 씁니다.
먼저 애님 블루프린트를 만듭니다. 콘텐츠 브라우저의 Add(+) 버튼에서 Animation > Animation Blueprint를 고르고 캐릭터의 스켈레톤을 선택해 만들거나, 스켈레탈 메시 에셋을 우클릭해 Create > Anim Blueprint를 고릅니다. 만든 에셋을 더블클릭해 애님 블루프린트 에디터를 열고 AnimGraph로 갑니다. State Machine이 없다면 하나 추가해 이름을 Default State Machine으로 정하고, 그 포즈 출력을 Output Pose에 연결합니다.
다음으로 Default State Machine 노드를 더블클릭해 안으로 들어갑니다. 빈 곳을 우클릭해 Add State로 Idle 상태를 추가하고, 같은 방법으로 WalkRun 상태를 하나 더 추가합니다. 그리고 Entry 노드를 Idle에 연결해 처음 시작할 상태를 정합니다.
이제 상태 사이의 전환 규칙을 만듭니다. Idle 상태의 테두리에서 WalkRun 상태로 드래그해 선을 이으면 그 선이 전환 규칙이 됩니다. 선 위의 규칙 아이콘을 더블클릭하면 전환 규칙 그래프가 열리고, 여기서 Can Enter Transition 핀에 들어갈 조건을 만듭니다. 조건에는 Speed 변수가 0보다 큰지를 둡니다. 아직 Speed 변수가 없다면 마이 블루프린트(My Blueprint) 패널에서 Float 타입의 Speed 변수를 먼저 추가하고, 이 값을 갱신하는 이벤트 그래프는 다음 글의 '이벤트 그래프에서 Speed 갱신하기' 절에서 연결합니다. 반대 방향으로 WalkRun에서 Idle로도 선을 잇고, 그 규칙에는 Speed가 0과 같은지를 확인하는 조건을 둡니다.
마지막으로 각 상태 안의 애니메이션을 지정합니다. Idle 상태를 더블클릭해 내부 그래프를 열고, Idle 애니메이션 시퀀스 에셋을 끌어다 놓아 플레이어 노드를 만든 뒤 그 포즈를 상태의 Output Animation Pose에 연결합니다. WalkRun 상태 안에는 속도 축을 쓰는 블렌드 스페이스 에셋을 끌어다 놓고, 포즈 출력을 Output Animation Pose에, Speed 변수를 속도 입력에 연결합니다. 그래프를 다 만들었다면 캐릭터의 Mesh 컴포넌트에서 Animation Mode를 Use Animation Blueprint로, Anim Class를 만든 애님 블루프린트로 지정합니다. 공식 문서도 강조하듯 애님 블루프린트는 메시에 지정하기 전까지 아무 효과가 없습니다.
이렇게 연결하면 애님 그래프는 캐릭터의 움직임과 상태를 노드로 정의하고, 변수 값에 따라 포즈를 만드는 흐름을 바꿉니다. 결과가 기대와 다를 때는 그림에서 본 두 길을 따로 확인합니다. 변수가 제대로 갱신되는지는 이벤트 그래프에서, 만든 포즈가 메시까지 도달하는지는 상태 안의 플레이어, 바깥의 State Machine, Output Pose, 메시의 Anim Class 순서로 확인합니다.
더 깊이: 이벤트 그래프의 계산을 워커 스레드로 옮기기
게임 스레드에서 차례로 실행되는 이벤트 그래프의 부담을 덜기 위해, 엔진은 계산을 워커 스레드(worker thread)로 옮기는 경로를 제공합니다. 애니메이션 최적화 문서에 따르면, 함수의 디테일 패널에서 Thread Safe를 켠 함수에 계산을 담고 Blueprint Thread Safe Update Animation을 오버라이드해 그 함수들을 부르면, 이 계산은 워커 스레드에 여유가 생길 때 동시에 평가될 수 있습니다. 문서는 애님 블루프린트에서 가장 비용이 큰 부분이 대개 이벤트 그래프의 로직이라고 설명하므로, 캐릭터가 많은 장면일수록 이 차이가 커집니다.
스레드 안전 함수는 다른 블루프린트나 컴포넌트에 직접 접근할 수 없으므로, 폰의 속도 같은 값은 속성 접근(Property Access) 노드로 읽어 옵니다. 문서는 이것을 다른 객체가 값을 애님 블루프린트에 밀어 넣는 대신, 애님 블루프린트가 값을 끌어와야 한다고 표현합니다. 이 경로로 옮기기 전에 이벤트 그래프가 다른 객체의 값을 어떻게 받고 있는지부터 확인하는 이유가 여기에 있습니다.
애님 그래프 쪽에도 비슷한 최적화가 있습니다. 노드의 입력에 멤버 변수를 계산 없이 그대로 연결하면, 블루프린트 가상 머신을 거치지 않고 값을 복사하는 패스트 패스(Fast Path)가 적용되며 그 노드의 오른쪽 위에 번개 모양 아이콘이 표시됩니다. 입력 앞에 곱셈 같은 계산을 하나만 넣어도 패스트 패스가 꺼지므로, 계산은 미리 변수에 담아 두고 애님 그래프에서는 읽기만 하는 편이 좋습니다. 애님 블루프린트의 Class Settings에서 Warn About Blueprint Usage를 켜면 패스트 패스를 쓰지 못한 곳을 컴파일 결과에 경고로 알려 줍니다.
정리
- 애님 블루프린트의 이벤트 그래프는 게임플레이 값을 읽어 애니메이션용 변수를 계산하고, 애님 그래프는 그 변수를 읽어 매 프레임 최종 포즈를 만듭니다.
- 애님 그래프의 포즈 연결은 실행 선이 아니며, 두 그래프는 변수를 통해서만 만납니다.
- 스테이트 머신은 상태와 전환 규칙을, 블렌드 스페이스는 입력값에 따른 보간을, 몽타주는 한 번 재생하는 동작을, 포즈 블렌딩 노드는 조건이나 뼈 범위에 따른 조합을 맡습니다.
- 모든 포즈는 Output Pose에 도달해야 메시에 반영되고, 애님 블루프린트는 메시의 Anim Class로 지정해야 효과가 있습니다.
- 몽타주를 애님 그래프에 섞으려면 몽타주의 슬롯 이름과 Slot 노드의 이름이 같아야 합니다.
연습 문제
1. 포즈가 메시까지 도달하는지 확인하기
상태 안의 Idle 플레이어 노드는 연결했지만, 바깥 AnimGraph에서 State Machine의 출력이 최종 Output Pose와 끊겨 있습니다. 이벤트 그래프의 Speed 값이 정상적으로 바뀌는 것을 확인했다면, 그 스테이트 머신의 포즈가 메시를 바꾼다고 결론 내릴 수 있을까요?
해설 보기
결론 내릴 수 없습니다. Speed는 상태를 고르는 입력 데이터일 뿐이며, 포즈를 메시에 적용하는 연결을 대신하지 않습니다. 변수 갱신과 포즈 전달은 그림에서 본 것처럼 서로 다른 길입니다.
상태 안의 플레이어 노드가 상태의 Output Animation Pose에 이어졌는지, 바깥의 State Machine이 최종 Output Pose에 이어졌는지, 메시의 Anim Class가 이 애님 블루프린트인지를 차례로 확인합니다. 상태 내부를 완성한 것과 메시가 그 애님 블루프린트를 사용하는 것은 각각 따로 확인해야 하는 사실입니다.
2. 걸으면서 공격하기
캐릭터가 걷는 동안 공격 버튼을 누르면 상체만 공격 동작을 하고 하체는 계속 걷게 하고 싶습니다. 공격 몽타주를 재생하는 것 외에 애님 그래프에 무엇을 준비해야 할까요?
해설 보기
먼저 애님 그래프에 Slot 노드를 두고, 그 슬롯 이름을 공격 몽타주가 쓰는 슬롯 이름과 맞춥니다. 이름이 다르면 몽타주를 재생해도 애님 그래프의 포즈에 끼어들지 못합니다.
그다음 Layered Blend Per Bone으로 이동 포즈를 기준 포즈에, 슬롯을 거친 공격 포즈를 섞을 포즈에 연결하고, 브랜치 필터의 시작 뼈를 척추 같은 상체의 뼈로 지정합니다. 그러면 그 뼈와 자손 뼈인 상체에만 공격 포즈가 적용되고, 하체는 이동 포즈를 유지합니다.
3. 정확히 0과 같은지 비교하기
WalkRun에서 Idle로 가는 전환 규칙을 Speed가 0과 같은지로 두었습니다. 다음 글의 실습이 0 대신 0.1이라는 기준을 쓰는 이유를 생각해 보세요.
해설 보기
Speed는 속도 벡터의 길이로 계산하는 실수(float)이므로, 캐릭터가 거의 멈췄어도 아주 작은 값이 남을 수 있습니다. 정확히 0과 같은지를 조건으로 두면 이런 미세한 값 때문에 멈춘 캐릭터가 WalkRun 상태에 남는 일이 생길 수 있습니다.
그래서 "0.1보다 작으면 멈춘 것으로 본다"처럼 여유를 둔 기준을 씁니다. 이 글의 0 기준은 연결을 읽기 쉽게 하려는 간단한 예이고, 실제 실습에서는 기준값을 정해 두 전환 규칙이 서로 겹치거나 비지 않게 맞춥니다.
애님 블루프린트를 만들고 메시에 지정하는 방법은 언리얼 엔진 공식 문서의 애니메이션 블루프린트에서, 이벤트 그래프와 애님 그래프의 역할은 애니메이션 블루프린트의 그래프 작성에서 확인할 수 있습니다.
다음 글 스테이트 머신의 기본 활용에서는 Idle과 Walk_Run 상태를 속도 기반 전환 규칙으로 잇고, 이동 상태 안에서 걷기와 달리기를 블렌딩합니다.