UnrealEngine5/프로젝트

[UE5] Blueprint 프로젝트를 C++로 (4) Animation State Machine, Blend Space와 Blend Node, 완료

왹져박사 2025. 4. 23. 16:21

애니메이션 설정하기 

1) Anim Instance 생성

 

2) 애니메이션 블루프린트 생성

캐릭터의 스켈레톤과 위에서 생성한 애님인스턴스 설정

 

CharacterBase의 AnimInstance class 참조 변경

	// set animation blueprint.
	ConstructorHelpers::FClassFinder<UAnimInstance> AnimInstanceClassRef(TEXT("/Game/Animations/Alien/ABP_MABCharacter.ABP_MABCharacter_C"));
	if (AnimInstanceClassRef.Succeeded())
	{
		GetMesh()->SetAnimInstanceClass(AnimInstanceClassRef.Class);
	}

 

확인

 

3) 생성한 AnimInstance 설정하기

애니메이션 상태머신을 관리하고 업데이트를 위하여 AnimInstance에서 다음 함수를 상속한다. 

NativeInitializeAnimation(): 생성시 호출

NativeUpdateAnimation(float DeltaSeconds): 매 프레임 호출

AnimInstance.h

주석에는 Update에서 데이터를 수집 후, ThreadSafeUpdate에서 작업을 진행하는 것을 권장한다. 

언리얼은 같은 네이밍의 파이프라인 단계는 같은 시점에 진행된다. 

객체들 간의 상호작용 중 안전하게 모든 데이터를 주고받은 후, 잘못된 값 또는 null참조를 막기 위한 단계 구분인 것이다. 

 

다음과 같이 현재 캐릭터가 움직이고 있는지 정보를 가져와 애님인스턴스를 업데이트하는 과정을 작성하였다. 

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Animation/AnimInstance.h"
#include "MABAnimInstance.generated.h"

/**
 * 
 */
UCLASS()
class MAB_API UMABAnimInstance : public UAnimInstance
{
	GENERATED_BODY()
	
public:
	UMABAnimInstance();

protected:
	virtual void NativeInitializeAnimation() override;

	virtual void NativeUpdateAnimation(float DeltaSeconds) override;

protected:
	// 소유 객체. 
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Character)
	TObjectPtr<class ACharacter> Owner;

	// Character Movement.
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Character)
	TObjectPtr<class UCharacterMovementComponent> Movement;

	// 현재 속도. 
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Character)
	FVector Velocity;

	// 땅 위에서의 속력.
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Character)
	float GroundSpeed;

	// 현재 Idle 상태인지 저장. 
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Character)
	uint8 bIsIdle : 1;

	// 움직임 여부 확인 한계값.
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Character)
	float MovingThreshold;

	// 현재 Hide 상태인지 저장. 
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Character)
	uint8 bIsHide : 1;

	// 현재 무기를 들고있는 상태인지 저장. 
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Character)
	uint8 bHoldWeapon : 1;
};

 

 

4) State Machine 생성하기

 

state machine 내부에 Locomotion State 추가

 

Idle과 Jog를 Blend한 결과를 cache로 저장하여 Locomotion에서 가져와 실행할 것이다. 

 

 

Blend 할 Idle과 Jog를 처음과 끝에 배치한다. 

 

Axis Setting에서 가로축의 값을 설정하여 값 변화에 따른 애니메이션 블렌드를 할 수 있다. 

위에서 속도를 받아오는 변수인 GroundSpeed를 기준으로 한다. 

 

이렇게 만든 BlendSapce를 끌어다가 State안에 배치한다. 

GetGroundSpeed를 연결하여 설정한다. 

 

이 state machine을 cache로 저장하고, 

 

다시 Main State Machine으로 돌아가 Locomotion state에 Locomotion Cache를 연결해 준다. 

 

 

결과 영상

 

 

 

// Blend Space vs Blend Pose

Blend Space

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/blend-spaces-in-unreal-engine

 

블렌드 스페이스는 설정한 값 변수를 기반으로 애니메이션간의 블렌딩을 할 수 있는 애니메이션 시스템이다. 

애니메이션 간의 보간을 통하여 자연스러운 블렌딩을 한다. 주로 속도와 같은 값을 사용한다. 

에셋으로 생성이 가능하고, 위와 같이 Animation Blueprint에서 레퍼런스로 참조하여 사용이 가능하다. 

 

Blend Node

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/animation-blueprint-blend-nodes-in-unreal-engine

 

블렌드 노드는 설정한 조건을 판단하여 애니메이션을 분기점에 따라 전환해 주는 Animation Blueprint의 노드이다. 

주로 상태 값을 조건으로 판별한다. 

Animaiont Blueprint 내부 노드로 생성이 가능하다. 

 

 

현재 진행하는 프로젝트에는 일반 Idle/Jog 말고도 Weapon을 들고 있는 상태, Hide 상태를 추가해 다음과 같이 구성하였다. 

모두 Locomotion이라고 판단하여 State가 아닌 Blend로 진행하였다. 

 

 


이제 블루프린트에서 cpp는 여기서 완료하고, 완전한 CPP 프로젝트를 시작할 것이다!