필요한 개념
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 변수는 에디터에 나타나지 않는다.
CPlayer에서 기본 애니메이션 세팅
Tip) C에서 항상 기본값을 세팅해라(메쉬, 애니메이션 등..)
다른 팀에서 BP에서 기본에서 다른걸로 수정
BindAction() // 액션 매핑을 키 입력에 따라 처리 가능
* CAnimInstance.cpp 및 CPlayer.cpp 참고 이미지
함수 그대로 CAnimInstance.cpp 및 CPlayer.cpp에 구현
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 |