티스토리 뷰
🟩 학습 목표
- HasAuthority 가드 클로즈 및 OnRep_ 콜백의 네트워크 특성을 이해하고 Server RPC 데이터 흐름 정립
- FGameplayTag 문자열 기반 데이터 테이블 탐색 로직의 데이터 무결성 검증
- FindStackableSlot 자동 병합 알고리즘의 방어 코드와 예외 처리 시퀀스 실증
- 단일 책임 원칙(SRP)에 따라 데이터 차감은 인벤토리에 캡슐화하고, 시각적 처리는 멀티캐스트 델리게이트로 위임하는 확장형 API 설계
🟧 1. 멀티플레이어 네트워크 리플리케이션(Replication)의 함정과 해결
🟦 클라이언트 데이터 갱신 누락 현상
클라이언트 환경에서 아이템 획득(Add) 키 입력 이벤트를 트리거했으나, 관련 로그가 출력되지 않고 인벤토리 컨테이너 데이터가 전혀 갱신되지 않는 현상이 발생하였다.
🟦 원인 분석
- HasAuthority() 가드 클로즈: C++ 코어 레벨에서 데이터 변조(핵)를 방지하기 위해 서버 권한(HasAuthority())이 없는 클라이언트 프록시의 데이터 직접 수정 접근을 완벽하게 가드 차단하고 있었다.
- OnRep_ 콜백의 실행 특성: 언리얼 엔진 리플리케이션 시스템에서 OnRep_ 콜백 함수는 오직 클라이언트(Proxy) 단에서만 자동 실행된다. 서버(Authority) 측 본인의 데이터가 변경될 때는 이 콜백이 자동으로 트리거되지 않으므로 서버 로컬 UI 갱신 로직이 누락되는 구조적 특성이 존재한다.
🟦 해결 방법
블루프린트 입력 이벤트를 C++ 인벤토리 조작 함수에 직접 바인딩하지 않고, 중간에 Run on Server (Reliable) 속성이 부여된 커스텀 이벤트(Server RPC) 파이프라인을 거치도록 데이터 흐름을 교정하였다. 클라이언트가 요청하면 서버가 안전하게 데이터를 검증·수정하고, 변동된 값이 다시 클라이언트들에게 복제(Replicate)되도록 구조적 안정성을 확보하였다.
🟧 2. 데이터 테이블 탐색 로직과 문자열 매칭
🟦 FindRow 탐색 실패 이슈
C++ 내부에서 FindRow() 함수를 통해 아이템 데이터베이스를 조회할 때, 데이터가 존재함에도 지속적으로 false를 반환하며 아이템 정보를 로드하지 못하는 문제가 발생하였다.
🟦 원인 및 해결
언리얼 엔진의 FGameplayTag를 Convert하여 데이터 테이블의 행 이름(Row Name)과 매칭할 때, 문자열이 단 1글자의 오타(예: 마침표 . 누락 또는 대소문자 불일치)도 없이 완벽하게 일치해야 함을 확인하였다. 데이터 테이블의 Row Name 포맷을 ItemType.Consumable 등의 태그 문자열 구조와 정확히 1:1로 일치하도록 교정하여 정상 룩업(Lookup)을 완료하였다.
🟧 3. C++ 방어 로직과 자동 병합(Auto-Stack) 알고리즘 검증
🟦 Move 로직의 리턴 false 현상
0번 슬롯에 아이템을 획득한 후 1번 슬롯으로 이동(Move)시키고, 다시 0번에 아이템을 재획득한 뒤 1번 슬롯으로 복사 이동을 재시도했을 때, 두 번째 Move 시퀀스에서 지속적으로 false가 반환되는 현상이 관찰되었다.
🟦 예외 처리 알고리즘의 무결성 실증
- 분석: 코드의 논리적 결함이 아닌, 인벤토리 시스템에 내장된 FindStackableSlot(자동 병합 알고리즘)이 의도대로 정교하게 작동한 결과였다.
- 시퀀스 흐름: 두 번째로 아이템을 획득할 때, 시스템은 아이템을 빈 슬롯(0번)에 새로 할당하지 않고, 이미 동일한 태그를 가진 1번 슬롯의 기존 아이템 스택에 수량을 자동으로 합산(Combine)시켰다.
- 결론: 결과적으로 0번 슬롯은 계속 비어있는 상태(IsEmpty() == true)를 유지했으므로, 빈 슬롯에서 아이템을 옮기려 한 두 번째 Move 로직이 상위 가드 조건문에서 안전하게 방어 처리된 정상적인 동작임을 검증하였다.
🟧 4. 확장성을 고려한 단일 책임 원칙(SRP)과 델리게이트 활용
🟦 핵심 데이터 로직의 내부 캡슐화
아이템 사용(UseQuickSlot) 및 파밍(LootItem) 시 발생하는 핵심 비즈니스 로직(물약 등의 소모품 수량 차감 및 슬롯 비우기)을 메인 인벤토리 컴포넌트 내부에서 중앙 제어하도록 설계하여 데이터 무결성을 확보하였다.
🟦 멀티캐스트 델리게이트를 통한 시각/스탯 처리 위임 (Decoupling)
인벤토리 컴포넌트가 캐릭터의 물리적 스탯 변동(체력 회복)이나 외형적 변화(무기 장착 애니메이션 몽타주 재생)까지 직접 처리하는 것은 단일 책임 원칙에 위배된다.
이를 분리하기 위해 C++ 레벨에서 FOnItemUsedSignature (동적 멀티캐스트 델리게이트)를 선언하였다. 인벤토리는 데이터 연산 완료 후 해당 델리게이트를 브로드캐스트(Broadcast)하기만 하고, 실제 시각적/체력적 변화는 이를 구독하는 캐릭터 블루프린트 파트에서 유연하게 수신하여 처리할 수 있도록 견고한 통합 API를 제공하였다.
🟧 후속 작업
- 완성된 C++ 백엔드 델리게이트(OnInventoryUpdated)를 UMG(블루프린트 위젯)와 바인딩하여 실제 화면에 인벤토리 그리드를 시각화한다.
- 아이템 드래그 앤 드롭 UI 기능 연동을 수행하여 데이터와 시각적 인터랙션을 통합한다.
🟧 핵심 요약
- 클라이언트의 불법 데이터 변조를 막기 위해 HasAuthority() 검증을 거치는 Server RPC 보안 파이프라인 정립
- FGameplayTag 문자열 데이터 구조와 데이터 테이블 Row Name의 1:1 매칭 구조를 정교화하여 탐색 오류 해결
- FindStackableSlot이 유효 스택을 찾아 선병합함에 따라 발생하는 슬롯 공백 상태와, 이에 따른 Move 함수의 방어 예외 처리가 정상 작동함 실증
- 백엔드 데이터 관리(Inventory)와 프론트엔드 비주얼 표현(Character ABP)의 결합도를 낮추기 위해 동적 멀티캐스트 델리게이트 기반의 분업 아키텍처 완성
'내일배움캠프 Unreal_7기 > 본캠프' 카테고리의 다른 글
| 멀티플레이 인벤토리 - 드래그 앤 드롭 구현 및 데이터·액터 분리 구조의 이해 (0) | 2026.06.02 |
|---|---|
| 캐릭터 상호작용 시스템 아키텍처 구현 및 포스트 프로세스 최적화 (0) | 2026.06.01 |
| 인벤토리 UI 최적화, 협업 아키텍처 및 MVP 구현 전략 (1) | 2026.05.28 |
| 게임플레이 태그 기반 인벤토리 C++ 아키텍처 및 코어 로직 구현 (0) | 2026.05.27 |
| 캐릭터 상태 제어 리팩토링 및 멀티플레이 동기화 (0) | 2026.05.26 |

