Unreal 본격 TIL

Unreal 팀 프로젝트 "PENTAGRAM" 기획/설계 시스템 문서

ggojun 2026. 5. 22. 15:31

[설계 문서] 아이템, 인벤토리 및 상호작용 시스템 (MVP v1.0)

본 문서는 게임의 가장 핵심이 되는 아이템, 장비 슬롯, 인벤토리, 오브젝트 상호작용 시스템의 규칙과 이를 구조화하기 위한 플레이어 컴포넌트 아키텍처를 누구나 이해하기 쉽게 정의한 문서입니다.


1. 아이템 시스템 (Item System)

게임 내 아이템은 크게 장비 아이템소비 아이템으로 분류되며, 상세 스펙은 다음과 같습니다.

아이템 종류 상세 타입 (Type) 등급 (Grade) 기본 성능 (Base Stat) 랜덤 추가 옵션 (Bonus Options) 주요 특징 및 효과
장비 아이템 무기 (Weapon) 일반 (Common)
희귀 (Rare)
공격력 (STR) 증가 Common: 없음
Rare: 1~2개 무작위 부여
(공격력 / 방어력 / 최대 HP 증가)
플레이어가 캐릭터에 착용하여 능력치를 영구적으로 높이는 아이템입니다.
장비 아이템 갑옷 (Chest) 일반 (Common)
희귀 (Rare)
방어력 (DEF) 증가 Common: 없음
Rare: 1~2개 무작위 부여
(공격력 / 방어력 / 최대 HP 증가)
플레이어가 캐릭터에 착용하여 능력치를 영구적으로 높이는 아이템입니다.
소비 아이템 물약 (Potion) 등급 없음 없음 없음 사용 시 5초 동안 매초 전체 체력(HP)의 3 ~ 5%씩 서서히 회복됩니다. (이동 및 전투 중 사용 가능)

2. 인벤토리 및 장비 슬롯 시스템 (Component Architecture)

인벤토리와 장비 창은 플레이어 캐릭터의 독립된 기능 단위로 관리하기 위해 컴포넌트(Component) 형식으로 부착하여 처리합니다.

2.1 컴포넌트 구조 (Component 구조)

  • 장비 컴포넌트 (Equipment Component): 캐릭터가 현재 장착 중인 장비 슬롯을 관리합니다.
    • 보유 슬롯: 무기(Weapon) 슬롯 1개, 갑옷(Chest) 슬롯 1개
  • 인벤토리 컴포넌트 (Inventory Component): 캐릭터가 획득하여 보관 중인 아이템 가방을 관리합니다.
    • 가방 크기: 총 30칸 (5 × 6 격자 구조)

2.2 인벤토리 보관 규칙

  • 소비 아이템 (물약): 완전히 동일한 물약은 가방 칸을 아끼기 위해 하나의 슬롯에 수량(quantity)만 늘어나며 겹쳐서 보관됩니다.
  • 장비 아이템 (무기/갑옷): 희귀 등급처럼 아이템마다 무작위 옵션이 다를 수 있으므로, 종류가 같더라도 무조건 가방의 개별 칸을 차지하며 나누어 보관됩니다.
  • 아이템 소실: 물약을 다 쓰거나 아이템이 사라져서 수량이 0이 되면, 해당 인벤토리 슬롯 데이터는 자동으로 삭제(빈칸 처리)됩니다.

2.3 장착 및 해제 규칙 (인벤토리 ↔ 장비 컴포넌트 상호작용)

인벤토리 창에서 아이템을 더블 클릭하거나 우클릭하여 장착 및 해제를 실행합니다.

  • 장착할 때 (Equip):
    • 인벤토리 컴포넌트의 장비가 장비 컴포넌트의 해당 슬롯으로 이동합니다.
    • 장착이 완료되면 아이템이 가진 성능(기본 성능 + 추가 옵션)이 캐릭터 능력치에 즉시 더해집니다.
    • 이미 슬롯에 다른 장비를 끼고 있다면, 기존 장비는 자동으로 인벤토리 컴포넌트의 빈 슬롯으로 돌아오고 새 장비로 교체(스왑)됩니다.
  • 해제할 때 (Unequip):
    • 장비를 벗으면 상승했던 캐릭터 능력치가 즉시 차감됩니다.
    • 벗은 장비는 인벤토리 컴포넌트의 빈칸으로 이동합니다. 만약 인벤토리가 가득 차서 빈 공간이 없다면 장비를 벗을 수 없습니다.

3. 상호작용 시스템 (Interaction System)

플레이어가 게임 속 세상(아이템, NPC, 구조물 등)과 반응하고 소통하는 규칙입니다.

3.1 상호작용 실행 (조작법)

  • 플레이어가 대상에게 1미터 이내로 가까이 접근했을 때 키보드 F 키를 눌러 실행합니다.
  • 단, 바닥에 떨어진 아이템의 경우 마우스 좌클릭으로 간편하게 주울 수 있습니다.

3.2 대상별 상호작용 효과

  • 아이템: 바닥에 떨어진 아이템을 획득하여 플레이어의 인벤토리 컴포넌트에 새 데이터로 추가합니다.
  • NPC: 해당 NPC와 대화 창이 열리며 이야기를 나눕니다.
  • 구조물 (보물상자, 세이브 포인트 등): 상자가 열리거나, 부활 위치가 등록되는 등 오브젝트 고유의 특수 이벤트가 발생합니다.

3.3 상호작용 취소 규칙 (NPC 대화 등 진행 중일 때)

  • 수동 취소: 플레이어가 언제든 ESC 버튼을 누르면 진행 중이던 대화(상호작용)가 종료됩니다.
  • 자동 취소 (피격): 상호작용 도중 몬스터 등 외부 공격을 받아 체력(HP)이 감소하면, 진행 중이던 상호작용이 강제로 즉시 취소됩니다.

💡 개발 참고용: 인벤토리 데이터 구조 (Data Reference)

기획 및 개발 직군 간의 명확한 데이터 소통을 위해 실제 코드에 반영될 핵심 구조를 요약한 데이터 테이블입니다.

[구조체 정의]

  • Inventory: 플레이어 가방 공간. slots라는 배열 형태로 총 30칸의 공간을 관리합니다.
  • InventorySlot: 가방의 한 칸을 의미하며, 들어있는 아이템 정보(item)현재 수량(quantity)을 기억합니다.

[Item 데이터 세부 명세]

필드명 (Field) 타입 (Type) 설명
item_id string 아이템 고유 식별 번호 (시스템 구분용)
item_name string 화면에 표시될 아이템 이름
item_category enum 대분류 (장비 아이템 / 소비 아이템)
item_type enum 소분류 (무기, 갑옷, 물약)
item_grade enum 장비 등급 (Common, Rare / 소비 아이템은 없음)
item_base_stat int 기본 성능 수치 (무기는 STR 증가량, 갑옷은 DEF 증가량)
item_bonus_options int Rare 등급에만 무작위로 붙는 추가 옵션들의 목록

[Equipment 데이터 세부 명세]

필드명 (Field) 타입 (Type) 설명
equipped_weapon EquipmentSlot 현재 장착 중인 무기(Weapon) 슬롯 데이터 (비어있을 수 있음)
equipped_chest EquipmentSlot 현재 장착 중인 갑옷(Chest) 슬롯 데이터 (비어있을 수 있음)
total_bonus_str int 장착 중인 장비로 인해 증가한 총 공격력(STR) 합산 값 (실시간 스탯 반영용)
total_bonus_def int 장착 중인 장비로 인해 증가한 총 방어력(DEF) 합산 값 (실시간 스탯 반영용)
total_bonus_hp int 장착 중인 장비의 추가 옵션으로 증가한 총 최대 HP 합산 값

[EquipmentSlot 세부 명세]

필드명 (Field) 타입 (Type) 설명
equipped_slot_type enum 장착 슬롯의 타입 (Weapon / Chest)
is_equipped bool 현재 슬롯에 장비가 장착되어 있는지 여부 (true / false)
mounted_item Item 슬롯에 장착된 아이템의 상세 데이터 (is_equippedfalse이면 null)

📌 장비 장착/해제 시 데이터 처리 흐름 (개발 참고)

  1. 장착 (Equip)
    • mounted_item에 아이템 데이터가 할당되면 is_equippedtrue로 변경합니다.
    • mounted_itemitem_base_statitem_bonus_options를 파싱하여 total_bonus_str/def/hp에 즉시 누적시키고, 이를 플레이어의 최종 스탯 컴포넌트에 반영합니다.
  2. 해제 (Unequip)
    • 해당 슬롯의 mounted_item이 가진 성능을 total_bonus_str/def/hp에서 차감한 후 플레이어 스탯을 갱신합니다.
    • 슬롯의 mounted_itemnull로 비우고, is_equippedfalse로 변경합니다.

🛠️ 4. MVP 시스템 개발 가이드 및 작업 리스트

💡 개발 우선순위 제안 (Priority)

  1. 1순위 (핵심 데이터 플로우): 1단계와 2단계를 싱글플레이 모드에서 텍스트(UE_LOG)로 먼저 검증하세요. 데이터가 인벤토리와 장비 창 사이를 정상적으로 오가는지(스탯이 잘 더해지고 빼지는지) 로그로 확인하는 것이 디버깅에 유리합니다.
  2. 2순위 (네트워크 동기화): 데이터 흐름이 완벽해지면 3단계(Replication)를 적용하여 클라이언트-서버 간에 패킷이 정상적으로 오가고 핵/변조가 불가능한 구조인지 체크하세요.
  3. 3순위 (인터페이스 확장): 상호작용은 반드시 인터페이스(UInterface)로 만드셔야 추후에 '발판 메커니즘'이나 '움직이는 장애물' 같은 환경 요소가 확장되어도 플레이어 코드를 수정하지 않고 유연하게 대응할 수 있습니다.

📅 개발 마일스톤 요약

단계 개발 프로세스 핵심 목표 예상 기간
[1단계] 데이터 기초 및 아이템 베이스 구축 데이터 구조체 선언 및 드롭 액터 배치 1 ~ 3일
[2단계] 핵심 컴포넌트 로직 구현 (Local) 싱글플레이 기준 인벤토리/장비 로직 완성 3 ~ 5일
[3단계] 멀티플레이어 리플리케이션 적용 서버 검증 및 클라이언트 동기화 (RPC) 5 ~ 7일
[4단계] 상호작용 시스템 구축 공용 인터페이스 기반의 상호작용/취소 구현 3 ~ 5일
[5단계] UI 및 최종 연동 UMG 인터페이스 데이터 바인딩 및 폴리싱 4 ~ 5일

[1단계] 데이터 기초 및 아이템 베이스 구축 (Data & Base Actor) (예상 개발 기간 : 1~3일)

가장 먼저 시스템의 뼈대가 되는 데이터 구조체와 바닥에 배치할 아이템의 부모 클래스를 정의합니다.

  • [ ] 아이템 데이터 구조 설계 (C++)
    • 기획서의 Item 세부 명세를 바탕으로 FItemData 구조체 정의
    • 아이템 카테고리(Equipment, Consumable), 타입(Weapon, Chest, Potion), 등급(Common, Rare)을 나타낼 UENUM 선언
    • 인벤토리 한 칸을 담당할 FInventorySlot 구조체(Item Data + Quantity) 정의
  • [ ] 데이터 테이블(Data Table) 생성
    • 정의한 FItemData를 기반으로 에디터에서 사용할 아이템 기본 데이터 테이블 생성 및 샘플 데이터(무기, 갑옷, 물약) 입력
  • [ ] 드롭 아이템 베이스 액터 생성 (AItemActorBase)
    • 바닥에 떨어져 상호작용할 수 있는 아이템 액터 구현
    • 시각적 표현을 위한 UStaticMeshComponent 및 충돌 감지용 USphereComponent 추가

[2단계] 핵심 컴포넌트 비즈니스 로직 구현 (Core Components) (예상 개발 기간 : 3~5일)

플레이어 캐릭터에 부착하여 독립적으로 작동할 두 개의 컴포넌트 핵심 기능을 먼저 싱글플레이 기준으로 구현합니다.

  • [ ] 인벤토리 컴포넌트 (UInventoryComponent)
    • TArray<FInventorySlot> 구조로 30칸짜리 가방 공간 생성
    • 아이템 획득/추가 로직: 물약(소비형)은 기존 슬롯의 수량(quantity) 증가, 장비형은 무조건 개별 빈 슬롯에 할당하는 규칙 반영
    • 아이템 소실 로직: 수량이 0이 되면 슬롯 데이터를 비우는 기능 구현
  • [ ] 장비 컴포넌트 (UEquipmentComponent)
    • 무기 슬롯과 갑옷 슬롯을 나타낼 변수(또는 크기 2짜리 TArray/TMap) 정의
  • [ ] 장착/해제 인터랙션 구현 (컴포넌트 간 통신)
    • 장착(Equip): 인벤토리 슬롯 ➡️ 장비 슬롯 이동 및 기존 장비 스왑(인벤토리 빈 슬롯으로 복귀) 로직 구현. 캐릭터 스탯(STR/DEF)에 즉시 반영.
    • 해제(Unequip): 장비 슬롯 ➡️ 인벤토리 빈 슬롯 이동 및 캐릭터 스탯 차감 로직 구현. (인벤토리가 가득 찼을 때 해제 불가 예외 처리 필수)
  • [ ] 소비 아이템(물약) 사용 로직
    • 물약 사용 시 5초 동안 매초 전체 HP의 3~5%씩 서서히 회복되는 타이머(FTimerHandle) 기반 로직 구현

[3단계] 멀티플레이어 네트워크 리플리케이션 적용 (Multiplayer & Networking) (예상 개발 기간 : 5~7일)

언리얼 멀티플레이어 환경에서 데이터 조작은 반드시 서버(Server)에서 이루어지고 클라이언트에 동기화되어야 합니다. 안전성과 부드러움을 위해 구조를 래핑합니다.

  • [ ] 컴포넌트 및 인벤토리 배열 리플리케이션 설정
    • 두 컴포넌트를 bReplicates = true로 설정
    • 인벤토리 슬롯 배열을 UPROPERTY(ReplicatedUsing = OnRep_InventoryUpdated) 형태로 지정하여 클라이언트 UI 갱신 이벤트와 연동. (더 정밀한 동기화를 원한다면 FFastArraySerializer 고려)
  • [ ] 서버 검증 RPC (Server RPC) 구현
    • 아이템 장착, 해제, 물약 사용 등 인벤토리 데이터가 변하는 모든 행동은 클라이언트가 서버에 요청(Server_EquipItem, Server_UsePotion)하도록 RPC 구현
    • 서버에서 인벤토리 공간 유효성 검증(예: 가방이 정말 꽉 찼는지 서버에서 최종 확인) 후 데이터 변경 수행

[4단계] 상호작용 시스템 구축 (Interaction System) (예상 개발 기간 : 3~5일)

플레이어가 월드의 오브젝트(아이템, NPC, 구조물)와 통신하는 공용 인터페이스 기반 시스템을 만듭니다.

  • [ ] 상호작용 인터페이스 구현 (IInteractionInterface)
    • C++ 인터페이스를 생성하여 ExecuteInteraction(APlayerController* Interactor) 순수 가상 함수 정의
    • AItemActorBase, NPC 액터, 구조물 액터가 이 인터페이스를 상속받아 각자 다른 효과(아이템 획득, 대화 창 오픈, 상자 열기 등)를 처리하도록 오버라이딩
  • [ ] 플레이어 상호작용 레이캐스트/트레이스 로직
    • 플레이어 캐릭터에서 라인 트레이스(Line Trace) 또는 구체 충돌(Sphere Overlap)을 통해 1미터 이내의 상호작용 대상 감지
    • 대상이 감지되었을 때 F 키를 누르면 서버 RPC를 통해 해당 대상의 ExecuteInteraction 호출
    • 아이템 마우스 좌클릭 획득: 플레이어 컨트롤러에서 마우스 커서 아래의 액터를 감지(GetHitResultUnderCursor)하여 아이템일 경우 획득 RPC 요청
  • [ ] 상호작용 취소 조건 반영
    • ESC 버튼: 현재 열린 UI 창 및 대화 상태 종료
    • 자동 취소 (피격): 캐릭터 데미지 처리 함수(TakeDamage) 발생 시, 현재 진행 중인 상호작용 상태나 열려 있는 NPC 대화 UI를 강제로 닫는 로직 추가

[5단계] UI 및 최종 연동 (UI Integration & Polishing) (예상 개발 기간 : 4~5일)

기획서 내용이 화면에 정상적으로 출력되고 조작할 수 있도록 UMG(UI)와 C++ 핵심 로직을 바인딩합니다.

  • [ ] UI - C++ 데이터 바인딩
    • 인벤토리 컴포넌트의 데이터 변경(OnRep 이벤트 등)이 발생하면 UMG 슬롯들이 새로고침되도록 이벤트 디스패처 연동
  • [ ] 마우스 조작(우클릭/더블클릭) 기능 연동
    • 슬롯 UI에서 더블클릭 또는 우클릭 감지 시, 플레이어 컨트롤러를 통해 서버에 장착/해제/사용 RPC를 날리도록 구현