[CH2/05] Unreal Engine 활용 프로그램 제작

김여울·2025년 6월 17일
1

내일배움캠프

목록 보기
24/111

Unreal Engine 활용 프로그램 제작

요구사항

개발 프로세스 가이드

1단계 : 액터 생성하기

  • 언리얼 엔진에서 새로운 엑터를 생성합니다.
  • 언리얼 엔진 동작시 엑터가 스폰(spawn)될 수 있도록 추가 합니다.

2단계 : 로직 설계하기

  • 엑터가 스폰(spawn)될 때 수행할 동작을 설계 합니다.
  • 이번 강의에서는 엑터 자체 동작이 아닌, 액터가 스폰되는 시점에 로그가 출력될수 있도록 합니다.

3단계 : 구현하기

  • UE_LOG를 활용하여 설계한 내용을 바탕으로 로그를 출력 할 수 있도록 구현합니다.
  • 엔진에서 결과를 테스트하고 필요시 수정합니다.

필수 기능 가이드

새로운 엑터를 생성하고 엑터가 spawn 되는 시점에 동작되도록 아래 요구사항대로 동작하도록 코드를 구현 합니다

시작점(0,0) 있는 게임 캐릭터가 랜덤하게 10회 이동 합니다. 각 스텝에서 거쳐간 좌표를 모두 출력하는게 목적입니다.

세부 요구사항은 아래와 같습니다.

  • 시작점은 (0,0)이고 한번 이동시 x좌표와 y좌표 모두 2이상 이동할 수 없습니다. 예를 들면 아래와 같습니다.
    • (0,0) 에서 (1,2)은 이동할수 없습니다. y좌표가 2이상 이동했기 때문입니다.
    • (0,0)에서 (1,1)은 이동할 수 있습니다. x좌표 y좌표 모두 2미만 이동했기 때문 입니다.
  • 이동은 입력을 받는게 아니고 10회 모두 랜덤으로 움직입니다.
  • 매번 이동시 현재 좌표를 출력할 수 있어야 합니다.
  • 로그 출력은 UE_LOG를 활용합니다.
  • step 함수는 x좌표 y좌표 각각 이동할 거리 입니다.
    • 예를들어서 현재 좌표가(x1,y1)이라면 다음 좌표는 (x1+step 함수의 리턴값,y1 + step함수의 리턴 값) 입니다.
    • step함수는 0혹은 1을 랜덤으로 반환 합니다.
  • move함수는 (0,0)부터 10회 움직이면서 좌표를 출력합니다. 이동시 step 함수가 활용 됩니다.

도전 기능 가이드

필수 기능 구현을 완료한 후 아래 기능을 추가 힙니다.

  • 10회 이동시 각 스텝마다 이전 좌표기준 이동 거리를 계산해서 출력 합니다. 이동 거리는 아래와 같이 계산 합니다.
  • 10회 이동시 각 스텝마다, 50% 확률로 랜덤하게 이벤트가 발생합니다.(발생 시키는 부분도 구현하셔야 합니다.) 각 스텝마다 이벤트 발생여부를 출력합니다.
  • 10회 이동후에는 총 이동거리와 총 이벤트 발생횟수를 출력 합니다.


코드

📄 MyActor.h

#pragma once

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

UCLASS()
class UE_HW05_API AMyActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AMyActor();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	int32 Step();

	void Move();

private:
	FVector Start;
};

✨ MyActor.cpp

#include "MyActor.h"

// Sets default values
AMyActor::AMyActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	Start = FVector(0, 0, 0);

}

// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
	Super::BeginPlay();
	Move();
	
}

// Called every frame
void AMyActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

int32 AMyActor::Step()
{
	return FMath::RandRange(0, 1);
}

void AMyActor::Move()
{
	UE_LOG(LogTemp, Warning, TEXT("Start Position: (%.0f, %.0f, %.0f)"), Start.X, Start.Y, Start.Z);

	for (int32 i = 0; i < 10; ++i)
	{
		int32 XStep = Step();
		int32 YStep = Step();

		Start.X += XStep;
		Start.Y += YStep;

		UE_LOG(LogTemp, Warning, TEXT("Step %d: Position = (%.0f, %.0f, %.0f)"), i + 1, Start.X, Start.Y, Start.Z);
	}	
}


코드 정리

📄 MyActor.h

class UE_HW05_API AMyActor : public AActor

AMyActorAActor 에서 상속받은 클래스
HW_API 는 모듈 간 사용할 수 있도록 하는 설정

// 이 파일이 프로젝트에 여러 번 포함되지 않게 하는 안전장치 
// 항상 맨 위에 자리
#pragma once

// UE에서 자주 쓰는 기본 자료형이나 함수들을 쓸 수 있게 하는 헤더파일
#include "CoreMinimal.h"	
// AActor` 언리얼에서 씬에 배치할 수 있는 기본 클래스
// 여기에 `MyActor` 가 상속받고 있으므로 포함
#include "GameFramework/Actor.h"
// 언리얼이 자동으로 내부 처리를 하게 하는 매크로 파일
// 항상 마지막에 자리
#include "MyActor.generated.h"

UCLASS()
class UE_HW05_API AMyActor : public AActor
{
    GENERATED_BODY()  // 언리얼이 자동으로 코드 생성을 도와주는 필수 매크로

public:  // 생성자
    // Sets default values for this actor's properties
    // 액터가 생성될 때 호출되는 함수
    // 보통 초기화를 여기서 
    AMyActor();  

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:
    // Called every frame
    // 계속 반복되는 작업은 여기에 넣기
    virtual void Tick(float DeltaTime) override;

    // Step() 함수: 0 또는 1을 랜덤으로 반환
    int32 Step();

    // Move() 함수: 10번 이동하며 좌표 출력
    void Move();

private:
	// 멤버 변수
    // 액터의 위치를 저장하는 벡터
    // X, Y, Z 3개의 좌표를 가짐
    FVector Start;  // 시작 위치
};

✨ MyActor.cpp

%.0f

소수점 0자리까지 출력 → 소수점 표시 안 됨

%d

TEXT("Step %d: Position = (%.0f, %.0f, %.0f)")는 출력할 메시지 형식을 정의하는 부분
%d 는 뒤에서 넘겨줄 정수 값을 출력할 자리 표시자

  • i + 1 이 이 자리에 들어감
  • i가 0이라면 i + 1은 1이 되고, 출력은 Step 1이 됨

#include "MyActor.h"

// Sets default values
// 클래스가 생성될 때 실행되는 함수
AMyActor::AMyActor()
{
    PrimaryActorTick.bCanEverTick = true;  // Tick 함수 활성화
    Start = FVector(0, 0, 0);  // 시작 위치 (0, 0, 0) = 월드 좌표 원점
}

// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
    Super::BeginPlay();  // 부모 클래스인 AActor의 BeginPlay를 먼저 실행
    Move();  // 게임 시작 동시에 이동 함수 호출
}

// Called every frame
void AMyActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

// Step(): 랜덤으로 0 또는 1을 반환
int32 AMyActor::Step()
{
    return FMath::RandRange(0, 1);  // 0 또는 1 반환
}

// Move(): 10번 이동하면서 좌표 출력
void AMyActor::Move()
{
    // 시작 위치를 로그로 출력
    UE_LOG(LogTemp, Warning, TEXT("Start Position: (%.0f, %.0f, %.0f)"), Start.X, Start.Y, Start.Z);

    // 10번 반복해서 이동
    for (int32 i = 0; i < 10; ++i)
    {
        // X, Y축으로 이동 거리 결정
        int32 XStep = Step();
        int32 YStep = Step();

        // 좌표 업데이트
        // 현재 좌표에서 X, Y를 각각 이동시킴
        Start.X += XStep;
        Start.Y += YStep;

        // 이동 후 좌표 출력
        UE_LOG(LogTemp, Warning, TEXT("Step %d: Position = (%.0f, %.0f, %.0f)"), i + 1, Start.X, Start.Y, Start.Z);
    }
}

2개의 댓글

comment-user-thumbnail
2025년 6월 17일

🤓

1개의 답글