[TIL] 2026-01-15 | UE 회전 발판과 움직이는 장애물

2026. 1. 15. 18:07·내배캠Unreal_TIL/UE
C++와 Unreal Engine으로 3D 게임 개발 과제 6

1. WHY

  • 이번 과제는 언리얼 C++과 엔진 기능 (Actor, Tick, 리플렉션 시스템 등)을 활용해 간단한 퍼즐용 오브젝트들을 준비하는 과제입니다.
  • 회전 발판, 이동 플랫폼 등 동적으로 움직이는 오브젝트를 만들고, 이를 C++ 로직과 Tick 함수로 제어하여 언리얼 C++ 개발 흐름을 체득하는 것이 목표입니다.
  • 리플렉션 시스템을 통해 변수 (속도, 범위, 각도 등)를 에디터에서 수정할 수 있도록 노출하여 효율적인 게임플레이 튜닝 과정을 경험합니다.

2. HOW

- 1단계 : 퍼즐 오브젝트 설계

이집트 컨셉으로 피라미드 안에 들어가서 보물을 찾는 스토리로 레벨 디자인 했다. 

돌아가는 벽과 랜덤 스폰되는 보물, 피라미드까지 가는 길에 움직이는 발판을 구현할 계획이다.

 

- 2단계 : C++ Actor 클래스 구현

 

- 3단계 : Tick 함수 활용하여 회전 및 이동 로직 작성

- 4단계 : 리플렉션 시스템 적용

 

1. 돌아가는 벽

#pragma once

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

UCLASS()
class NBC_UE_P6_API ARotating : public AActor
{
	GENERATED_BODY()
	
public:	
	ARotating();

protected:
	virtual void BeginPlay() override;
	USceneComponent* SceneRoot;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Comp")
	UStaticMeshComponent* StaticMeshComp;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Custom")
	float RotationSpeed;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Custom")
	bool Reverse;
	virtual void Tick(float DeltaTime) override;
};
#include "Rotating.h"

ARotating::ARotating()
{
	PrimaryActorTick.bCanEverTick = true;

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

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

	RotationSpeed = 90.f;
	Reverse = false;

}

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

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

	if (!FMath::IsNearlyZero(RotationSpeed))
	{
		if(Reverse)
		{
			AddActorLocalRotation(FRotator(0.f, -RotationSpeed * DeltaTime, 0.f));
		}
		else
		{
			AddActorLocalRotation(FRotator(0.f, RotationSpeed * DeltaTime, 0.f));
		}
	}
}

스태틱 매쉬 및 속도, 반전을 리플렉션 시스템으로 수정할 수 있도록 했다.

 

2. 움직이는 발판

#pragma once

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

UCLASS()
class NBC_UE_P6_API AMoving : public AActor
{
	GENERATED_BODY()
	
public:	
	AMoving();

protected:
	virtual void BeginPlay() override;
	virtual void Tick(float DeltaTime) override;
	USceneComponent* SceneRoot;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Comp")
	UStaticMeshComponent* StaticMeshComp;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Custom")
	float MovingSpeed;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Custom")
	bool Reverse;
	FVector StartPosition;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Custom")
	float Range;
};
#include "Moving.h"

AMoving::AMoving()
{
	PrimaryActorTick.bCanEverTick = true;

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

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

	MovingSpeed = 200.f;
	Reverse = false;
	Range = 500.f;
}

void AMoving::BeginPlay()
{
	Super::BeginPlay();
	StartPosition = GetActorLocation();
}

void AMoving::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	if (!FMath::IsNearlyZero(MovingSpeed))
	{
		if (Reverse)
		{
			AddActorLocalOffset(FVector(0.f, -MovingSpeed * DeltaTime, 0.f));
		}
		else
		{
			AddActorLocalOffset(FVector(0.f, MovingSpeed * DeltaTime, 0.f));
		}
		if (FVector::Dist(GetActorLocation(), StartPosition) >= Range)
		{
			Reverse = !Reverse;
		}
	}
}

스태틱 매쉬 및 범위, 스피드, 반전을 리플렉션 시스템을 사용했다.

BeginPlay()에서 시작위치값을 저장하고 Tick()에서 시작위치와 현재위치 거리 계산을 통해 방향 전환을 할 수 있다.

 

- 5단계 : 오브젝트 배치 및 테스트

하나하나 스피드랑 각도 조절해서 배치하려고 했는데

그냥 랜덤으로 생성되도록 코드를 수정해야겠다.

 

움직이는 발판은 각각의 범위와 속도, 방향을 조절해줬다.

 

 

- 도전 과제 1번

 

[TIL] 2025-01-20 | 과제 6에 타이머로 자동문 추가

C++와 Unreal Engine으로 3D 게임 개발 과제 6 [TIL] 2025-01-15 | UE 회전 발판과 움직이는 장애물C++와 Unreal Engine으로 3D 게임 개발 과제 61. WHY이번 과제는 언리얼 C++과 엔진 기능 (Actor, Tick, 리플렉션 시스템

zzageuli.tistory.com

 

- 도전 과제 2번

1. 동적 스폰

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "MyGameModeBase.generated.h"

class ATreasure;

UCLASS()
class NBC_UE_P6_API AMyGameModeBase : public AGameModeBase
{
	GENERATED_BODY()
	
protected:
	virtual void BeginPlay() override;

	UPROPERTY(EditDefaultsOnly, Category="Spawn")
	TSubclassOf<ATreasure> TreasureClass;
	UPROPERTY(EditAnywhere, Category = "Spawn")
	TArray<FVector> SpawnLocations;

	void SpawnRandom();
};

게임모드 클래스를 생성하고 동적 스폰할 클래스와 위치를 지정하도록 했다.

#include "MyGameModeBase.h"
#include "Engine/World.h"
#include "Treasure.h"

void AMyGameModeBase::BeginPlay()
{
    SpawnRandom();
}

void AMyGameModeBase::SpawnRandom()
{
    if (!TreasureClass)
        return;

    UWorld* World = GetWorld();

    if (!World)
        return;

    int32 idx = FMath::RandRange(0, SpawnLocations.Num() - 1);

    FActorSpawnParameters Params;
    Params.SpawnCollisionHandlingOverride =
        ESpawnActorCollisionHandlingMethod::AlwaysSpawn;

    if (!World->SpawnActor<ATreasure>(
        TreasureClass,
        SpawnLocations[idx],
        FRotator::ZeroRotator,
        Params
    ))
    {
        UE_LOG(LogTemp, Warning, TEXT("Treasure Spawn Failed."));
    }
    else
    {
        UE_LOG(LogTemp, Log, TEXT("Treasure Spawn."));
    }
}

SpawnActor을 통해 동적 스폰되도록한다.

랜덤으로 TArray값을 가져와서 위치를 정해 스폰되도록 했다.

 

아직 충돌 관련 로직은 없어서 무조건 생성되도록 AlwaysSpawn으로 지정했다.

생성 여부를 포인터로 반환하기 때문에 생성 성공/실패를 로그로 확인했다.

 

랜덤한 위치에 잘 생성된 것을 확인할 수 있다.

 

2. 랜덤 속성 부여

void ARotating::BeginPlay()
{
	Super::BeginPlay();
	SetActorRotation(FRotator(0.0f, FMath::RandRange(0.0f, 180.0f), 0.0f));
	if (FMath::RandRange(0, 1)) 
	{
		Reverse = true;
	}
	else
	{
		Reverse = false;
	}
	RotationSpeed = FMath::RandRange(80.f, 100.f);
}

BeginPlay()에서 랜덤으로 값을 지정해준다.

 

시작 회전값 0~180도,

방향 50% 확률,

회전 스피드 80~100.

 

 

3. RESULT

https://github.com/yoonseo4343/NBC_UE_P6

 

GitHub - yoonseo4343/NBC_UE_P6: 내일배움캠프 언리얼7기 과제 6

내일배움캠프 언리얼7기 과제 6. Contribute to yoonseo4343/NBC_UE_P6 development by creating an account on GitHub.

github.com

https://youtu.be/l-eyJugBXrU

 

 

4. 참고

https://dev.epicgames.com/documentation/en-us/unreal-engine/spawning-actors-in-unreal-engine?application_version=5.5

 

Spawning Actors in Unreal Engine | Unreal Engine 5.5 Documentation | Epic Developer Community

Methods of creating new instances of Actors in gameplay code.

dev.epicgames.com


https://smore.im/quiz/2yNgdMN9jQ?lang=0

'내배캠Unreal_TIL > UE' 카테고리의 다른 글

[TIL] 2026-01-16 | UE 아이템 시스템 구현하기 (1), 아이템 인터페이스  (1) 2026.01.16
[TIL] 2026-01-16 | UE 애니메이션 리타겟팅  (0) 2026.01.16
[TIL] 2026-01-14 | UE Pawn 클래스로 3D 캐릭터 만들기  (2) 2026.01.14
[TIL] 2026-01-13 | State Machine 설계를 통한 캐릭터 애니메이션 적용  (0) 2026.01.13
[TIL] 2026-01-12 | UE C++ 캐릭터 컨트롤  (0) 2026.01.12
'내배캠Unreal_TIL/UE' 카테고리의 다른 글
  • [TIL] 2026-01-16 | UE 아이템 시스템 구현하기 (1), 아이템 인터페이스
  • [TIL] 2026-01-16 | UE 애니메이션 리타겟팅
  • [TIL] 2026-01-14 | UE Pawn 클래스로 3D 캐릭터 만들기
  • [TIL] 2026-01-13 | State Machine 설계를 통한 캐릭터 애니메이션 적용
윤윤씨
윤윤씨
🎮 내일배움캠프 Unreal 7기
  • 윤윤씨
    컴퓨터온열맛사지
    윤윤씨
  • 전체
    오늘
    어제
    • 분류 전체보기 (62)
      • 내배캠Unreal_TIL (62)
        • C++ (23)
        • UE (31)
        • 팀프로젝트 (7)
      • etc (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
    • Solved.ac
    • YouTube
  • 태그

    gas
    코드카타
    머티리얼
    언리얼과제
    오토마타
    ta
    프로그래머스
    챌린지
    스테이트머신
    디자인패턴
    STL
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.6
윤윤씨
[TIL] 2026-01-15 | UE 회전 발판과 움직이는 장애물
상단으로

티스토리툴바