오늘 한 것
언리얼 엔진 C++ 과제로 Actor의 좌표 이동 및 회전 시뮬레이션을 구현했다.BeginPlay()에서 랜덤 이동과 회전을 10회 반복하고, 매 스텝마다 좌표를 화면에 출력하는 구조다.
도전 기능까지 포함해 50% 확률 이벤트 시스템과 10회 종료 후 결과 리포트도 완성했다.
구현 구조 요약
AMyActor
├── BeginPlay() ← 10회 루프 실행
├── Move(float Distance) ← X축 이동 + 좌표 로그
├── Turn(float Angle) ← Yaw 회전 + 각도 로그
└── TriggerEvent() ← 50% 확률 이벤트
헤더 (MyActor.h)
UCLASS()
class MYPROJECT_API AMyActor : public AActor
{
GENERATED_BODY()
public:
AMyActor();
protected:
virtual void BeginPlay() override;
private:
void Move(float Distance);
void Turn(float Angle);
void TriggerEvent();
};
소스 (MyActor.cpp)
void AMyActor::BeginPlay()
{
Super::BeginPlay();
// 시작 위치 설정
SetActorLocation(FVector(0.f, 50.f, 0.f));
int32 EventCount = 0;
float TotalDistance = 0.f;
FVector PrevLocation = GetActorLocation();
for (int32 i = 0; i < 10; i++)
{
float RandDist = FMath::RandRange(50.f, 200.f);
float RandAngle = FMath::RandRange(0.f, 360.f);
Move(RandDist);
Turn(RandAngle);
// 이동 거리 누적
FVector CurrLocation = GetActorLocation();
TotalDistance += FVector::Dist(PrevLocation, CurrLocation);
PrevLocation = CurrLocation;
// 이동 횟수 출력
FString StepMsg = FString::Printf(TEXT("Step %d / 10"), i + 1);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, StepMsg);
// 50% 확률 이벤트
if (FMath::RandRange(0, 1) == 1)
{
TriggerEvent();
EventCount++;
}
}
// 최종 리포트
FString Report = FString::Printf(
TEXT("=== RESULT === TotalDist: %.1f | Events: %d"), TotalDistance, EventCount);
GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Green, Report);
}
void AMyActor::Move(float Distance)
{
FVector NewLocation = GetActorLocation() + GetActorForwardVector() * Distance;
SetActorLocation(NewLocation);
FString Msg = FString::Printf(TEXT("Pos: %s"), *NewLocation.ToString());
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Cyan, Msg);
}
void AMyActor::Turn(float Angle)
{
FRotator NewRotation = GetActorRotation() + FRotator(0.f, Angle, 0.f);
SetActorRotation(NewRotation);
FString Msg = FString::Printf(TEXT("Rot Yaw: %.1f"), NewRotation.Yaw);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Orange, Msg);
}
void AMyActor::TriggerEvent()
{
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("[EVENT] Triggered!"));
}
오늘의 핵심 : AddOnScreenDebugMessage 파라미터 정리
오늘 가장 헤맸던 부분이 바로 이 함수다.
파라미터가 4개인데 순서와 역할을 정확히 몰라서 처음엔 색이 안 나오거나 메시지가 쌓이지 않았다.
GEngine->AddOnScreenDebugMessage(
int32 Key, // [1] 메시지 식별 키
float TimeToDisplay, // [2] 화면 표시 시간 (초)
FColor DisplayColor, // [3] 텍스트 색상
FString DebugMessage // [4] 출력할 문자열
);
Key 값의 동작 차이가 핵심이다
Key 값 동작
| -1 | 매번 새 줄로 추가 (로그처럼 쌓임) |
| 0 이상 정수 | 같은 Key면 덮어씌움 (값 실시간 갱신용) |
FString 변환 시 * 연산자 필수
// 컴파일 에러
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Cyan, NewLocation.ToString());
// 올바른 방법
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Cyan, *NewLocation.ToString());
// 또는
FString Msg = FString::Printf(TEXT("Pos: %s"), *NewLocation.ToString());
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Cyan, Msg);
FString을 직접 넘길 때는 *로 TCHAR*로 변환해야 한다.Printf로 포맷팅하면 FString이 만들어지므로 그대로 넘겨도 된다.
오늘 새로 쓴 언리얼 API 정리
| API | 용도 |
|---|---|
GEngine->AddOnScreenDebugMessage() |
화면에 디버그 텍스트 출력 |
FMath::RandRange(min, max) |
범위 내 랜덤 정수/실수 반환 |
FVector::Dist(A, B) |
두 벡터 간 거리 계산 |
GetActorForwardVector() |
액터의 전방 방향 벡터 반환 |
FString::Printf(TEXT(...), ...) |
C의 printf 스타일 FString 생성 |
느낀 점
- 언리얼 C++은 일반 C++과 문법은 같지만 타입 체계가 다르다.
FString,FVector,FRotator등 언리얼 전용 타입에 익숙해지는 게 먼저다. AddOnScreenDebugMessage의 Key 파라미터를 이해하고 나니
디버깅 전략 자체가 달라졌다. 값 갱신인지, 로그 누적인지를 의식적으로 선택하게 됐다.BeginPlay()에서 루프를 돌리는 건 시각적으로는 한 프레임에 전부 출력된다.
실제로 움직이는 것처럼 보이려면Tick()또는 타이머(FTimerHandle)가 필요하다는 걸 알았다 → 다음 챕터 예습 포인트.
Hollow Village Dev / Ironclad Studios
'코딩' 카테고리의 다른 글
| [C++] 인벤토리 시스템 구현— Project HW03 (0) | 2026.03.17 |
|---|---|
| STL Vector / 고정폭 정수형 / enum class (0) | 2026.03.16 |
| [C++] 전직 & 전투 시스템 구현— Project HW02 (0) | 2026.03.11 |
| CH2 개인과제 1번 상태창 구현(2) (0) | 2026.03.05 |
| CH2 개인과제 1번 상태창 구현(1) (0) | 2026.03.04 |