본문 바로가기

언리얼 + cpp

언리얼C++ 6일차(애니메이션 블루프린트, 스테이트 머신, Control Rig)

애니메이션 블루프린트

언리얼 엔진에서 캐릭터의 골격(스켈레톤) 기반 애니메이션을 시각적으로 설계하는 데 특화된 전용 Blueprint다.

보통은 스켈레탈 메시, 애니메이션 시퀀스, State Machine 등을 연결하는 “중간 다리” 역할을 한다.

 

애니메이션 블루프린트에는 Anim 그래프와 Event 그래프가 있다.

Anim Graph (애니메이션 그래프)

입력 노드블렌딩 (Blend)출력 노드 (Output Pose) 순으로, 최종적으로 캐릭터가 어떤 포즈와 애니메이션을 취할지 결정합니다.

  • 예: 캐릭터가 걷기 (Walk)에서 달리기 (Run)로 전환할 때, 얼마나 부드럽게 (Blend Time) 섞어줄지, 또 속도에 따라 Walk 애니메이션과 Run 애니메이션의 비율을 어떻게 조절할지를 정의합니다.

Event Graph (이벤트 그래프)

이벤트 노드를 활용하여 C++ 혹은 게임 로직과 애니메이션을 연동할 수 있습니다.

  • 예) 공격 모션 중 특정 타이밍에 데미지를 가한다든지, Idle 상태가 5초 이상 지속될 경우 자동으로 ‘긴장 풀린’ 애니메이션을 재생하는 식의 이벤트 로직을 추가할 수 있습니다.

이벤트 그래프에서 캐릭터의 Movement Component 정보 받아오기

캐릭터의 Movement Component는 캐릭터의 이동 속도, 가속도, 점프, 낙하 여부 등 다양한 이동 관련 정보가 있다.

이 정보를 활용해서 캐릭터의 이동 상태(걷기, 달리기, 점프, 착지 등)에 따라 다른 애니메이션을 재생해야한다.

Event Blueprint Initialize Animation(BeginPlay)

  • 애니메이션 블루프린트가 초기화될 때(즉, 한 번만 호출) 실행되는 이벤트입니다.
  • 여기서 Get Owning Actor 노드로 현재 애니메이션을 재생 중인 액터를 가져옵니다.(JinCharacter)
  • 캐스팅(Cast to BP_Character)을 통해 사용 중인 캐릭터가 맞는지 확인하고, 성공하면 해당 객체를 Character 변수에 저장합니다.
  • Character에서 Get Character Movement 노드를 사용해 Movement Component를 얻어, 이를 CharacterMovement 변수에 저장합니다.

매 프레임마다 캐릭터의 수평 속도 가져오기

Event BlueprintUpdateAnimation(Tick) 노드는 프레임마다 호출되어 애니메이션 로직을 업데이트하는 핵심 이벤트입니다.

캐릭터의 현재 이동 속도, 가속도 등을 매번 체크하여 Anim Graph에서 참조할 변수를 계속 갱신합니다.

1. Valid 체크

  • 먼저 Character가 유효한지 (Null이 아닌지) Is Valid? 노드 등을 통해 확인합니다.
  • 캐릭터가 제대로 셋업되지 않았다면, 이후 로직을 수행하지 않도록 합니다.

2. Ground Speed 계산(수평 속도 계산)

  • CharacterMovement의 Get Velocity 노드로 캐릭터의 현재 속도 벡터(X, Y, Z)를 가져옵니다.

Sequence 0

  • Vector Length XY 노드를 사용해 X, Y 성분의 길이(즉, 2D 평면상의 속도)만 구합니다. float 변수에 저장합니다.
    • 이렇게 하면 캐릭터가 수평으로 어느 정도 빠르게 움직이고 있는지 알 수 있게 됩니다.
  • Z축 속도를 확인해야 하는 상황이 있기 때문에 전체 속도 벡터는 Velocity라는 Vector 변수에 저장해둡니다.

3. 캐릭터의 움직임 여부 저장하기

  • 캐릭터가 정지 상태 (Idle) 인지 이동 중 (Walk/Run) 인지를 구분하는 기본적인 로직을 구현해봅시다.

Sequence 1

  • Ground Speed가 어느 정도 이상이면 (3.0f 이상) “캐릭터가 움직이고 있다”고 판단할 수 있습니다.
  • CharacterMovement의 Get Current Acceleration 노드로 현재 가속도 값을 가져올 수도 있습니다. 가속도 벡터가 (0, 0, 0)에 가깝다면, 입력 중이 아닌 상태라고 판단합니다.
  • 이동 여부와 사용자 입력(가속도 여부)을 AND 조건 등으로 조합해, "캐릭터가 실제로 이동 중인지”를 판정하는 변수를 만들어 둘 수 있습니다. bShouldMove = (Ground Speed > 3.0) AND (Acceleration != 0)

4. 캐릭터의 낙하 여부 저장하기

  • CharacterMovement의 Is Falling 함수를 사용해 캐릭터가 공중에 떠 있는지 확인할 수 있습니다.
  • 점프를 했거나 플랫폼에서 떨어졌을 때 등, 캐릭터가 지면에 붙어있지 않으면 True가 반환됩니다.
  • 이를 bool 변수에 저장하면, Anim Graph 내에서 캐릭터가 점프나 낙하 관련 애니메이션으로 전환하도록 제어할 수 있습니다.

스테이트 머신(State Machine)

  • 언리얼 엔진의 애니메이션 시스템에서, 캐릭터의 상태(Idle, Walk, Run, Jump 등)에 따라 어떤 애니메이션을 재생하고, 어떻게 전환할지를 결정하기 위한 논리적 구조입니다.
  • 가장 쉽게 이해하자면, “Idle 상태이면 Idle 애니메이션을 재생하고, 캐릭터가 움직이기 시작하면 Walking 애니메이션으로 전환한다.” 같은 로직을 직관적으로 구성하게 해줍니다.

State Machine의 핵심 개념

  1. State(상태)
    • 캐릭터가 현재 어떤 동작을 하고 있는지 나타냅니다.
    • 예) Idle, Walking, Running, Jumping 등이 각각 하나의 상태가 될 수 있습니다.
  2. Transition(전환)
    • 한 상태에서 다른 상태로 언제 전환되는지 조건(Condition)을 정의합니다.
    • 예) Idle → Walking 전환 조건: “속도 > 0” (즉, 캐릭터가 이동을 시작)
  3. Animation Graph와의 연결
    • State Machine 내부의 상태 (State)는 실제로 재생할 애니메이션을 배치하는 장소입니다.
    • State 간 전환 조건을 만족하면 다른 애니메이션이 재생되도록 합니다.

State Machine 노드를 Output Pose 쪽에 연결하면 State Machine에서 나온 결과가 캐릭터 최종 포즈가 된다.

각 상태에 맞게 애니메이션 에셋을 연결해주고 이벤트 그래프에서 만들어둔 변수를 활용해서 상태의 전환 조건도 설정한다.

Control Rig 설정

스테이트 머신에서 나온 포즈를 한 번 더 가공하거나, Foot IK (지형이 울퉁불퉁해도 발을 지면에 맞추는 기능) 같은 것을 적용하기 위해 사용하는 노드이다.

  • Control Rig를 클릭하고 Details 창에서 Control Rig Calss를 CR_Mannequin_BasicFootIK로 지정해줍니다.(프로젝트에 존재하는 IK용 Control Rig 에셋이다.)
  • Set Initial Transforms From Mesh” 옵션에 체크를해줍니다.
    • 이 옵션은 “현재 스켈레탈 메쉬 (Anim Graph에서 넘어온 포즈)의 뼈 변환을 그대로 초기값으로 사용하겠다”는 의미다.
    • 매 프레임 “State Machine에서 계산된 포즈”를 기반으로 Control Rig이 추가적인 IK나 변형을 진행하게 됩니다.
  • Input과 Output 카테고리 둘 다 ShouldDoIKTrace - Use Pin에 체크를 해둡니다.
    • 보통 CR_Mannequin_BasicFootIK에서는 ShouldDoIKTrace (또는 이와 유사한 이름의 Boolean 값)가 있어서, 실제로 발 위치를 추적 (Trace)할 것인지를 결정합니다.
    • Use Pin”에 체크하게 되면, 이 값이 Anim Graph나 Blueprint에서 핀으로 연결 가능하게 됩니다.
      • 즉, “캐릭터가 공중에 있을 땐 발 IK 안 쓰고, 지면 위에서만 발 IK 사용” 등 조건에 따라 사용 가능하게 되는겁니다.

기존에 만든 Locomotion 스테이트 머신을 캐시 포즈로 저장하여 다른 곳에서 재활용 하기 쉽게 만든다.

현재 Locomotion에는 Idle, Walk/Run(Blend) 상태가 저장돼있다.

메인 스테이트 머신을 만들어서 아래와 같이 연결한다.

1. Locomotion (걷기/뛰기) State

캐시 포즈로 저장한 Locomotion 포즈를 연결

2. Land(착지) State

Locomotion 상태에서 넘어온 포즈를 Apply Additive노드로 적절히 착지 모션을 섞어줍니다.

  • Land → Locomotion 전환 조건 (Transition rule 설정)
    • 전환 조건을 2개를 설정해야한다. 두 번 드래그하면 두 개의 조건이 생성이 된다.
    •  첫 번째 조건은 bShouldMove == true, 두 번째 조건은 Details 창에서 애니메이션 시퀀스 재생 완료하면 자동으로 State가 변할 수 있는 조건인 “Automatic Rule Based on Sequence Player in State”에 체크를 합니다.

 

3. Fall Loop(낙하) State

떨어지는 동안 반복 재생하기 위해 Loop Animation을 체크해둡니다.

 

4. Jump(점프) State

Jump -> Fall Loop 전환 조건은 Jump 시퀀스가 끝나면 자동으로 Fall Loop로 전환되게끔 Automatic Rule Based on Sequence Player in State에 체크합니다.

 

5. To Land(공중에 있는 = 지면으로 향하는) 그룹(State Alias)

  • State Alias는 대규모 State Machine에서 여러 상태를 한 번에 관리하기 유용합니다.
  • Jump, Fall Loop 두 상태를 To Land State 그룹으로 묶어줍니다.

  • To Land -> Land  전환 조건

  • bIsFalling == false가 되면 Land로 전환하도록 설정합니다. 공중에서 착지로 상태 전환을 해야하는 상황들을 가리킵니다.

6. To Falling 그룹

  • Locomotion, Land 두 상태를 To Falling State 그룹으로 묶어줍니다.

  • To Falling -> Jump 전환 조건
    • Z축 속도가 일정 값(예: 100) 이상이고, bIsFalling == true라면 점프 상태로 인식한다.

  • To Falling -> Fall Loop 전환 조건
    • 바닥에 있다가 공중으로 전환되는 상황을 말합니다