Unreal

[7강 숙제] 멤버 변수 및 멤버 함수 리플렉션 시스템 사용하기

(ꐦ •᷄ࡇ•᷅) 2025. 1. 23. 12:56

6강 숙제에 리플렉션 시스템을 활용해 보았다.

 

코드(Test1.h)

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Test1.generated.h"

UCLASS()
class PROJECTJS_API ATest1 : public AActor
{
	GENERATED_BODY()
	
public:	
	ATest1();

protected:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Test1|Components")
	USceneComponent* SceneRoot;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Test1|Components")
	UStaticMeshComponent* StaticMeshComp;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Test1|Properties")
	float SpeedZ;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Test1|Properties")
	float RotationSpeed;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Test1|Properties")
	float ScaleSpeed;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Test1|Properties")
	float MaxScale;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Test1|Properties")
	float MinScale;

	bool bIsScalingUp;

	virtual void BeginPlay() override;
	virtual void Tick(float DeltaTime) override;

	UFUNCTION(BlueprintCallable, Category = "Test1|Actions")
	void SetInitLocation();
};

 

UPROPERTY()

멤버 변수 대부분은 BP에서 수정이 가능하게 만들었으나 스케일 변경 로직에 연관이 있는 bIsScalingUp 변수는 중요하다 생각해 리플렉션 하지 않았다. 

 

UFUNCTION()

BeginPlay()에서 Location을 설정해 주던 것을 리플렉션하여 BP에서 실행할 수 있게끔 설정했다.

 

코드(Test1.cpp)

#include "Test1.h"

ATest1::ATest1()
{
	PrimaryActorTick.bCanEverTick = true;
	bIsScalingUp = true;

	SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
	SetRootComponent(SceneRoot);

	StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
	StaticMeshComp->SetupAttachment(SceneRoot);
}

void ATest1::BeginPlay()
{
	Super::BeginPlay();
}

void ATest1::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (!FMath::IsNearlyZero(SpeedZ))
	{
		SetActorLocation(GetActorLocation() + FVector(0.0f, 0.0f, SpeedZ * DeltaTime));
	}

	if (!FMath::IsNearlyZero(RotationSpeed))
	{
		AddActorLocalRotation(FRotator(0.f, 0.f, RotationSpeed * DeltaTime));
	}
	
	FVector CurScale = GetActorScale3D();
	if (bIsScalingUp)
	{
		CurScale += FVector(ScaleSpeed * DeltaTime);
		if (CurScale.X >= MaxScale)
		{
			CurScale = FVector(MaxScale);
			bIsScalingUp = false;
		}
	}
	else
	{
		CurScale -= FVector(ScaleSpeed * DeltaTime);
		if (CurScale.X <= MinScale)
		{
			CurScale = FVector(MinScale);
			bIsScalingUp = true;
		}
	}

	SetActorScale3D(CurScale);
}

void ATest1::SetInitLocation()
{
	FVector NewPosition(100.0f, 200.0f, 400.0f);
	FVector NewScale(2.0f, 2.0f, 2.0f);
	FRotator NewRotation(0.0f, 0.0f, 180.0f);

	FTransform NewTransform(NewRotation, NewPosition, NewScale);

	SetActorTransform(NewTransform);
}

 

멤버 변수들은 BP에서 설정이 가능하므로 생성자에 있던 멤버 변수 set 과정은 삭제해 주었다.

비슷한 이유로 BeginPlay()에 있던 Location 셋팅 과정을 삭제하였다.

 

결과

클래스를 상속받는 블루프린트 만들기

 

결과를 확인하기 위하여 Test1 클래스를 상속받는 블루프린트를 만들었다.

 

리플렉션 적용된 멤버 변수들

 

BP 인스턴스의 디테일 창에서 리플렉션된 변수들을 잘 확인할 수 있다.

리플렉션이 적용되어 블루프린트에서 함수 불러오기 가능

 

또한 BP 상에서 Test1의 함수를 불러올 수 있게 되었다.