티스토리 뷰
🟩 학습 목표
- 인벤토리 슬롯 데이터에 데이터 테이블 Key 값을 연동하여 런타임 동적 에셋 복원 및 데이터 주도형 아키텍처를 수립한다.
- FDataTableRowHandle 및 리플렉션 한정자를 활용하여 레벨 디자이너의 휴먼 에러를 원천 차단하는 방어적 C++ 클래스를 설계한다.
- OnConstruction 라이프사이클 함수를 오버라이드하여 에디터 뷰포트 내 실시간 위지윅(WYSIWYG) 데이터 동기화 시스템을 구현한다.
🟧 1. Data-Driven 인벤토리 아키텍처 개편
🟦 추상 데이터 기반 에셋 복원의 한계점 분석
기존 시스템은 FGameplayTag만을 기반으로 아이템의 카테고리를 분류하였다. 이로 인해 아이템을 필드에 재드롭(Server_DropItem)하는 시점에 해당 아이템이 본래 소유하고 있던 고유 스태틱 메쉬(예: 특정 장비의 고유 외형)가 무엇인지 역산해내지 못하고 기본 베이스 껍데기로만 스폰되는 아키텍처적 한계가 존재하였다.
🟦 ItemID 연동을 통한 동적 메쉬 스폰 메커니즘
인벤토리 최소 단위 구조체인 FInventorySlot이 데이터 테이블의 고유 식별자인 ItemID(Row Name)를 직접 기억하도록 데이터 구조를 개편하였다.
아이템 버리기 함수(Server_DropItem_Implementation)가 호출되면, 슬롯에 저장되어 있던 ItemID를 Key값으로 삼아 DT_ItemData 테이블을 탐색(Lookup)한다. 이후 추출된 행 데이터 내부의 스태틱 메쉬 레퍼런스를 기본 마네킹 액터인 NCItemActor에게 동적으로 주입하여 원본 외형을 완벽하게 복원 및 스폰하도록 로직을 고도화하였다.
🟧 2. 휴먼 에러 방지를 위한 C++ 변수 및 제약 조건 설계
🟦 FDataTableRowHandle을 활용한 데이터 무결성 확보
레벨 디자이너나 기획자가 월드 뷰포트에 아이템 액터를 배치하고 고유 식별자를 문자열(FName, FString) 형태로 직접 타이핑하게 할 경우, 마침표 누락이나 대소문자 오타 등으로 인해 데이터베이스 조회 연산이 실패하는 휴먼 에러가 필연적으로 발생한다.
이를 방지하기 위해 C++ 헤더에 데이터 테이블과 행을 명시적으로 결합하는 FDataTableRowHandle 구조체를 도입하였다.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item Setting")
FDataTableRowHandle ItemDataHandle;
이 구조체를 선언하면 언리얼 에디터 디테일 패널상에 텍스트 입력창 대신 등록된 데이터 테이블의 모든 Row Name을 직관적으로 선택할 수 있는 '드롭다운 컴보 박스' 목록이 생성되므로 데이터 입력 무결성을 원천 확보할 수 있다.
🟦 VisibleAnywhere를 통한 데이터 변조 방지 (Read-Only)
ItemID나 ItemTypeTag와 같이 데이터 테이블 룩업 완료 후 런타임에 결정되는 핵심 원본 변수들을 사용자가 에디터에서 임의로 수정하여 싱크가 깨지는 현상을 방지해야 한다. 이를 위해 해당 속성들을 읽기 전용으로 제약하는 VisibleAnywhere 매크로를 적용하여 사용자는 눈으로 데이터 검증만 수행하고 직접적인 값 수정은 불가능하도록 방어 코드를 설계하였다.
🟧 3. OnConstruction 오버라이드를 통한 위지윅(WYSIWYG) 환경 구축
🟦 에디터 타임 빌드 시퀀스의 필요성
기존의 BeginPlay() 기반 에셋 할당 로직은 시뮬레이션 버튼(Play)을 누르기 전까지는 월드에 배치된 아이템 액터가 실제 도끼인지, 회복 포션인지 뷰포트상에서 외형적으로 확인할 수 없어 레벨 디자인의 직관성을 저해하는 요소였다.
🟦 실시간 뷰포트 동기화 구현
액터가 월드에 배치되거나 디테일 패널의 컴포넌트 변수 수치가 변경될 때 에디터 타임에서 즉시 트리거되는 라이프사이클 함수인 OnConstruction을 오버라이드하였다.
// NCItemActor.h 선언부
virtual void OnConstruction(const FTransform& Transform) override;
// NCItemActor.cpp 구현부
void ANCItemActor::OnConstruction(const FTransform& Transform)
{
Super::OnConstruction(Transform);
if (ItemDataHandle.DataTable && !ItemDataHandle.RowName.IsNone())
{
// 에디터 타임에서 드롭다운 수정을 감지하여 즉시 테이블 데이터 파싱
FItemData* RowData = ItemDataHandle.DataTable->FindRow<FItemData>(ItemDataHandle.RowName, TEXT("OnConstructionFetch"));
if (RowData && MeshComponent)
{
// 플레이 버튼을 누르지 않아도 뷰포트에 실시간 메쉬 변경 반영
MeshComponent->SetStaticMesh(RowData->ItemStaticMesh);
}
}
}
기획자가 디테일 패널에서 아이템 ID를 클릭하는 순간, 백엔드에서 데이터 테이블을 즉각 서치하여 SetStaticMesh를 구동하므로 레벨 디자이너가 인게임 결과를 실시간으로 예측하며 배치할 수 있는 고효율 작업 환경을 완성하였다.
🟧 핵심 요약
- 슬롯 구조체가 태그를 넘어 테이블 고유 Key인 ItemID를 추적하도록 개편하여 동적 외형 복원 파이프라인을 구축하였다.
- FDataTableRowHandle 구조체를 연동하여 에디터 내 데이터 입력을 드롭다운 방식으로 규격화하고 오타 버그를 원천 배제하였다.
- VisibleAnywhere 지정을 통해 기획 데이터의 수동 변조 가능성을 차단하고 시스템 내부 데이터의 안전성을 확보하였다.
- OnConstruction 함수 캐싱을 활용해 에디터 런타임 이전에 메쉬 데이터를 즉각 동기화하는 위지윅 레벨 디자인 아키텍처를 완수하였다.
'내일배움캠프 Unreal_7기 > 본캠프' 카테고리의 다른 글
| 파밍 상자 확률 시스템 구현 및 PlayerState 기반 인벤토리 아키텍처 리팩토링 (0) | 2026.06.09 |
|---|---|
| UMG Drag & Drop 이벤트 처리의 함정과 인벤토리 세이브/로드 아키텍처 (0) | 2026.06.08 |
| 멀티플레이 인벤토리 - 드래그 앤 드롭 구현 및 데이터·액터 분리 구조의 이해 (0) | 2026.06.02 |
| 캐릭터 상호작용 시스템 아키텍처 구현 및 포스트 프로세스 최적화 (0) | 2026.06.01 |
| 멀티플레이 인벤토리 코어 시스템 구축 및 네트워크 데이터 흐름 검증 (1) | 2026.05.29 |

