Post

2026-03-18 TIL (17일차)

2026-03-18 TIL (17일차)

Unreal

💡 Tip

FString 출력 시 %s 서식 지정자

FString%s 서식 지정자로 출력할 때 FString 변수나 반환값 앞에 *를 반드시 붙여야 합니다.

오류 이유

  • %s: %s 서식 지정자는 글자들이 나열된 메모리 주소를 원합니다. (C스타일 포인터)
  • 사용자의 입력: FString이라는 객체을 던져주었기 때문입니다.
  • 해결책: 객체의 실제 문자열 주소를 꺼내서 전달해야 하며, 언리얼에서는 FString변수명 앞에 *를 붙여 이 작업을 수행합니다.
1
2
3
4
5
6
7
8
9
    if (GEngine) {
        GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, TEXT("Text"));

        // GetName() 반환값(FString) 앞에 * 추가
        GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Blue, FString::Printf(TEXT("Actor : %s"), *GetName()));

        // ToString() 결과물(FString) 앞에 * 추가
        GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Blue, FString::Printf(TEXT("Location : %s"), *ActorLocation.ToString()));
    }


5번 과제

Unreal Engine 실시간 디버깅: GEngine

GEngine은 언리얼 엔진의 최상위에 존재하는 전역 엔진 포인터입니다.

  • 정의: 엔진 전체에 영향을 미치는 명령을 내릴 때 사용합니다.
  • 특징: 프로젝트 어디에서든 이 포인터를 통해 게임 전체 시스템 기능에 접근할 수 있습니다.
  • 주의사항: 엔진이 초기화 중이거나 종료 중일 때는 Null일 수 있습니다. 따라서 사용 안전성 체크가 필수입니다.
1
2
3
4
if (GEngine)
{
    // GEngine이 유효할 때만 실행
}


AddOnScreenDebugMessage

로그 창을 보지 않아도 게임 화면(뷰포트)에 실시간으로 텍스트를 출력해 주는 함수입니다.

1
2
3
4
5
6
7
8
9
if (GEngine)
{
    GEngine->AddOnScreenDebugMessage(
        -1,                   // 1. 키 (Key)
        5.f,                  // 2. 표시 시간 (Seconds)
        FColor::Red,          // 3. 색상 (Color)
        TEXT("공격 성공!")     // 4. 내용 (Message)
    );
}
  • Key (-1): 메시지의 고유 번호입니다.
    • -1: 새로운 메시지가 위로 계속 쌓입니다. (로그 형태)
    • 특정 숫자(예: 1): 동일한 번호를 가진 이전 메시지를 덮어씁니다. 좌표값이나 체력 등 실시간으로 변하는 수치를 확인할 때 유용합니다.
  • TimeToDisplay: 메시지가 화면에 머무는 시간(초)입니다.
  • DisplayColor: 글자의 색상을 지정합니다.
  • DebugMessage: 출력할 실제 문자열입니다.


UE_LOG vs AddOnScreenDebugMessage

특징UE_LOG (로그)AddOnScreenDebugMessage (화면 메시지)
확인 위치출력 로그 창, .log 파일 저장게임 플레이 화면 (뷰포트)
주요 용도상세 데이터 기록, 장기적인 디버깅즉각적인 상태 확인 (전투, 충돌 등)
가시성로그 창을 따로 열어야 함플레이 중 화면에 즉시 노출
휘발성파일로 저장되어 나중에 확인 가능저장 안 됨 (일시적 노출)


C++


C++의 철칙: 참조와 임시 객체


1. 참조자 두 가지

  • 일반 참조자 (T&): 이 실체를 가져와서 수정할 수도 있다는 뜻이 있습니다.
  • 상수 참조자 (const T&): 이 실체를 읽기만 한다는 의미입니다.


임시 객체는 const T&로만 받을 수 있을까?

설계: 유령을 수정하지 마라!

  • 실수 방지: 임시 객체는 함수 호출이 끝나면 즉시 파괴되는 ‘찰나의 존재’입니다. 만약 수정 가능한 참조자(T&)로 임시 객체를 고치게 허용한다면, 프로그래머는 곧 사라질 임식객체를 수정하는 의미 없는 작업을 하게 됩니다. C++은 이를 버그로 간주하여 문법적으로 금지합니다.

  • 수명 연장: C++ 표준 규정상, 임시 객체를 const 참조자에 대입하면, 해당 참조자가 Scope를 벗어나 사라질 때까지 임시 객체의 생명 주기가 함께 연장됩니다. const라는 안전장치가 있기 때문에 컴파일러가 믿고 수명을 늘려주는 것입니다.


C++ 알고리즘 (Stack&Queue)

Queue의 pop()은 Vector의 erase보다 빠른 이유

  • Vector: vector는 앞에서 데이터를 삭제할 때(erase(v.begin())), 뒤에 있는 모든 요소를 한 칸씩 앞으로 당겨야 하므로 O(n)의 시간이 걸립니다.
  • Queue: 반면 queuepop()은 데이터 개수에 상관없이 항상 O(1)의 속도로 처리됩니다.

이유 std::queue는 내부적으로 std::deque를 기본 컨테이너로 사용합니다. deque는 구조적으로 양쪽 끝에서의 삽입과 삭제가 모두 O(1)인 자료구조이기 때문입니다.



Stack vs Queue

구분Stack (LIFO)Queue (FIFO)
원리후입선출 (LIFO)선입선출 (FIFO)
데이터 넣기위에 쌓기 (push)뒤에 서기 (push)
데이터 빼기위에서 빼기 (pop)앞에서 빼기 (pop)
데이터 확인top()front() / back()
대표 용도Undo(되돌리기), 괄호 검사, DFS순서 처리, BFS, 대기열(Task)


Stack & Queue 내부 구현

stackqueue는 데이터를 직접 저장하는 저장소가 아니라, 기존의 컨테이너를 감싸서 접근 방식을 특정 목적에 맞게 제한한 컨테이너 어댑터입니다.

  • stack
  • 내부 컨테이너: 기본적으로 deque를 사용하며, 뒤쪽(back)으로만 데이터를 넣고 뺍니다.
  • 특이점: 임의 접근 기능을 막아 ‘쌓기’ 동작만 가능하게 제한했습니다.

  • queue
  • 내부 컨테이너: 기본적으로 deque를 사용하며, 양쪽 끝을 모두 활용합니다.
  • 효율성: deque의 ‘앞에서 빼기’ 성능 덕분에 queue 역시 O(1)의 효율적인 pop()을 제공합니다.

주의사항
vector는 임의 접근(v[i])이 가능하지만, stackqueue는 자료구조의 의도를 지키기 위해 임의 접근을 차단했습니다.



Deque vs Queue

구분Deque (Double-Ended Queue)Queue
정체성시퀀스 컨테이너 (데이터 저장소)컨테이너 어댑터 (기존 저장소를 감싼 것)
입출구양쪽 끝 모두 자유로움한쪽으로 넣고 반대쪽으로만 뺌
임의 접근가능 (dq[i] 접근 가능)불가능 (앞/뒤 데이터만 확인 가능)
함수명push_front, pop_back 등 구체적push, pop으로 추상화
속도앞/뒤 삽입·삭제 모두 O(1)앞/뒤 삽입·삭제 모두 O(1)

설계의 의도 두 자료구조의 차이는 의도의 명확성에 있습니다. 누군가 내 코드를 봤을 때 Queue를 쓰고 있다면 의도를 파악할 수 있게 해줍니다.

This post is licensed under CC BY 4.0 by the author.