Unreal 개발 본 캠프 47일차

HappyCircle·2026년 2월 3일

Unreal 개발

목록 보기
64/163

📘 TIL – 8번 과제 해설

1. 객체 주기 일관성 & 이벤트 중심 설계

🎯 핵심 목표

객체가 언제 생성되고, 언제 사라지며, 누가 관리하는지가 명확한 구조

“누가 이 이벤트를 처리하는지 몰라도 동작하는” 구조

🔑 핵심 키워드

이벤트 시스템

메시지 시스템

델리게이트 브로드캐스트

GameMode / GameState / Subsystem 역할 분리

✏️ 정리

기존에는

“이 상태가 바뀌면 → 저 객체를 찾아서 → 함수 호출”

같은 강한 결합 구조를 쓰기 쉬웠다.
하지만 규모가 커질수록 이 방식은 유지보수가 급격히 어려워진다.

그래서 오늘은 구조를 이렇게 정리했다:

GameMode

게임의 규칙과 흐름만 관리 (FSM)

직접 UI나 월드 오브젝트를 건드리지 않음

GameState

현재 상태를 “사실”로 보관

상태 변화 시 델리게이트로 브로드캐스트

각 객체 (SpawnVolume, Widget 등)

GameState의 이벤트를 구독만 함

누가 상태를 바꿨는지는 알 필요 없음

👉 결과적으로
“상태를 바꾸는 쪽”과 “상태에 반응하는 쪽”이 완전히 분리됨

2. 3D 위젯 – 스폰 볼륨 중앙 코인 카운터 표시

🎯 구현 의도

웨이브 중 플레이어가 현재 진행 상황을 월드 안에서 직관적으로 확인

UI와 월드 로직의 결합 최소화

🧱 구조 요약

WidgetComponent

World Space

Billboard 모드 (항상 카메라를 바라봄)

CoinCounterWidget

GameState의 OnCoinCountChanged 구독

텍스트만 갱신

🔄 흐름

GameMode에서 웨이브 상태 변경

GameState가 OnWaveStateChanged 브로드캐스트

SpawnVolume

웨이브 시작 → 위젯 Visible

웨이브 종료 → Hidden

코인 획득 시

GameState가 OnCoinCountChanged 브로드캐스트

위젯은 "3 / 10" 같은 텍스트만 갱신

📌 중요 포인트

SpawnVolume은 UI의 내부 구조를 모름

Widget은 코인을 누가 증가시켰는지 모름
→ 완전한 단방향 의존

  1. 웨이브별 환경 변화 – 서브레벨 방식 선택
    ❌ 코드로 직접 Spawn/Destroy 했을 때 문제

런타임 비용 증가

에디터에서 미리보기 불가

레벨 디자이너와 협업 어려움

코드가 환경 디테일까지 책임짐

✅ 서브레벨 방식의 장점

환경은 에셋

코드는 언제 전환할지만 결정

UGameplayStatics::UnloadStreamLevel(this, "Wave1_SubLevel", FLatentActionInfo());
UGameplayStatics::LoadStreamLevel(this, "Wave2_SubLevel", true, true, FLatentActionInfo());

4. 도전 과제 – 버프 시스템 설계

❓ 왜 버프 시스템이 필요했는가

기존 아이템 구조:

즉시 효과 → 끝

하지만 이런 요구가 생김:

“5초간 이동속도 감소”

“중첩 시 배율 적용”

👉 시간 + 중첩 개념을 가진 객체가 필요

🧩 아키텍처 설계
1️⃣ 버프는 UObject

액터에 종속되지만, 액터 그 자체는 아님

수명과 로직을 독립적으로 관리

2️⃣ BuffComponent가 중앙 관리

캐릭터가 USpartaBuffComponent 보유

모든 버프 인스턴스를 배열로 관리

Tick에서 수명 갱신

3️⃣ 토큰 기반 중첩

단순 덮어쓰기 ❌

각 버프 인스턴스가 자기 토큰을 발급

만료 시 자기 토큰만 회수

Speed = BaseSpeed × 0.5 × 0.5 × 0.5

👉 중첩/해제 모두 안전하게 처리 가능

🔄 버프 수명 주기 핵심 인사이트

OnFirstStart

“효과가 처음 등장했을 때 한 번만”

파티클, 블랙보드 등록

OnStart

매 인스턴스마다

토큰 발급

OnEnd

매 인스턴스 종료

토큰 회수

OnLastEnd

모든 인스턴스 종료 시

파티클 제거, 정리

📌 이 구조 덕분에
시각 효과 / 수치 효과 / 중첩 로직이 깔끔하게 분리됨

5. DataTable + Subsystem 설계

🎯 목적

데이터 접근의 단일 창구

레벨 전환과 무관한 데이터 유지

반복 순회 제거

🧠 구조적 판단

GameInstance Subsystem 사용

시작 시 DataTable 로드 후 캐싱

TMap으로 정리해서 O(1) 접근

WaveCache[LevelIndex][WaveIndex];

6. 웨이브 상태 머신 적용

기존 문제

타이머 기반 흐름

상태가 늘어날수록 조건 분기 지옥

해결

상태를 클래스로 승격

Enter / Update / Exit 명확화

None → Begin → Progress → End → Intermission → Begin

설계 원칙

SRP: 상태는 자기 책임만

OCP: 새 상태 추가 시 기존 코드 수정 최소화

타이머, 리소스는 Enter/Exit에서 관리

📘 dump 파일 디버깅 실무 팁 – 크래시를 다루는 관점의 변화

❓ dump 파일 디버깅이 왜 중요한가

이전까지 크래시는 보통 이렇게 받아들였다.

“어디서 터졌는지 모르겠다”

“재현 안 되면 어쩔 수 없다”

“로그 좀 더 찍어볼까…”

하지만 오늘 알게 된 건,
dump 파일은 ‘운 나쁘게 터진 흔적’이 아니라 ‘이미 정답이 들어 있는 자료’라는 점이었다.

🛠 실제 디버깅 절차 정리

Visual Studio에서 dump 파일 열기

프로세스 선택 시
→ unreal.exe 선택

심볼(Symbol) 경로 설정

엔진 심볼

Engine/Binaries/Win64

프로젝트 심볼

Project/Binaries/Win64

심볼 로드가 정상적으로 되면

Call Stack이 깨지지 않고

엔진 함수 + 프로젝트 함수까지 연결해서 확인 가능

📌 이 과정의 핵심 포인트

심볼이 없으면

함수 이름 ❌

파일 위치 ❌

라인 번호 ❌

심볼이 있으면

“어디서 터졌는지”

“그 시점에 어떤 상태였는지”

“엔진 코드 → 내 코드 흐름”을 연결해서 추적 가능

즉,
크래시를 ‘추측’이 아니라 ‘추적’의 영역으로 끌어오는 작업이다.

🧠 관점의 변화

이제 크래시를 이렇게 보게 됐다.

❌ “왜 터졌지…?”

✅ “이 dump에 어떤 정보가 들어있지?”

👉 로그를 늘리는 것보다
👉 dump를 제대로 읽는 게 훨씬 강력한 디버깅 수단이라는 걸 체감했다.

📘 커리어 데이 – 이력서 & 자기소개서 인사이트 정리

1️⃣ 이력서: “기술 나열”에서 “문제 해결 기록”으로
❌ 흔한 실수

Unreal Engine 사용

C++

GAS

FSM

→ 이건 ‘무엇을 썼는지’만 있고, ‘왜 썼는지’가 없다.

✅ 권장 구조: 문제 → 접근 → 적용 → 결과

이력서는 설명서가 아니라 결과 보고서에 가깝다.

예시 관점

어떤 문제가 있었는가?

그 문제를 왜 그렇게 판단했는가?

어떤 기술을 선택했는가?

그 결과 무엇이 개선되었는가?

✍️ 예시 비교

❌ Before

Unreal Engine으로 게임 제작, GAS 사용

✅ After

웨이브 기반 전투 구조에서 상태 분기 로직이 복잡해지는 문제를 해결하기 위해
FSM 기반 Wave State Machine을 설계하고,
Delegate 기반 이벤트 브로드캐스트 구조로 UI 및 월드 오브젝트와의 결합도를 제거함.
그 결과 상태 추가 시 기존 코드 수정 없이 확장 가능하도록 개선함.

📌 같은 기술이라도
“왜 필요했는지”가 드러나면 평가가 완전히 달라진다.

2️⃣ “언리얼 사용” vs “언리얼로 무엇을 설계했는가”

❌ 언리얼 엔진 사용

❌ 블루프린트 + C++

이건 너무 넓고, 너무 추상적이다.

대신 이렇게 써야 한다:

GAS 기반 Attribute / Effect 설계

Delegate 기반 이벤트 아키텍처

GameMode / GameState / Subsystem 책임 분리

DataTable 캐싱 구조 설계

UObject 기반 버프 시스템 구현

👉 엔진을 ‘사용했다’가 아니라
엔진의 ‘개념을 이해하고 설계에 활용했다’는 인상을 주는 게 핵심

3️⃣ 자기소개서 작성법 – 단계별 접근

자기소개서는 “한 번에 잘 쓰는 글”이 아니다.
단계를 나눠야 한다.

✏️ 초벌 – 생각 다 쏟아내기

문장 퀄리티 ❌

구조 ❌

중복 ❌

👉 대신

했던 고민

실패

막혔던 지점

선택의 이유
전부 쏟아낸다.

✂️ 중벌 – 구조 정리

비슷한 이야기 묶기

흐름 만들기

불필요한 기술 나열 제거

이 단계에서 처음으로
“읽는 사람 입장”을 고려하기 시작한다.

✨ 종벌 – 검증 단계

다른 사람에게 보여주기

하루 지나서 다시 읽기

소리 내서 읽어보기

📌 소리 내서 읽으면 바로 들린다.

말이 안 되는 문장

주장만 있고 근거 없는 문단

내가 아닌 ‘이력서용 나’의 문장들

profile
개발합시다!

0개의 댓글