Unreal

[6강 숙제] 위치/회전/스케일을 동적으로 변경하는 오브젝트 만들기

(ꐦ •᷄ࡇ•᷅) 2025. 1. 23. 11:17
  • 새로운 C++ 클래스를 만든다.
  • BeginPlay()에서 액터의 트랜스폼을 임의로 설정한다.
  • Tick()에서 매 프레임마다 트랜스폼을 동적으로 변경한다.
    • 특히 Scale이 일정 시간마다 커졌다가 작아지는 효과를 구현한다.
    • 이때, DeltaTime을 곱해 프레임에 독립적인 움직임을 구현한다.

코드

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:
	USceneComponent* SceneRoot;
	UStaticMeshComponent* StaticMeshComp;

	float SpeedZ;
	float RotationSpeed;
	float ScaleSpeed;
	float MaxScale;
	float MinScale;
	bool bIsScalingUp;

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

 

test1.cpp

#include "Test1.h"

ATest1::ATest1()
{
	PrimaryActorTick.bCanEverTick = true;
	
	SpeedZ = 10.f;
	RotationSpeed = 90.f;
	ScaleSpeed = 3.f;
	MinScale = 0.5f;
	MaxScale = 3.f;
	bIsScalingUp = true;

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

	StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
	StaticMeshComp->SetupAttachment(SceneRoot);
	
	static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshAsset(TEXT("/Game/Resources/Props/SM_AssetPlatform.SM_AssetPlatform"));
	if (MeshAsset.Succeeded())
	{
		StaticMeshComp->SetStaticMesh(MeshAsset.Object);
	}
}

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

	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);
}

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);
}

결과

 

 

후기

일정 시간마다 스케일을 조절하는 것을 어떻게 해야 할지 고민이었는데, bool 변수를 두어 이것을 해결할 수 있었다.

max scale, min scale을 설정해 놓고, bool 변수로 오브젝트가 커질지, 작아질지 흐름을 제어한다.

만약 현재 오브젝트의 스케일이 max나 min scale 범위를 초과한다면 bool 변수를 반대로 설정해 주어 로직을 구현하였다.