Source
    Characters
    CAnimInstance.h .cpp
CPlayer.h .cpp
    Utilities
    CHelper.h
CLog.h .cpp
    Global.h
CGameMode.h .cpp
U2212_06.Build.cs
    U2212_06.uproject
 

 

 

 

Player 초기 세팅하기

 


 

 

Utilities 폴더 + Global.h 파일 가져오기

 

Utilities 폴더 + Global.h 파일을 가져와서 재사용한다.

 

Global.h

더보기
#pragma once
#include "DrawDebugHelpers.h"
#include "Kismet/KismetSystemLibrary.h"
#include "Kismet/KismetMathLibrary.h"
#include "Kismet/GameplayStatics.h"
#include "Utilities/CHelpers.h"
#include "Utilities/CLog.h"

 

CHelpers.h

더보기
#pragma once
#include "CoreMinimal.h"
#define CheckTrue(x) { if(x == true) return; }
#define CheckTrueResult(x, y) { if(x == true) return y; }
#define CheckFalse(x) { if(x == false) return;}
#define CheckFalseResult(x, y) { if(x == false) return y;}
#define CheckNull(x) { if(x == nullptr) return;}
#define CheckNullResult(x, y) { if(x == nullptr) return y;}
#define CreateTextRender()\
{\
CHelpers::CreateComponent<UTextRenderComponent>(this, &Text, "Tex", Root);\
Text->SetRelativeLocation(FVector(0, 0, 100));\
Text->SetRelativeRotation(FRotator(0, 180, 0));\
Text->SetRelativeScale3D(FVector(2));\
Text->TextRenderColor = FColor::Red;\
Text->HorizontalAlignment = EHorizTextAligment::EHTA_Center;\
Text->Text = FText::FromString(GetName().Replace(L"Default__", L""));\
}
class U2212_06_API CHelpers
{
public:
template<typename T>
static void CreateComponent(AActor* InActor, T** OutComponent, FName InName, USceneComponent* InParent = nullptr, FName InSocketName = NAME_None)
{
*OutComponent = InActor->CreateDefaultSubobject<T>(InName);
if (!!InParent)
{
(*OutComponent)->SetupAttachment(InParent, InSocketName); //이렇게 사용하면 Socket Name에 _를 사용하면 안 된다.
return;
}
InActor->SetRootComponent(*OutComponent);
}
//CreateActorComponent 추가
template<typename T>
static void CreateActorComponent(AActor* InActor, T** OutComponent, FName InName)
{
*OutComponent = InActor->CreateDefaultSubobject<T>(InName);
}
template<typename T>
static void GetAsset(T** OutObject, FString InPath)
{
ConstructorHelpers::FObjectFinder<T> asset(*InPath);
*OutObject = asset.Object;
}
template<typename T>
static void GetAssetDynamic(T** OutObject, FString InPath)
{
*OutObject = Cast<T>(StaticLoadObject(T::StaticClass(), nullptr, *InPath));
}
template<typename T>
static void GetClass(TSubclassOf<T>* OutClass, FString InPath)
{
ConstructorHelpers::FClassFinder<T> asset(*InPath);
*OutClass = asset.Class;
}
template<typename T>
static T* FindActor(UWorld* InWorld)
{
for (AActor* actor : InWorld->GetCurrentLevel()->Actors)
{
if (!!actor && actor->IsA<T>())
return Cast<T>(actor);
}
return nullptr;
}
template<typename T>
static void FindActors(UWorld* InWorld, TArray<T*>& OutActors)
{
for (AActor* actor : InWorld->GetCurrentLevel()->Actors)
{
if (!!actor && actor->IsA<T>())
OutActors.Add(Cast<T>(actor));
}
}
template<typename T>
static T* GetComponent(AActor* InActor)
{
return Cast<T>(InActor->GetComponentByClass(T::StaticClass()));
}
template<typename T>
static T* GetComponent(AActor* InActor, const FString& InName)
{
TArray<T*> components;
InActor->GetComponents<T>(components);
for (T* component : components)
{
if (component->GetName() == InName)
return component;
}
return nullptr;
}
static void AttachTo(AActor* InActor, USceneComponent* InParent, FName InSocketName)
{
InActor->AttachToComponent(InParent, FAttachmentTransformRules(EAttachmentRule::KeepRelative, true), InSocketName);
}
};

 

CLog.h

더보기
#pragma once
#include "CoreMinimal.h"
#define LogLine(){ CLog::Log(__FILE__, __FUNCTION__, __LINE__); }
#define PrintLine(){ CLog::Print(__FILE__, __FUNCTION__, __LINE__); }
class U2212_06_API CLog
{
public:
static void Log(int32 InValue);
static void Log(float InValue);
static void Log(const FString& InValue);
static void Log(const FVector& InValue);
static void Log(const FRotator& InValue);
static void Log(const UObject* InValue);
static void Log(const FString& InFileName, const FString& InFuncName, int32 InLineNumber);
static void Print(int32 InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue);
static void Print(float InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue);
static void Print(const FString& InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue);
static void Print(const FVector& InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue);
static void Print(const FRotator& InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue);
static void Print(const UObject* InValue, int32 InKey = -1, float InDuration = 10, FColor InColor = FColor::Blue);
static void Print(const FString& InFileName, const FString& InFuncName, int32 InLineNumber);
};

 

CLog.cpp

더보기
#include "Utilities/CLog.h"
#include "Engine.h"
DEFINE_LOG_CATEGORY_STATIC(GP, Display, All)
void CLog::Log(int32 InValue)
{
//GLog->Log("GP", ELogVerbosity::Display, FString::FromInt(InValue));
UE_LOG(GP, Display, L"%d", InValue);
}
void CLog::Log(float InValue)
{
UE_LOG(GP, Display, L"%f", InValue);
}
void CLog::Log(const FString & InValue)
{
UE_LOG(GP, Display, L"%s", *InValue);
}
void CLog::Log(const FVector & InValue)
{
UE_LOG(GP, Display, L"%s", *InValue.ToString());
}
void CLog::Log(const FRotator & InValue)
{
UE_LOG(GP, Display, L"%s", *InValue.ToString());
}
void CLog::Log(const UObject * InValue)
{
FString str;
if (!!InValue)
str.Append(InValue->GetName());
str.Append(!!InValue ? " Not Null" : "Null");
UE_LOG(GP, Display, L"%s", *str);
}
void CLog::Log(const FString & InFileName, const FString & InFuncName, int32 InLineNumber)
{
//C:\\Test\\Test.cpp
int32 index = 0, length = 0;
InFileName.FindLastChar(L'\\', index);
length = InFileName.Len() - 1;
FString fileName = InFileName.Right(length - index);
UE_LOG(GP, Display, L"%s, %s, %d", *fileName, *InFuncName, InLineNumber);
}
void CLog::Print(int32 InValue, int32 InKey, float InDuration, FColor InColor)
{
GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, FString::FromInt(InValue));
}
void CLog::Print(float InValue, int32 InKey, float InDuration, FColor InColor)
{
GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, FString::SanitizeFloat(InValue));
}
void CLog::Print(const FString & InValue, int32 InKey, float InDuration, FColor InColor)
{
GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, InValue);
}
void CLog::Print(const FVector & InValue, int32 InKey, float InDuration, FColor InColor)
{
GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, InValue.ToString());
}
void CLog::Print(const FRotator & InValue, int32 InKey, float InDuration, FColor InColor)
{
GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, InValue.ToString());
}
void CLog::Print(const UObject * InValue, int32 InKey, float InDuration, FColor InColor)
{
FString str;
if (!!InValue)
str.Append(InValue->GetName());
str.Append(!!InValue ? " Not Null" : "Null");
GEngine->AddOnScreenDebugMessage(InKey, InDuration, InColor, str);
}
void CLog::Print(const FString& InFileName, const FString& InFuncName, int32 InLineNumber)
{
int32 index = 0, length = 0;
InFileName.FindLastChar(L'\\', index);
length = InFileName.Len() - 1;
FString fileName = InFileName.Right(length - index);
FString str = FString::Printf(L"%s, %s, %d", *fileName, *InFuncName, InLineNumber);
GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Blue, str);
}

 

 

CPlayer + BP_CPlayer 생성하기

 

새 C++ 생성하기 -  Character - CPlayer 생성

 

CPlayer.h

더보기
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "CPlayer.generated.h"
UCLASS()
class U2212_06_API ACPlayer : public ACharacter
{
GENERATED_BODY()
private:
UPROPERTY(VisibleAnywhere)
class USpringArmComponent* SpringArm;
UPROPERTY(VisibleAnywhere)
class UCameraComponent* Camera;
public:
ACPlayer();
protected:
virtual void BeginPlay() override;
public:
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};

 

 

 

CPlayer.cpp

더보기
#include "Characters/CPlayer.h"
#include "Global.h"
#include "CAnimInstance.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/InputComponent.h"
ACPlayer::ACPlayer()
{
CHelpers::CreateComponent<USpringArmComponent>(this, &SpringArm, "SpringArm", GetMesh());
CHelpers::CreateComponent<UCameraComponent>(this, &Camera, "Camera", SpringArm);
GetMesh()->SetRelativeLocation(FVector(0, 0, -90));
GetMesh()->SetRelativeRotation(FRotator(0, -90, 0));
USkeletalMesh* mesh;
CHelpers::GetAsset<USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Character/Mesh/SK_Mannequin.SK_Mannequin'");
GetMesh()->SetSkeletalMesh(mesh);
TSubclassOf<UCAnimInstance> animInstance;
CHelpers::GetClass<UCAnimInstance>(&animInstance, "AnimBlueprint'/Game/ABP_Character.ABP_Character_C'");
GetMesh()->SetAnimClass(animInstance);
SpringArm->SetRelativeLocation(FVector(0, 0, 140));
SpringArm->SetRelativeRotation(FRotator(0, 90, 0));
SpringArm->TargetArmLength = 200;
SpringArm->bDoCollisionTest = false;
SpringArm->bUsePawnControlRotation = true;
SpringArm->bEnableCameraLag = true;
GetCharacterMovement()->RotationRate = FRotator(0, 720, 0);
}
void ACPlayer::BeginPlay()
{
Super::BeginPlay();
}
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}

 

 

 

 

BP_CPlayer

새 C++ 클래스 생성 - (방금 전에 생성한) CPlayer -  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

CGameMode 생성

 

U_06GameModeBase를 CGameMode로 이름변경

 

CGameMode.h

더보기
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "CGameMode.generated.h"
UCLASS()
class U2212_06_API ACGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
ACGameMode();
};

 

 

 

CGameMode.cpp

더보기
#include "CGameMode.h"
#include "Global.h"
ACGameMode::ACGameMode()
{
CHelpers::GetClass<APawn>(&DefaultPawnClass, "Blueprint'/Game/Player/BP_CPlayer.BP_CPlayer_C'");
}

 

 

 

프로젝트 세팅 - 맵&모드 - Default Modes - 기본 게임모드 - CGameMode로 변경

 


 

 

CAnimInstance + ABP_Character 생성

 

새 C++ 클래스 - AnimInstance - CAnimInstance 생성

 

 

CAnimInstance.h

더보기
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimInstance.h"
#include "CAnimInstance.generated.h"
UCLASS()
class U2212_06_API UCAnimInstance : public UAnimInstance
{
GENERATED_BODY()
protected:
UPROPERTY(BlueprintReadOnly, Category = "Animation")
float Speed;
UPROPERTY(BlueprintReadOnly, Category = "Animation")
float Pitch;
UPROPERTY(BlueprintReadOnly, Category = "Animation")
float Direction;
public:
void NativeBeginPlay() override;
void NativeUpdateAnimation(float DeltaSeconds) override;
private:
class ACharacter* OwnerCharacter;
private:
FRotator PrevRotation;
};

 

 

 

CAnimInstance.cpp

더보기
#include "Characters/CAnimInstance.h"
#include "Global.h"
#include "GameFramework/Character.h"
void UCAnimInstance::NativeBeginPlay()
{
Super::NativeBeginPlay();
OwnerCharacter = Cast<ACharacter>(TryGetPawnOwner());
CheckNull(OwnerCharacter);
}
void UCAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
Super::NativeUpdateAnimation(DeltaSeconds);
CheckNull(OwnerCharacter);
Speed = OwnerCharacter->GetVelocity().Size2D();
FRotator rotator = OwnerCharacter->GetVelocity().ToOrientationRotator();
FRotator rotator2 = OwnerCharacter->GetControlRotation();
FRotator delta = UKismetMathLibrary::NormalizedDeltaRotator(rotator, rotator2);
PrevRotation = UKismetMathLibrary::RInterpTo(PrevRotation, delta, DeltaSeconds, 25);
Direction = PrevRotation.Yaw;
Pitch = UKismetMathLibrary::FInterpTo(Pitch, OwnerCharacter->GetBaseAimRotation().Pitch, DeltaSeconds, 25);
}

 

 

 

애니메이션 - 애니메이션 블루프린트 - ABP_Character 생성

 

 

 

 


 

 

 

실행화면