KoreanFoodie's Study
[언리얼] Helper Function : 오브젝트 생성 및 애셋 불러오기 본문
Game Dev/Unreal C++ : Dev Log
[언리얼] Helper Function : 오브젝트 생성 및 애셋 불러오기
GoldGiver 2022. 4. 19. 15:35
오브젝트 생성 및 애셋 불러오기
언리얼에서 오브젝트를 생성하고 애셋을 불러올 때는 보통 CreateDefaultSubobject 로 CDO 를 만들어 준 다음, ConstructorHelpers::FObjectFinder 로 애셋을 연결시켜 준다. 이 과정을 단축시켜주는 Helper Function 을 만들어 사용해 보자.
CHelpers.h
#pragma once
#include "CoreMinimal.h"
#include "Components/SkeletalMeshComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Particles/ParticleSystem.h"
#include "NiagaraSystem.h"
#include "NiagaraFunctionLibrary.h"
class UE_PROJECT_NAME_API CHelpers
{
public:
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(), NULL, *InPath));
}
template<typename T>
static void GetClass(TSubclassOf<T>* OutClass, FString InPath)
{
ConstructorHelpers::FClassFinder<T> asset(*InPath);
*OutClass = asset.Class;
}
template<typename T>
static void CreateComponent(AActor* InActor, T** OutComponent, FName InName, USceneComponent* InParent = NULL)
{
*OutComponent = InActor->CreateDefaultSubobject<T>(InName);
if (!!InParent)
{
(*OutComponent)->SetupAttachment(InParent);
return;
}
InActor->SetRootComponent(*OutComponent);
}
template<typename T>
static void CreateActorComponent(AActor* InActor, T** OutComponent, FName InName)
{
*OutComponent = InActor->CreateDefaultSubobject<T>(InName);
}
template<typename T>
static T* FindActor(UWorld* InWorld, int32 InIndex = 0)
{
TArray<AActor*> actors;
UGameplayStatics::GetAllActorsOfClass(InWorld, T::StaticClass(), actors);
if (actors.Num() < 1)
return NULL;
return Cast<T>(actors[InIndex]);
}
template<typename T>
static void FindActors(UWorld* InWorld, TArray<T*>& OutActors)
{
TArray<AActor*> actors;
UGameplayStatics::GetAllActorsOfClass(InWorld, T::StaticClass(), actors);
for (AActor* actor : actors)
{
T* obj = Cast<T>(actor);
if (!!obj)
OutActors.Add(obj);
}
}
static FLinearColor GetRandomColor()
{
FLinearColor color;
color.R = UKismetMathLibrary::RandomFloatInRange(0, 1);
color.G = UKismetMathLibrary::RandomFloatInRange(0, 1);
color.B = UKismetMathLibrary::RandomFloatInRange(0, 1);
color.A = 1.0f;
return color;
}
template<typename T>
static T* GetComponent(AActor* InActor)
{
return Cast<T>(InActor->GetComponentByClass(T::StaticClass()));
}
template<typename T>
static T* GetComponent(AActor* InActor, FString InComponentName)
{
TArray<T*> components;
InActor->GetComponents<T>(components);
for(T* component : components)
{
if (component->GetName() == InComponentName)
return component;
}
return NULL;
}
static FString GetStringFromEnum(FString InTypeName, int32 InIndex)
{
UEnum* ptr = FindObject<UEnum>(ANY_PACKAGE, *InTypeName, true);
return ptr->GetNameStringByIndex(InIndex);
}
static void PlayEffect(UWorld* InWorld, UFXSystemAsset* InEffect, FTransform& InTransform, USkeletalMeshComponent* InMesh = NULL, FName InSocketName = NAME_None)
{
UParticleSystem* particle = Cast<UParticleSystem>(InEffect);
UNiagaraSystem* niagara = Cast<UNiagaraSystem>(InEffect);
FVector location = InTransform.GetLocation();
FRotator rotation = FRotator(InTransform.GetRotation());
FVector scale = InTransform.GetScale3D();
if (InMesh)
{
if (particle)
{
UGameplayStatics::SpawnEmitterAttached(particle, InMesh, InSocketName, location, rotation, scale);
return;
}
if (niagara)
{
UNiagaraFunctionLibrary::SpawnSystemAttached(niagara, InMesh, InSocketName, location, rotation, scale, EAttachLocation::KeepRelativeOffset, true, ENCPoolMethod::None);
return;
}
}
if (particle)
{
UGameplayStatics::SpawnEmitterAtLocation(InWorld, particle, InTransform);
return;
}
if (niagara)
UNiagaraFunctionLibrary::SpawnSystemAtLocation(InWorld ,niagara, location, rotation, scale);
}
};
CreateActorComponent 로 UObject 를 생성하고, GetAsset 으로 애셋을 대입시킨다. GetComponent 로 특정 액터의 액터 컴포넌트를 조회할 수도 있다. GetActor 를 이용해 World 에 스폰된 액터들을 조회하거나, PlayEffect 를 이용해 파티클 시스템/나이아가라 시스템을 이용할 수도 있다.
예시 코드를 보자.
Example.cpp
CHelpers::CreateComponent<USpringArmComponent>(this, &SpringArm, "SpringArm", GetMesh());
CHelpers::CreateComponent<UCameraComponent>(this, &Camera, "SpringArm", SpringArm);
CHelpers::CreateActorComponent<UStatusComponent>(this, &Status, "Status");
USkeletalMesh* mesh;
CHelpers::GetAsset<USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Character/Mesh/SK_Mannequin.SK_Mannequin'");
GetMesh()->SetSkeletalMesh(mesh);
TSubclassOf<UAnimInstance> animInstance;
CHelpers::GetClass<UAnimInstance>(&animInstance, "AnimBlueprint'/Game/BP_CAnimInstance.BP_CAnimInstance_C'");
GetMesh()->SetAnimInstanceClass(animInstance);
...
ACharacter* OwnerCharacter;
State = CHelpers::GetComponent<UCStateComponent>(OwnerCharacter);
Status = CHelpers::GetComponent<UCStatusComponent>(OwnerCharacter);
'Game Dev > Unreal C++ : Dev Log' 카테고리의 다른 글
[언리얼] UPoseableMeshComponent 는 무엇일까? (1) | 2022.04.23 |
---|---|
[언리얼] 특정 액터에 Attached 된 액터 삭제하기 (0) | 2022.04.19 |
[언리얼] Helper Function - 로그 (Log) 2 : 화면에 출력하기 (0) | 2022.04.19 |
[언리얼] Helper Function - 로그 (Log) 1 : 콘솔에 출력하기 (0) | 2022.04.19 |
언리얼 실습용 게임 WithTheLight 기획 (0) | 2022.03.28 |
Comments