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 변수를 반대로 설정해 주어 로직을 구현하였다.