Unreal Engine, Item 설계 전 기초

아이템을 구현하기 전에 어떻게 설계할 것인지에 대한 고민이 있을 수 있다. 대부분의 게임들이 구현한 Item 들은 다음과 같은 이유로 Item에 대한 데이터 관계가 모두 다르게 개발될 수밖에 없다.

  • 아이템 착용 시 스테이터스 수치 요구사항
  • 아이템 착용 시 스테이터스 수치 증가 감소 (고정, 랜덤)
  • 강화된 아이템 수치 증가 감소 (고정, 랜덤)
  • 인벤토리 아이템 소유 시 어빌리티 시전
  • 인벤토리 아이템 소유 시 어빌리티 레벨 증가/감소
  • 캐릭터 아이템 착용 시 신규 몽타쥬가 포함된 스킬 추가
  • 인벤토리 아이템 소유 시 특정 이벤트 Map 발생
  • 인벤토리 아이템 소유 시 NPC 대화 가능 유무
  • 인벤토리 아이템 갯수 단일 / 복수 표현
  • 아이템 인벤토리 크기 2x2, 2x3
  • 캐릭터 아이템 착용 시 장비 장착
  • 인벤토리 아이템 강화 시 소멸 / 업그레이드
  • 캐릭터 아이템 세트 착용
  • 인벤토리 아이템 유저 거래
  • 인벤토리 아이템 NPC 거래
  • 인벤토리 아이템 퀘스트
  • 인벤토리 아이템 NPC / 인벤토리 조합
  • 바닥에 드랍한 아이템 유저 간 공유 유무
  • 우편함

나열한 아이템을 모두 게임에 구현하지 않고 일부만 구현해도 아이템에 대한 로직이 굉장히 커진다. 아이템 설계에 규칙, 수치가 고정된 경우 공통 설계로 아이템을 개발하는 방법도 있고, 디렉터 주도로 이루어진 복잡한 프로젝트인 경우 Slot 단위로 데이터 관계를 확립하고 게임 개발을 시작할 때 아이템부터 설계하기도 하다.


Lyra의 Item 설계

Unreal Engine 에서 튜토리얼처럼 제공하는 Lyra를 살펴보도록 한다.
FPS 게임이기 때문에 심화된 Item 구조로 만들지 않았지만, 어떻게 개발하였는지 엿볼 수 있다. 폴더 구조는 다음과 같이 되어있다.

My Project
└─Source
   └─LyraGame
      └─Inventory (*)
         └─InventoryFragment_EquippableItem.cpp
         └─InventoryFragment_EquippableItem.h
         └─InventoryFragment_PickupIcon.cpp
         └─InventoryFragment_PickupIcon.h
         └─InventoryFragment_QuickBarIcon.cpp
         └─InventoryFragment_QuickBarIcon.h
         └─InventoryFragment_SetStats.cpp
         └─InventoryFragment_SetStats.h
         └─IPickupable.cpp
         └─IPickupable.h
         └─LyraInventoryItemDefinition.cpp
         └─LyraInventoryItemDefinition.h
         └─LyraInventoryItemInstance.cpp
         └─LyraInventoryItemInstance.h
         └─LyraInventoryManagerComponent.cpp
         └─LyraInventoryManagerComponent.h
      
      

Lyra의 인벤토리를 확인할 수 있다.

  • LyraInventoryManagerComponent 파일
    • 대부분 프로젝트에서는 통합 관리하는 매니저가 있고, Lyra은 해당 파일에서 관리한다.
    • 이 매니저의 변수 TArray<FLayaInventoryEntry> Entries; 를 살펴보면, 아이템을 TArray로 담을 수 있도록 하고 있다.
  • LyraInventoryItemDefinition 파일
    • 아이템 시트의 구조, 타입을 설계되어 만들어진 파일이다.
  • LyraItemInstance 파일
    • 인 게임 아이템을 만드는 파일, IO 및 메모리 상에서 아이템을 관리한다.
    • Actor와 비슷할 수 있는데, 캐릭터 스폰시 입히는 아이템뿐 아니라 인게임에서 구현되지 않는 목걸이, 반지 같은 인스턴스 아이템도 관리할 수 있게 한다.

LyraInventoryManagerComponent 컴포넌트와 LyraInventoryItemDefinition 파일을 볼 수 있듯이 조각들을 모두 만들어 블루프린트 에디터에서 에셋을 붙이는 방식으로 생산성을 높인 방법이다.

스킬이나, 아이템 밸런스 수치 관련으로 엑셀 파일 내용대로 입력되도록 요구할 수 있는데, 이러한 Lyra 구조에서는 원칙을 깨야 할 수 있다.


Lyra 데이터 관계

Lyra 에서 어떻게 데이터 관계를 위한 구조체를 어떻게 만들었는지 살펴보도록 한다.
먼저, 상단의 LyraInventoryItemDefinition.h 파일을 열어본다.

Item 을 관리하기 위해 일반적으로 싱글톤과 복합체 디자인 패턴으로 구현하게 되는데, 헤더 파일에서 다음과 같은 코드가 있을 것이다. 살펴보면, Lyra에서는 공통된 기능으로 Fragments 라는 조각을 사용하고 있다.

  UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category=Display, Instance)
  TArray<TObjectPtr<ULyraInventoryItemFragment>> Fragments;

ULyraInventoryItemFragment 베이스 기반으로 Lyra 아이템 장착, 아이콘, 스탯 조각들이 들어가 인스턴스를 만들게 된다.

  • InventoryFragment_EquippableItem.cpp
  • InventoryFragment_EquippableItem.h
  • InventoryFragment_PickupIcon.cpp
  • InventoryFragment_PickupIcon.h
  • InventoryFragment_QuickBarIcon.cpp
  • InventoryFragment_QuickBarIcon.h
  • InventoryFragment_SetStats.cpp
  • InventoryFragment_SetStats.h