본문 바로가기

Unreal Engine 4/C++

<Unreal C++> 10 - UAnimInstance

 

필요한 개념

 


AnimInstance는 클래스 생성시
에디터에서 모든 클래스 표시 -> AnimInstance를 상속 받아서 만든다.

BlueprintReadOnly : 블루프린트 읽기 전용, Protected: 여야함(이 클래스를 상속받은 BP에서 접근해야하니까)
EditAnyWhere : 액터가 아닌 클래스에서 에디터에 변수를 공개할 때 반드시 이것으로 지정해줘야 에디터에 나타난다.

AnimInstance BP에 있던 이벤트 그래프 기존 노드들이 전부 C로 들어간다고 보면 된다.

BP에서
float Speed를 구할때 Player의 GetVelocity(방향 벡터를 구하고) 이 결과를 VectorLengthXY(크기를 구해서) Speed로 지정해주었다.
Blueprint Update Animation 이벤트는 매 프레임 마다 콜되는 거였고 애니메이션에 소속된 Pawn을 가져오는 것이(Try Get Pawn Owner) 였다.

부모의 오버라이딩된 virtual이 붙은 것들을 파고들어가서 보면 파악이 가능하다.
재정의가 가능해서 필요하면 재정의 하면됨
virtual void NativeInitalizeAnimation(); -> 최초로 애니메이션이 초기화 될때
virtual void NativeUpdateAnimation(float DeltaSeconds); -> 이게 애니메이션이 매프레임마다 업데이트 되는 부분(BP에서 Blueprint Update Animation 이벤트와 같음), 이 함수가 BP함수 Blueprint Update Animation를 콜함,  Blueprint Update Animation 함수는 virtual이 아니여서 재정의할 수 없다. 그래서 재정의할 수 있는 여기 함수를 사용함
virtual void NativeBeginPlay(); -> 게임에서 애니메이션 블루프린트가 실행될때



override 키워드는 언리얼에서 필수다.


BP생성해서 변수 콜했는데 카테고리뜨는게 마음에 안들면
매크로 정의하는 부분에서 카테고리에 원하는 텍스트를 넣어서 하면 된다. 그러면 이렇게 생성된다.
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Animation")
float Speed;

먄약 Speed 변수에 EditAnywhere가 명시되어 있지 않았다면 Speed 변수는 에디터에 나타나지 않는다.

 

 

EditAnywhere시에 Speed 에디터에 표시됨

 



CPlayer에서 기본 애니메이션 세팅

Tip) C에서 항상 기본값을 세팅해라(메쉬, 애니메이션 등..)
다른 팀에서 BP에서 기본에서 다른걸로 수정


BindAction() // 액션 매핑을 키 입력에 따라 처리 가능

 

* CAnimInstance.cpp 및 CPlayer.cpp 참고 이미지

 

함수 그대로 CAnimInstance.cpp 및 CPlayer.cpp에 구현

 

AnimationBP 이벤트 그래프

 

 

CharacterBP 액션 이벤트 처리

 

 

CAnimInstance.h


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

#pragma once

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

/**
 * 
 */
UCLASS()
class UONLINE_03_CPP_API UCAnimInstance : public UAnimInstance
{
	GENERATED_BODY()


	
protected:
	// BlueprintReadOnly : 블루프린트 읽기 전용, Protected : 여야함(이 클래스를 상속받은 BP에서 접근해야하니까)
	// EditAnyWhere : 액터가 아닌 클래스에서 에디터에 변수를 공개할 때 반드시 이것으로 지정해줘야 에디터에 나타난다.
	// 블루프린트에서 읽을 수 있도록
	// EditAnywhere를 써야 에디터에 공개가 됨(그래야 AnimInstance BP에 나타남)
	// speed는 속도에 따라 애니메이션 움직임 같은거 처리할려고 
	UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Animation")
		float Speed;

public:
	// override 키워드는 언리얼에서 필수다.	
	virtual void NativeBeginPlay() override;
	virtual void NativeUpdateAnimation(float DeltaSeconds) override;

private:
	// 원래는 ACPlayer로 직접가져와도 되지만 이런 이유는?
	// 나중에 건 슈팅모드 만들때, 캐릭터에도 총이 붙을 수 있고, 적에도 총이 붙을 수 있어서
	class ACharacter* OwnerCharacter;
};

 

 

 

 

 

 

 

CAnimInstance.cpp


더보기
#include "CAnimInstance.h"
#include "Global.h"
#include "GameFramework/Character.h"

void UCAnimInstance::NativeBeginPlay()
{
	// 부모 함수 호출
	Super::NativeBeginPlay();

	// TryGetPawnOwner : 애니메이션에 소속된 Pawn을 가져옴
	// Pawn가져와서 ACharacter로 캐스팅해서 값을 넣었다.
	// GameMode일때만 TryGetPawnOwner가 값이있다. GameMode가 아닐시 NULL이 됨
	OwnerCharacter = Cast<ACharacter>(TryGetPawnOwner());
}

void UCAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
	// 부모 함수 호출
	Super::NativeUpdateAnimation(DeltaSeconds);

	// 애니메이션 BP는 에디터 모드에서 열어도 동작을 함(게임모드가 아니어도)
	// CheckNull : NULL인지 체크 
	CheckNull(OwnerCharacter);

	// 우리는 2D 크기로 항상 얻어옴
	// Size2D() 함수가 BP에서는 VectorLengthXY()이다. 즉 방향백터의 크기를 얻어옴
	// Size2D()가 VectorLengthXY()를 콜함
	// VectorLengthXY()는 C에서는 VSizeXY(FVector A) 함수이다.
	// float UKismetMathLibrary::VSizeXY(FVector A) 
	// {
	//	return A.Size2D();
	// }
	// 이다.
	// FMath::Sqrt(X*X + Y*Y);
	Speed = OwnerCharacter->GetVelocity().Size2D();

	
}

 

 

 

 

 

CPlayer.h 추가된 내용


더보기
...

UCLASS()
class UONLINE_03_CPP_API ACPlayer : public ACharacter
{
  ...
private:
	// ActionMapping은 축 매핑과 다르게 Pressed냐 Released냐만 있다. (Key는 따로 없음)
	// 그래서 액션 매핑일때는 따로 파라미터를 넣지 않음
	void OnRunning();
	void OffRunning();
};

 

 

 

 

 

CPlayer.cpp 추가된 내용


더보기
ACPlayer::ACPlayer()
{
	...
	// 기본 애니메이션 세팅
	TSubclassOf<UAnimInstance> animInstance;
	// 클래스 불르기
	CHelpers::GetClass<UAnimInstance>(&animInstance, "AnimBlueprint'/Game/ABP_CPlayer.ABP_CPlayer_C'");
	GetMesh()->SetAnimInstanceClass(animInstance);
}

void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	...
    
	// BindAction : 키 입력 상황에 따라 함수를 연결함
	/*
	enum EInputEvent
	{
		IE_Pressed              =0, // 눌렀는지
		IE_Released             =1, // 떼었는지
		IE_Repeat               =2, // 눌르고 있는지
		IE_DoubleClick          =3, // 더블클릭했는지
		IE_Axis                 =4, // 축으로 사용할건지
		IE_MAX                  =5,
	};
	
	*/
	// 1 : 액션 이벤트 이름 2 : 키의 누른 상태, 3 : 함수 주소를 가진 객체 4 : 실행 될 함수
	PlayerInputComponent->BindAction("Running", EInputEvent::IE_Pressed, this, &ACPlayer::OnRunning);
	PlayerInputComponent->BindAction("Running", EInputEvent::IE_Released, this, &ACPlayer::OffRunning);
}


void ACPlayer::OnRunning()
{
	// 이 속도만 높여줌
	GetCharacterMovement()->MaxWalkSpeed = 600;
}

void ACPlayer::OffRunning()
{
	GetCharacterMovement()->MaxWalkSpeed = 400;
}

 

 

 

 

Defines.h


더보기
#pragma once

// 매크로를 넣음

// 함수 내에서 쓰면 return하면 됨
#define CheckNull(p) {if(p == NULL) return;}
// 그러나 함수 내에 리턴값이 있다면 값을 리턴해야 하니까
#define CheckNullResult(p, result) {if(p == NULL) return result;}

#define CheckTrue(p) {if(p == true) return;}
#define CheckTrueResult(p, result) {if(p == true) return result;}

#define CheckFalse(p) {if(p == false) return;}
#define CheckFalseResult(p, result) {if(p == false) return result;}

 

 

 

 

 

 

 

Global.h 추가된 내용


더보기
...

#include "Utillites/Defines.h"

 

 

 

 

 

 

결과


애니메이션 추가 및 뛰는것도 가능하다.

 

'Unreal Engine 4 > C++' 카테고리의 다른 글

<Unreal C++> 12 - DrawDebug  (0) 2022.04.07
<Unreal C++> 11 - Debug(출력로그, 게임창)  (0) 2022.04.07
<Unreal C++> 9 - PlayerInputComponent  (0) 2022.04.04
<Unreal C++> 8 - Player  (0) 2022.04.04
<Unreal C++> 7 - Material  (0) 2022.04.04