Portfolio

PROJECT CASE STUDY

기물락도 락이다

Unreal Engine 5.7 기반 TFT 모작 프로젝트입니다. 57개 챔피언을 확장 가능한 데이터 중심 구조로 관리하고, 에디터 자동화·Modifier 기반 스탯 시스템·Subsystem 아키텍처·C++ 전투 로직을 구현했습니다.

Unreal Engine 5.7C++Data-Driven DesignEditor Utility WidgetAsset RegistryModifier SystemSubsystem

프로젝트 개요

ChampionLockIsaRock는 Unreal Engine 5.7로 제작한 TFT 스타일 전략 게임 프로토타입입니다. 상점, 벤치와 보드 배치, 전투 라운드, 시너지, 유닛 합체, 아이템 장착 등 오토배틀러의 핵심 게임 루프를 구현하는 것을 목표로 했습니다.

프로젝트 정보

  • 개발 기간: 2026년 3월 10일 ~ 2026년 4월 10일 (26일)
  • 참여 인원: 3명
  • 플랫폼: PC
  • 장르: Strategy / Simulation
  • 개발 환경: Unreal Engine 5.7, Windows 11

담당 업무

프로젝트에서 다음과 같은 시스템의 설계와 구현을 담당했습니다.

  • 57개 챔피언을 관리하기 위한 DataTable 기반 데이터 구조 설계
  • 챔피언 데이터와 관련 에셋을 자동으로 연결하는 Editor Utility Widget 제작
  • Asset Registry 기반 Skeletal Mesh, Animation, Montage, Portrait 탐색 시스템 구현
  • Data Modifier 기반 스탯 확장 및 아이템 시스템 구현
  • GameInstance와 Subsystem을 활용한 데이터 및 UI 아키텍처 설계
  • C++ 기반 FSM 유사 행동 흐름과 전투 시스템 구현
  • 벤치·헥스 그리드·드래그 앤 드롭 배치 시스템 구현
  • 유닛 합체, 시너지 계산, 스테이지 진행 및 보상 시스템 구현

핵심 구현 방향

Data-Driven Design

챔피언의 이름, 코스트, 초상화, 오리진, 클래스, 전투 스탯, 마나, 스킬 정보, 시각 에셋을 FTFT_ChampionData 구조체와 DataTable에서 관리하도록 구성했습니다.

상점, 유닛 초기화, 시너지 계산, 스킬 UI, 애니메이션 로딩이 동일한 챔피언 데이터를 참조하도록 설계했습니다. 이를 통해 신규 챔피언을 추가하거나 기존 챔피언의 수치를 조정할 때 gameplay 코드를 반복해서 수정할 필요가 없도록 했습니다.

데이터와 로직을 분리하여 DataTable의 값을 수정하는 것만으로도 챔피언의 스탯과 콘텐츠를 확장할 수 있도록 했습니다.

반복적인 에셋 연결 작업 자동화

초기에는 챔피언마다 Skeletal Mesh, Animation Blueprint, 공격·사망·댄스·스킬 Montage, Portrait를 개별적으로 연결해야 했습니다. 챔피언 수가 늘어날수록 동일한 에셋 연결 작업이 반복되고, 잘못된 에셋이 연결될 가능성도 커지는 문제가 있었습니다.

이를 해결하기 위해 Editor Utility Widget을 제작하여 챔피언 데이터를 DataTable에 일괄 등록하고, 네이밍 규칙을 기준으로 관련 에셋을 자동으로 탐색하도록 구현했습니다.

Asset Registry를 활용해 챔피언 키를 기준으로 다음 에셋을 자동으로 매핑했습니다.

  • Skeletal Mesh
  • Animation Blueprint
  • Attack Montage
  • Death Montage
  • Dance Montage
  • Skill Montage
  • Portrait

이 구조를 통해 신규 챔피언을 추가할 때 반복적인 에셋 연결 작업을 줄이고, 데이터 입력과 콘텐츠 확장 과정을 자동화했습니다.

챔피언 런타임 초기화

공통 유닛 클래스에서 InitWithChampionKey()를 호출하면 GameInstance가 보관한 Champion DataTable에서 챔피언 정보를 조회하고, 해당 데이터를 바탕으로 유닛의 런타임 상태를 초기화하도록 구현했습니다.

초기화 과정은 다음 순서로 동작합니다.

1. ChampionKey를 이용해 DataTable Row 조회 2. 챔피언의 기본 스탯과 스킬 정보 초기화 3. Skeletal Mesh와 Animation Blueprint 설정 4. 공격·사망·댄스·스킬 Montage 연결 5. HP와 MP UI 연결 6. 전투 및 스탯 컴포넌트 초기화

챔피언별 클래스를 별도로 제작하는 대신 공통 유닛 클래스와 데이터 기반 초기화 구조를 사용하여 코드 중복을 줄였습니다.

Modifier 기반 스탯 및 아이템 시스템

아이템 효과를 유닛의 최종 스탯에 직접 더하는 방식으로 처리하지 않고, Modifier를 생성해 StatComponent에 적용하는 구조로 구현했습니다.

각 유닛은 세 개의 아이템 슬롯을 가지고 있습니다. 아이템을 장착하면 아이템 정의에서 스탯 보너스를 조회하고 Modifier를 생성합니다. 생성된 Modifier는 StatComponent에 적용되어 기본 스탯과 아이템 적용 이후의 최종 스탯을 분리해 관리하도록 했습니다.

이를 통해 다음과 같은 확장이 가능하도록 설계했습니다.

  • 공격력·체력·공격 속도와 같은 기본 스탯 보정
  • 버프와 디버프 효과
  • 지속 시간이나 조건을 가진 효과
  • 아이템 조합 및 특수 효과
  • 원본 스탯과 최종 스탯의 분리

아이템 시스템을 단순한 수치 변경이 아닌 Modifier 기반으로 구성하여 향후 다양한 전투 효과를 같은 방식으로 확장할 수 있도록 했습니다.

C++ 기반 게임플레이 및 전투 흐름

상점 구매부터 유닛 배치, 전투 시작, 승패 판정, 보상 지급, 다음 라운드 전환까지의 게임 흐름을 C++ 중심으로 구현했습니다.

상점 시스템은 플레이어 레벨에 따른 챔피언 등장 확률, 5개의 상점 슬롯, 리롤, 골드 차감, 구매한 유닛의 벤치 스폰을 담당하도록 구현했습니다.

스테이지 시스템은 적 유닛 스폰, 전투 시작과 종료, 승패 판정, 보상 지급, 다음 준비 단계 전환을 관리하도록 구성했습니다. 전투가 30초 이상 지속될 경우 GlobalTimeDilation을 2.0으로 설정해 오버타임을 적용했습니다.

전투 중에는 보드 조작을 잠그고, 준비 단계에서만 유닛 배치와 합체가 가능하도록 게임 상태를 분리했습니다.

벤치와 헥스 그리드 배치 시스템

벤치와 전장을 별도의 데이터 구조로 관리했습니다. BenchUnits 배열은 9개의 벤치 슬롯에 배치된 유닛을 관리하고, DeployedUnits 배열은 실제 전장에 배치된 유닛을 관리하도록 구성했습니다.

전장은 Instanced Static Mesh를 이용해 헥스 그리드 형태로 생성했습니다. 행과 열의 개수, 헥스 크기, 타일 간격을 설정값으로 분리하고, 마우스 위치에서 가장 가까운 슬롯을 계산해 유닛이 해당 위치에 스냅되도록 구현했습니다.

드래그 앤 드롭 과정에서는 다음 기능을 처리하도록 구현했습니다.

  • 벤치와 전장 사이의 유닛 이동
  • 가장 가까운 슬롯으로 위치 보정
  • 다른 유닛과의 위치 교환
  • 플레이어 레벨에 따른 전장 배치 인원 제한
  • 판매 영역에 드롭했을 때 유닛 판매
  • 배치 완료 후 시너지 재계산
  • 전투 중 배치 조작 제한

유닛 합체와 시너지 계산

같은 챔피언이면서 같은 성급을 가진 유닛 세 개를 탐색해 상위 성급으로 합체시키는 시스템을 구현했습니다.

전장 유닛을 우선적으로 탐색하고, 전투 중 메인 유닛이 전장에 배치된 경우에는 즉시 상태를 변경하지 않고 PendingUpgradeKeys에 합체 요청을 저장하도록 구성했습니다.

전투가 종료되고 준비 단계로 전환되면 보류된 합체 요청을 처리하도록 했습니다. 이를 통해 전투 중인 유닛의 상태를 안전하게 유지하면서도 연쇄 합체를 지원할 수 있도록 했습니다.

시너지 계산은 실제 전장에 배치된 플레이어 유닛만 수집하고, TSet을 사용해 동일 챔피언의 중복 데이터를 제거하도록 구현했습니다. 이후 각 유닛의 Origins와 Classes를 분석해 활성화된 시너지 수를 계산하고 UI에 전달했습니다.

Subsystem 기반 UI 아키텍처

게임플레이 클래스가 특정 위젯을 직접 참조하지 않도록 UTFT_UISubsystem을 중심으로 UI 갱신 구조를 설계했습니다.

골드, 레벨, 경험치, HP와 MP, 유닛 스탯, 인벤토리 등의 변경 사항이 발생하면 Subsystem이 이벤트를 방송하고, 각각의 UI가 필요한 이벤트를 구독해 화면을 갱신하도록 구성했습니다.

이 구조를 통해 gameplay 로직과 위젯 구현의 결합도를 낮췄습니다. 또한 HUD나 인벤토리 UI가 변경되더라도 핵심 게임 로직을 수정하지 않고 확장할 수 있도록 했습니다.

결과

26일이라는 짧은 개발 기간 안에 57개의 챔피언을 포함한 TFT 스타일 오토배틀러의 핵심 게임 루프를 구현했습니다.

가장 중점을 둔 부분은 개별 기능을 단순히 나열하는 것이 아니라, 데이터 입력부터 에셋 연결, 런타임 초기화, 전투 적용, UI 반영까지의 흐름을 하나의 확장 가능한 구조로 연결하는 것이었습니다.

DataTable과 Asset Registry를 활용해 콘텐츠 제작 과정을 자동화했으며, Modifier 기반 스탯 구조와 Subsystem 기반 UI 구조를 통해 이후 아이템·버프·챔피언·UI를 확장할 수 있는 기반을 마련했습니다.

소스 코드 저장소 보기