> For the complete documentation index, see [llms.txt](/llms.txt)

# GS2-Inventory SDK for Game Engine API 레퍼런스

게임 엔진용 GS2-Inventory SDK의 모델 사양과 API 레퍼런스



## 모델

### EzInventory

인벤토리<br>

인벤토리는 게임 플레이어가 소유한 아이템을 보관하기 위한 가방과 같은 것입니다.<br>
가방에는 용량이 있으며, 플레이어마다 용량을 확장할 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| inventoryId | string |  | ※ |  |  ~ 1024자 | 인벤토리 GRN<br>※ 서버가 자동으로 설정 |
| inventoryName | string |  | ✓ |  |  ~ 128자 | 인벤토리 모델 이름<br>이 인벤토리의 구조와 용량 설정을 정의하는 인벤토리 모델의 이름입니다. 사용자의 인벤토리 인스턴스를 모델 정의에 연결하여 사용 가능한 아이템의 종류와 용량 제한을 결정합니다. |
| currentInventoryCapacityUsage | int |  |  | 0 | 0 ~ 2147483646 | 용량 사용량<br>아이템 세트에 의해 현재 사용되고 있는 인벤토리 슬롯의 수입니다. 새로운 아이템 스택이 추가될 때(예: allowMultipleStacks에 의해 새로운 슬롯이 생성될 때) 증가하고, 아이템 세트가 완전히 소비되거나 삭제될 때 감소합니다. currentInventoryMaxCapacity를 초과할 수 없습니다. |
| currentInventoryMaxCapacity | int |  | ✓ |  | 1 ~ 2147483646 | 최대 용량<br>이 사용자가 사용할 수 있는 인벤토리 슬롯의 현재 최대 수입니다. 인벤토리 모델의 initialCapacity로 초기화되며, 입수 액션 또는 직접적인 API 호출을 통해 모델의 maxCapacity까지 확장할 수 있습니다. |

**관련 메서드:**
getInventory - 특정 인벤토리의 상세 정보 조회
listInventories - 플레이어의 인벤토리 목록 조회
consume - 플레이어의 인벤토리에서 아이템 사용(소비)
getItem - 인벤토리 이름과 아이템 이름으로 특정 아이템 조회
getItemWithSignature - 소지 증명 서명이 포함된 아이템 조회


---

### EzItemSet

아이템 세트<br>

아이템 세트는 게임 플레이어의 인벤토리 내에 저장된 소유물을 나타냅니다.<br>
인벤토리 모델명과 아이템 모델명, 소지 수량, 유효기간 등을 보유합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| itemSetId | string |  | ※ |  |  ~ 1024자 | 아이템 세트 GRN<br>※ 서버가 자동으로 설정 |
| name | string |  | ✓ | UUID |  ~ 36자 | 아이템 세트를 식별하는 이름<br>아이템 세트의 고유한 이름을 보유합니다.<br>이름은 UUID(Universally Unique Identifier) 형식으로 자동 생성되며, 각 아이템 세트를 식별하는 데 사용됩니다. |
| inventoryName | string |  | ✓ |  |  ~ 128자 | 인벤토리 모델명<br>이 아이템 세트를 포함하는 인벤토리 모델의 이름입니다. itemName과 함께 사용되어 이 소지품이 어떤 인벤토리와 아이템 종류에 속하는지를 식별하는 데 사용됩니다. |
| itemName | string |  | ✓ |  |  ~ 128자 | 아이템 모델명<br>이 세트에 저장된 아이템의 종류를 정의하는 아이템 모델의 이름입니다. inventoryName과 조합하여 이 아이템 세트의 스택 상한과 다중 스택 동작을 결정합니다. |
| count | long |  | ✓ |  | 1 ~ 9223372036854775805 | 소지 수량<br>이 스택 내의 아이템 수입니다. 1부터 아이템 모델의 스택 상한까지의 범위입니다. 아이템을 입수하면 스택 상한까지 수량이 증가하고, 소비하면 감소합니다. 수량이 0이 되면 아이템 세트는 삭제되고 인벤토리 슬롯이 해제됩니다. |
| sortValue | int |  | ✓ |  | 0 ~ 2147483646 | 표시 순서<br>아이템 모델의 sortValue에서 복사된 숫자 값으로, 인벤토리 내에서 아이템 세트를 표시용으로 정렬하는 데 사용됩니다. 값이 작을수록 먼저 표시됩니다. |
| expiresAt | long |  |  | 0 |  | 유효기간<br>UNIX 시간·밀리초 |
| referenceOf | List&lt;string&gt; |  |  | [] | 0 ~ 24 items | 참조원 목록<br>이 아이템 세트에 등록된 외부 참조입니다. 어떤 시스템이 이 아이템을 사용하고 있는지(예: 무기로 장비, 편성에 할당)를 추적하는 데 사용됩니다. 아이템 세트당 최대 24개의 참조입니다. |

**관련 메서드:**
consume - 플레이어의 인벤토리에서 아이템 사용(소비)
getItem - 인벤토리 이름과 아이템 이름으로 특정 아이템 조회
getItemWithSignature - 소지 증명 서명이 포함된 아이템 조회
listItems - 인벤토리 내 플레이어가 소지한 아이템 목록 조회


---

### EzSimpleItem

심플 아이템<br>

심플 아이템은 게임 플레이어의 인벤토리 내에 저장된 소유물을 나타냅니다.<br>
심플 아이템은 모델 이름과 소지 수량을 가집니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| itemId | string |  | ※ |  |  ~ 1024자 | 심플 아이템 GRN<br>※ 서버가 자동으로 설정 |
| itemName | string |  | ✓ |  |  ~ 128자 | 심플 아이템 모델 이름<br>이 레코드에 저장된 아이템의 종류를 정의하는 심플 아이템 모델의 이름입니다. 이 소지품이 어떤 아이템 정의에 대응하는지 식별하는 데 사용됩니다. |
| count | long |  | ✓ |  | 0 ~ 9223372036854775805 | 소지 수량<br>사용자가 소지한 이 아이템 종류의 수량입니다. 일반적인 인벤토리 아이템과 달리 심플 아이템에는 스택 상한이 없으며, 수량은 int64 범위 내에서 임의의 값을 가질 수 있습니다. 다른 심플 아이템과 함께 일괄 처리로 증감할 수 있습니다. |

**관련 메서드:**
consumeSimpleItems - 플레이어의 인벤토리에서 심플 아이템 사용(소비)
getSimpleItem - 특정 심플 아이템의 소지 수량 조회
getSimpleItemWithSignature - 소지 증명 서명이 포함된 심플 아이템 조회
listSimpleItems - 인벤토리 내 플레이어가 소지한 심플 아이템 목록 조회


---

### EzBigItem

거대 아이템<br>

거대 아이템은 게임 플레이어의 거대 인벤토리 내에 저장되어 있는 소유물을 나타냅니다.<br>
거대 아이템 모델 이름과, int64 범위를 초과하는 소지 수량을 보유합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| itemId | string |  | ※ |  |  ~ 1024자 | 거대 아이템 GRN<br>※ 서버가 자동으로 설정 |
| itemName | string |  | ✓ |  |  ~ 128자 | 거대 아이템 모델 이름<br>이 레코드에 저장된 아이템의 종류를 정의하는 거대 아이템 모델의 이름입니다. 이 거대 아이템 소지품이 어떤 아이템 정의에 대응하는지 식별하는 데 사용됩니다. |
| count | string<br>BigInteger (Unity) |  | ✓ |  |  ~ 1024자 | 소지 수량<br>최대 1024자리까지의 정수값 문자열 |

**관련 메서드:**
consumeBigItem - 플레이어의 인벤토리에서 대형 아이템 사용(소비)
getBigItem - 특정 대형 아이템의 소지 수량 조회
listBigItems - 인벤토리 내 플레이어가 소지한 대형 아이템 목록 조회


---

### EzInventoryModel

인벤토리 모델<br>

인벤토리는 게임 플레이어가 소유한 아이템을 담는 가방과 같은 것입니다.<br>
인벤토리에는 용량을 설정할 수 있으며, 용량을 초과하여 소유할 수 없습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 인벤토리 모델 이름<br>인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 2048자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |
| initialCapacity | int |  | ✓ |  | 0 ~ 2147483646 | 초기 크기<br>인벤토리가 처음 생성될 때 사용자에게 제공되는 인벤토리 칸의 수입니다. 각 칸에는 하나의 아이템 스택을 저장할 수 있습니다. 사용자는 게임 플레이 액션을 통해 maxCapacity까지 용량을 확장할 수 있습니다. |
| maxCapacity | int |  | ✓ |  | 0 ~ 2147483646 | 최대 크기<br>사용자가 확장할 수 있는 인벤토리 칸의 상한값입니다. 이 값을 초과하여 용량을 늘릴 수 없습니다. 모든 칸이 사용 중이고 아이템을 더 이상 스택할 수 없는 경우, 오버플로우 스크립트가 초과분을 처리하지 않는 한 입수는 실패합니다. |

**관련 메서드:**
getInventoryModel - 이름으로 특정 인벤토리 타입 정의 조회
listInventoryModels - 인벤토리 타입 정의 목록 조회


---

### EzItemModel

아이템 모델<br>

아이템은 포션 ×99 처럼, 하나의 인벤토리 칸에 여러 개를 모아서 소지할 수 있습니다.<br>
이렇게 한 칸에 여러 개를 모으는 것을 "스택"이라고 하며, 아이템마다 스택 가능한 상한 수를 설정할 수 있습니다.<br>

스택 상한에 도달했을 때의 동작도 아이템마다 설정할 수 있습니다.<br>
구체적으로는 다음 중 하나를 선택할 수 있습니다:<br>

- 새로운 인벤토리 칸을 추가하여 추가로 소지할 수 있도록 한다<br>
- 상한에 도달했으므로 더 이상 입수할 수 없도록 한다

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 아이템 모델 이름<br>아이템 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 2048자 | 메타데이터<br>GS2-Enhance에는 GS2-Inventory와 연동하여 강화를 수행하는 메커니즘이 있으며, ItemModel의 메타데이터에 JSON 형식으로 강화 소재로 사용했을 때의 경험치량을 설정합니다.<br>자세한 내용은 [마이크로서비스 소개 / GS2-Enhance](/microservices/enhance/#강화-레이트) 항목에서 설명합니다. |
| stackingLimit | long |  | ✓ |  | 1 ~ 9223372036854775805 | 스택 가능한 최대 수량<br>하나의 인벤토리 칸(스택)에 보관할 수 있는 이 아이템의 최대 수입니다. 이 상한에 도달하면 allowMultipleStacks 설정에 따라 새로운 칸이 할당되거나 추가 입수가 차단됩니다. |
| allowMultipleStacks | bool |  | ✓ |  |  | 복수 스택 허용<br>활성화하면 스택 상한에 도달했을 때 새로운 인벤토리 칸이 자동으로 할당되어 이 아이템의 추가 수량을 저장합니다(추가 용량을 소비합니다). 비활성화하면 기존 칸에서 스택 상한에 도달한 시점에 입수가 차단됩니다. |
| sortValue | int |  | ✓ |  | 0 ~ 2147483646 | 표시 순서<br>인벤토리 내 아이템을 표시용으로 정렬하기 위한 수치입니다. 값이 작을수록 먼저 표시됩니다. 이 값은 ItemSet 레코드에도 복사되어 소지 아이템의 일관된 정렬을 가능하게 합니다. |

**관련 메서드:**
getItemModel - 이름으로 특정 아이템 정의 조회
listItemModels - 인벤토리 내 아이템 정의 목록을 취득한다
consume - 플레이어의 인벤토리에서 아이템 사용(소비)
getItem - 인벤토리 이름과 아이템 이름으로 특정 아이템 조회
getItemWithSignature - 소지 증명 서명이 포함된 아이템 조회


---

### EzSimpleInventoryModel

심플 인벤토리 모델<br>

일반적인 InventoryModel에서는 인벤토리 안에 저장할 수 있는 아이템의 용량 제한을 설정할 수 있었습니다.<br>
하지만 심플 인벤토리에는 그러한 기능이 없으며, 단순히 아이템의 소지 수량을 보유할 뿐입니다.<br>

다만 심플 인벤토리에서는 여러 아이템의 증감 처리를 한 번의 처리로 실행할 수 있는 API를 사용할 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 심플 인벤토리 모델 이름<br>심플 인벤토리 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 2048자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |

**관련 메서드:**
getSimpleInventoryModel - 이름으로 특정 심플 인벤토리 타입 정의 조회
listSimpleInventoryModels - 심플 인벤토리 타입 정의 목록 조회


---

### EzSimpleItemModel

심플 아이템 모델<br>

ItemModel에서는 스택할 수 있는 수량의 최댓값을 설정할 수 있어, 일정 수를 초과하는 경우 여러 스택으로 나누는 구현이 가능했습니다.<br>
심플 아이템에는 그러한 기능이 없으며, 단순히 아이템의 소지 수량만을 보관합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 심플 아이템 모델 이름<br>심플 아이템 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 2048자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |

**관련 메서드:**
getSimpleItemModel - 이름을 지정하여 심플 아이템 정의를 취득한다
listSimpleItemModels - 심플 인벤토리 내 아이템 정의 목록을 취득한다
getSimpleItem - 특정 심플 아이템의 소지 수량 조회
getSimpleItemWithSignature - 소지 증명 서명이 포함된 심플 아이템 조회


---

### EzBigInventoryModel

거대 인벤토리 모델<br>

일반적인 InventoryModel이나 SimpleInventoryModel에서는 인벤토리에 저장할 수 있는 아이템의 수가 int64 범위로 제한되었습니다.<br>
인플레이션 계열 게임에서는 더 넓은 범위의 값이 필요한 경우가 있습니다.<br>

거대 인벤토리 모델에서는 인벤토리에 저장할 수 있는 아이템의 수가 최대 1024자리의 정수값을 가질 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 거대 인벤토리 모델 이름<br>거대 인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 2048자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |

**관련 메서드:**
getBigInventoryModel - 이름으로 특정 대형 인벤토리 타입 정의 조회
listBigInventoryModels - 대형 인벤토리 타입 정의 목록 조회


---

### EzBigItemModel

거대 아이템 모델<br>

거대 아이템 모델은 거대 인벤토리 모델에 저장되는 거대 아이템을 정의하는 모델입니다.<br>
거대 아이템은 소지 수량을 int64 범위를 초과하여 보유할 수 있습니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ |  |  ~ 128자 | 거대 아이템 모델 이름<br>거대 아이템 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| metadata | string |  |  |  |  ~ 2048자 | 메타데이터<br>메타데이터에는 임의의 값을 설정할 수 있습니다.<br>이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. |

**관련 메서드:**
getBigItemModel - 이름으로 특정 대형 아이템 정의 조회
listBigItemModels - 인벤토리 내 대형 아이템 정의 목록 조회
getBigItem - 특정 대형 아이템의 소지 수량 조회


---

### EzConsumeCount

심플 아이템의 소비 수량

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| itemName | string |  | ✓ |  |  ~ 128자 | 심플 아이템 모델 이름<br>이 레코드에 저장된 아이템의 종류를 정의하는 심플 아이템 모델의 이름입니다. 이 소지품이 어떤 아이템 정의에 대응하는지 식별하는 데 사용됩니다. |
| count | long |  | ✓ |  | 1 ~ 9223372036854775805 | 소비 수량 |

**관련 메서드:**
consumeSimpleItems - 플레이어의 인벤토리에서 심플 아이템 사용(소비)


---

### EzAcquireCount

심플 아이템의 입수 수량

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| itemName | string |  | ✓ |  |  ~ 128자 | 심플 아이템 모델 이름<br>이 레코드에 저장된 아이템의 종류를 정의하는 심플 아이템 모델의 이름입니다. 이 소지품이 어떤 아이템 정의에 대응하는지 식별하는 데 사용됩니다. |
| count | long |  | ✓ |  | 1 ~ 9223372036854775805 | 입수하는 양 |


---

## 메서드

### getInventoryModel

이름으로 특정 인벤토리 타입 정의 조회<br>

이름을 지정하여 인벤토리 모델을 1건 조회합니다.<br>
조회되는 정보에는 초기 용량과 최대 용량, 아이템 보호 설정, 이 인벤토리에 속한 모든 아이템 모델이 포함됩니다.<br>
특정 인벤토리 타입의 상세 정보를 표시할 때 사용합니다. 예를 들어 "장비 가방 — 용량: 50/100 — 아이템: 철검, 강철 방패, 가죽 갑옷…"과 같은 표시에 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 인벤토리 모델 이름<br>인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzInventoryModel](#ezinventorymodel) | 인벤토리 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->InventoryModel(
        "item" // inventoryName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).inventory_model(
        "item"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->InventoryModel(
        "item" // inventoryName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Inventory::Model::FInventoryModel> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).inventory_model(
        "item"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### listInventoryModels

인벤토리 타입 정의 목록 조회<br>

이 네임스페이스에 등록된 모든 인벤토리 모델을 조회합니다.<br>
인벤토리 모델은 아이템을 담는 컨테이너의 종류를 정의합니다. "장비 가방", "재료 주머니", "소모품 상자" 등이 있습니다.<br>
각 모델에는 초기 용량과 최대 용량(몇 종류의 아이템을 담을 수 있는지)이 설정되어 있으며, 담을 수 있는 아이템 모델의 목록도 포함됩니다.<br>
플레이어가 어떤 종류의 인벤토리를 가지고 있는지 표시할 때 사용합니다. 예를 들어 "장비(50/100 슬롯)", "재료(30/200 슬롯)"와 같은 탭 표시에 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzInventoryModel&gt;](#ezinventorymodel) | 인벤토리 모델 리스트|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    var items = await domain.InventoryModelsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    var it = domain.InventoryModels(
    );
    List<EzInventoryModel> items = new List<EzInventoryModel>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto It = Domain->InventoryModels(
    );
    TArray<Gs2::UE5::Inventory::Model::FEzInventoryModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeInventoryModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeInventoryModels(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeInventoryModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeInventoryModels(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeInventoryModels(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeInventoryModels(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getItemModel

이름으로 특정 아이템 정의 조회<br>

인벤토리 이름과 아이템 이름을 지정하여 아이템 모델을 1건 조회합니다.<br>
조회되는 정보에는 최대 스택 수, 복수 스택 지원 여부(예: 유효기간이 다른 아이템은 별도 스택에 저장됨), 정렬 순서가 포함됩니다.<br>
아이템 규칙을 표시할 때 사용합니다. 예를 들어 "회복 포션 — 스택당 최대: 99개 — 유효기간이 다른 것은 별도 스택으로 보관"과 같은 표시에 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 인벤토리 모델 이름<br>인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| itemName | string |  | ✓|  |  ~ 128자 | 아이템 모델 이름<br>아이템 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzItemModel](#ezitemmodel) | |

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    ).ItemModel(
        itemName: "item-master-0001"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    ).ItemModel(
        itemName: "item-master-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->InventoryModel(
        "item" // inventoryName
    )->ItemModel(
        "item-master-0001" // itemName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).inventory_model(
        "item"
    ).item_model(
        "item-master-0001"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    ).ItemModel(
        itemName: "item-master-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    ).ItemModel(
        itemName: "item-master-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->InventoryModel(
        "item" // inventoryName
    )->ItemModel(
        "item-master-0001" // itemName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Inventory::Model::FItemModel> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).inventory_model(
        "item"
    ).item_model(
        "item-master-0001"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### listItemModels

인벤토리 내 아이템 정의 목록을 취득한다<br>

지정한 인벤토리에 속하는 모든 아이템 모델을 취득합니다.<br>
아이템 모델은 특정 아이템 타입의 규칙을 정의합니다. 최대 스택 수(예: 물약은 99개까지 쌓을 수 있음), 복수 스택으로 분할 가능한지, 표시 정렬 순서 등입니다.<br>
인벤토리에 어떤 종류의 아이템이 존재할 수 있는지 표시하는 데 사용합니다. 예를 들어 "장비 가방"의 전체 장비 타입이나 "소재 주머니"의 전체 소재를 목록으로 표시할 때 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 인벤토리 모델 이름<br>인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzItemModel&gt;](#ezitemmodel) | 아이템 모델 리스트|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    );
    var items = await domain.ItemModelsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    );
    var it = domain.ItemModels(
    );
    List<EzItemModel> items = new List<EzItemModel>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->InventoryModel(
        "item" // inventoryName
    );
    const auto It = Domain->ItemModels(
    );
    TArray<Gs2::UE5::Inventory::Model::FEzItemModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeItemModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeItemModels(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).InventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeItemModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeItemModels(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->InventoryModel(
        "item" // inventoryName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeItemModels(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeItemModels(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getInventory

특정 인벤토리의 상세 정보 조회<br>

이름을 지정하여 특정 인벤토리의 상세 정보를 조회합니다. 현재 용량 사용 현황(사용 중인 슬롯 / 최대 슬롯)이 포함됩니다.<br>
특정 인벤토리의 상태를 표시할 때 사용합니다. 예를 들어 장비 인벤토리 화면 상단에 "장비 가방 — 45 / 100 슬롯 사용 중"이라고 표시하는 데 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 인벤토리 모델 이름<br>이 인벤토리의 구조와 용량 설정을 정의하는 인벤토리 모델의 이름입니다. 사용자의 인벤토리 인스턴스를 모델 정의에 연결하여 사용 가능한 아이템의 종류와 용량 제한을 결정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzInventory](#ezinventory) | 인벤토리|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "inventory-0001"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "inventory-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Inventory(
        "inventory-0001" // inventoryName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).inventory(
        "inventory-0001"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "inventory-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "inventory-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Inventory(
        "inventory-0001" // inventoryName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Inventory::Model::FInventory> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).inventory(
        "inventory-0001"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### listInventories

플레이어의 인벤토리 목록 조회<br>

플레이어가 보유한 모든 인벤토리를 조회합니다.<br>
각 인벤토리에는 현재 용량 사용 현황(최대 용량 중 몇 종류의 아이템(슬롯)이 사용되고 있는지)이 포함됩니다.<br>
인벤토리 개요 화면을 구성할 때 사용합니다. 예를 들어 "장비 가방: 45/100 슬롯 사용 중", "재료 주머니: 120/200 슬롯 사용 중"과 같이 플레이어의 아이템 컨테이너를 목록으로 표시하는 화면에 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| pageToken | string |  | |  |  ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |
| limit | int |  | | 30 | 1 ~ 1000 | 취득할 데이터 건수 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzInventory&gt;](#ezinventory) | 인벤토리 목록|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.InventoriesAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.Inventories(
    );
    List<EzInventory> items = new List<EzInventory>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto It = Domain->Inventories(
    );
    TArray<Gs2::UE5::Inventory::Model::FEzInventoryPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeInventories(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeInventories(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeInventories(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeInventories(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeInventories(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeInventories(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### consume

플레이어의 인벤토리에서 아이템 사용(소비)<br>

플레이어의 인벤토리에 있는 특정 아이템의 수량을 줄입니다. 게임 고유의 로직으로 플레이어가 아이템을 사용하거나 소비하는 경우에 사용합니다.<br>
예를 들어, 전투에서 회복 포션을 사용하거나, 제작 재료를 소비하거나, 커스텀 게임 기능에서 아이템을 사용하는 경우입니다.<br>
주의: 상품 구매(GS2-Showcase)나 퀘스트 시작(GS2-Quest)의 대가로 아이템을 소비하는 경우에는 해당 시스템이 자동으로 처리하므로, 이 API를 호출할 필요가 없습니다.<br>
어느 스택(itemSetName)에서 소비할지 선택적으로 지정할 수 있습니다. 생략하면 가장 오래된 스택부터 우선적으로 소비됩니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 인벤토리 모델명<br>이 아이템 세트를 포함하는 인벤토리 모델의 이름입니다. itemName과 함께 사용되어 이 소지품이 어떤 인벤토리와 아이템 종류에 속하는지를 식별하는 데 사용됩니다. |
| itemName | string |  | ✓|  |  ~ 128자 | 아이템 모델명<br>이 세트에 저장된 아이템의 종류를 정의하는 아이템 모델의 이름입니다. inventoryName과 조합하여 이 아이템 세트의 스택 상한과 다중 스택 동작을 결정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| consumeCount | long |  | ✓|  | 1 ~ 9223372036854775805 | 소비 수량 |
| itemSetName | string |  | |  |  ~ 36자 | 아이템 세트를 식별하는 이름 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzItemSet&gt;](#ezitemset) | 소비 후 아이템 세트 리스트|
| itemModel | [EzItemModel](#ezitemmodel) | 아이템 모델|
| inventory | [EzInventory](#ezinventory) | 인벤토리|

#### Error

이 API에는 특별한 예외가 정의되어 있습니다.<br>
GS2-SDK for Game Engine에서는 게임 내에서 핸들링이 필요할 것으로 예상되는 에러를, 일반적인 예외에서 파생된 특수화된 예외로 제공하여 다루기 쉽게 하고 있습니다.<br>
일반적인 에러의 종류와 핸들링 방법은 [여기]() 문서를 참고해 주세요.

| 타입 | 베이스 클래스 | 설명 |
| --- | --- | --- |
| ConflictException | ConflictException | 아이템 조작 처리가 충돌했습니다. 재시도가 필요합니다. |
| InsufficientException | BadRequestException | 아이템 소지 수량이 부족합니다. |

#### 구현 예제




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "inventory-0001"
    ).ItemSet(
        itemName: "item-0001",
        itemSetName: null
    );
    var result = await domain.ConsumeAsync(
        consumeCount: 1L
    );
    var item = await result.ModelAsync();
} catch(Gs2.Gs2Inventory.Exception.ConflictException e) {
    // Item manipulation process conflicted. Retry required.
} catch(Gs2.Gs2Inventory.Exception.InsufficientException e) {
    // Insufficient quantity of items in your possession.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "inventory-0001"
    ).ItemSet(
        itemName: "item-0001",
        itemSetName: null
    );
    var future = domain.ConsumeFuture(
        consumeCount: 1L
    );
    yield return future;
    if (future.Error != null)
    {
        if (future.Error is Gs2.Gs2Inventory.Exception.ConflictException)
        {
            // Item manipulation process conflicted. Retry required.
        }
        if (future.Error is Gs2.Gs2Inventory.Exception.InsufficientException)
        {
            // Insufficient quantity of items in your possession.
        }
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Inventory(
        "inventory-0001" // inventoryName
    )->ItemSet(
        "item-0001", // itemName
        nullptr // itemSetName
    );
    const auto Future = Domain->Consume(
        1L // consumeCount
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        auto e = Future->GetTask().Error();
        if (e->IsChildOf(Gs2::Inventory::Error::FConflictError::Class))
        {
            // Item manipulation process conflicted. Retry required.
        }
        if (e->IsChildOf(Gs2::Inventory::Error::FInsufficientError::Class))
        {
            // Insufficient quantity of items in your possession.
        }
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).inventory(
        "inventory-0001"
    ).item_set(
        "item-0001",
        null
    )

var async_result = await domain.consume(
    1 # consume_count
)
if async_result.error != null:
    if async_result.error is Gs2InventoryConflictException:
        # 아이템 조작 처리가 충돌했습니다. 재시도가 필요합니다.
        pass
    if async_result.error is Gs2InventoryInsufficientException:
        # 아이템 소지 수량이 부족합니다.
        pass
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### getItem

인벤토리 이름과 아이템 이름으로 특정 아이템 조회<br>

지정한 인벤토리에서 플레이어가 소지한 특정 아이템 유형의 모든 스택을 조회합니다.<br>
같은 아이템이라도 여러 스택(아이템 세트)으로 반환될 수 있습니다. 유효기간이 다른 아이템은 반드시 별도의 스택이 됩니다.<br>
예를 들어 "회복 포션"을 요청하면, 곧 만료되는 50개 스택과 나중에 만료되는 30개 스택의 두 가지가 반환될 수 있습니다.<br>
아이템 상세 화면을 표시할 때 사용합니다. 예를 들어 "회복 포션 — 합계: 80개 — 스택 1: 50개(만료 2024-03-01), 스택 2: 30개(만료 2024-03-15)"와 같은 표시에 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 인벤토리 모델명<br>이 아이템 세트를 포함하는 인벤토리 모델의 이름입니다. itemName과 함께 사용되어 이 소지품이 어떤 인벤토리와 아이템 종류에 속하는지를 식별하는 데 사용됩니다. |
| itemName | string |  | ✓|  |  ~ 128자 | 아이템 모델명<br>이 세트에 저장된 아이템의 종류를 정의하는 아이템 모델의 이름입니다. inventoryName과 조합하여 이 아이템 세트의 스택 상한과 다중 스택 동작을 결정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzItemSet&gt;](#ezitemset) | 아이템 세트 리스트|
| itemModel | [EzItemModel](#ezitemmodel) | 아이템 모델|
| inventory | [EzInventory](#ezinventory) | 인벤토리|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "item"
    ).ItemSet(
        itemName: "item-0001",
        itemSetName: "itemSet-0001"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "item"
    ).ItemSet(
        itemName: "item-0001",
        itemSetName: "itemSet-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Inventory(
        "item" // inventoryName
    )->ItemSet(
        "item-0001", // itemName
        "itemSet-0001" // itemSetName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).inventory(
        "item"
    ).item_set(
        "item-0001",
        "itemSet-0001"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "item"
    ).ItemSet(
        itemName: "item-0001",
        itemSetName: "itemSet-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "item"
    ).ItemSet(
        itemName: "item-0001",
        itemSetName: "itemSet-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Inventory(
        "item" // inventoryName
    )->ItemSet(
        "item-0001", // itemName
        "itemSet-0001" // itemSetName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Inventory::Model::FItemSet> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).inventory(
        "item"
    ).item_set(
        "item-0001",
        "itemSet-0001"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getItemWithSignature

소지 증명 서명이 포함된 아이템 조회<br>

아이템 세트와 함께, 플레이어가 API 호출 시점에 이 아이템을 소지하고 있었음을 증명하는 서버 서명을 함께 조회합니다.<br>
외부 서버나 다른 시스템에서 아이템 소지 여부를 검증해야 할 때 유용합니다. 서명은 위변조 방지 증거로 사용됩니다.<br>
예를 들어, 특별한 던전에 입장하기 전에 플레이어가 특정 무기를 실제로 소지하고 있는지 검증하는 데 사용할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 인벤토리 모델명<br>이 아이템 세트를 포함하는 인벤토리 모델의 이름입니다. itemName과 함께 사용되어 이 소지품이 어떤 인벤토리와 아이템 종류에 속하는지를 식별하는 데 사용됩니다. |
| itemName | string |  | ✓|  |  ~ 128자 | 아이템 모델명<br>이 세트에 저장된 아이템의 종류를 정의하는 아이템 모델의 이름입니다. inventoryName과 조합하여 이 아이템 세트의 스택 상한과 다중 스택 동작을 결정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| itemSetName | string |  | |  |  ~ 36자 | 아이템 세트를 식별하는 이름 |
| keyId | string |  | | "grn:gs2:{region}:{ownerId}:key:default:key:default" |  ~ 1024자 | 암호화 키 GRN |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzItemSet&gt;](#ezitemset) | 아이템 세트 리스트|
| itemModel | [EzItemModel](#ezitemmodel) | 아이템 모델|
| inventory | [EzInventory](#ezinventory) | 인벤토리|
| body | string | 서명 대상의 아이템 세트 정보|
| signature | string | 서명|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "inventory-0001"
    ).ItemSet(
        itemName: "item-0001",
        itemSetName: null
    );
    var result = await domain.GetItemWithSignatureAsync(
        keyId: "key-0001"
    );
    var item = await result.ModelAsync();
    var body = result.Body;
    var signature = result.Signature;

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "inventory-0001"
    ).ItemSet(
        itemName: "item-0001",
        itemSetName: null
    );
    var future = domain.GetItemWithSignatureFuture(
        keyId: "key-0001"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;
    var body = future.Result.Body;
    var signature = future.Result.Signature;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Inventory(
        "inventory-0001" // inventoryName
    )->ItemSet(
        "item-0001", // itemName
        nullptr // itemSetName
    );
    const auto Future = Domain->GetItemWithSignature(
        "key-0001" // keyId
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();
    const auto Body = Result->Body;
    const auto Signature = Result->Signature;

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).inventory(
        "inventory-0001"
    ).item_set(
        "item-0001",
        null
    )

var async_result = await domain.get_item_with_signature(
    "key-0001" # key_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### listItems

인벤토리 내 플레이어가 소지한 아이템 목록 조회<br>

지정한 인벤토리에서 플레이어가 현재 소지하고 있는 모든 아이템을 조회합니다.<br>
각 항목은 "아이템 세트"로, 수량과 선택적으로 유효기간을 가지는 아이템 스택입니다. 같은 아이템 유형이라도 유효기간이 다르면 여러 스택으로 표시될 수 있습니다.<br>
예를 들어 "회복 포션"이 "회복 포션 x50(3일 후 만료)"과 "회복 포션 x30(7일 후 만료)"의 두 항목으로 표시될 수 있습니다.<br>
인벤토리의 메인 아이템 목록 화면을 구성할 때 사용합니다. 소지한 모든 아이템과 그 수량을 표시하는 화면입니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 인벤토리 모델 이름<br>인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| pageToken | string |  | |  |  ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |
| limit | int |  | | 30 | 1 ~ 1000 | 취득할 데이터 건수 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzItemSet&gt;](#ezitemset) | 아이템 세트 리스트|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "item"
    );
    var items = await domain.ItemSetsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "item"
    );
    var it = domain.ItemSets(
    );
    List<EzItemSet> items = new List<EzItemSet>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Inventory(
        "item" // inventoryName
    );
    const auto It = Domain->ItemSets(
    );
    TArray<Gs2::UE5::Inventory::Model::FEzItemSetPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeItemSets(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeItemSets(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Inventory(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeItemSets(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeItemSets(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Inventory(
        "item" // inventoryName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeItemSets(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeItemSets(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getSimpleInventoryModel

이름으로 특정 심플 인벤토리 타입 정의 조회<br>

이름을 지정하여 심플 인벤토리 모델을 1건 조회합니다.<br>
조회되는 정보에는 이 인벤토리에 속한 심플 아이템 모델의 목록(저장할 수 있는 아이템과 그 속성 정의)이 포함됩니다.<br>
특정 심플 인벤토리의 내용을 표시할 때 사용합니다. 예를 들어 "화폐"나 "재료" 인벤토리에 포함된 아이템 유형을 확인할 때 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 심플 인벤토리 모델 이름<br>심플 인벤토리 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzSimpleInventoryModel](#ezsimpleinventorymodel) | 심플 인벤토리 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->SimpleInventoryModel(
        "item" // inventoryName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).simple_inventory_model(
        "item"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->SimpleInventoryModel(
        "item" // inventoryName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Inventory::Model::FSimpleInventoryModel> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).simple_inventory_model(
        "item"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### listSimpleInventoryModels

심플 인벤토리 타입 정의 목록 조회<br>

이 네임스페이스에 등록된 모든 심플 인벤토리 모델을 조회합니다.<br>
심플 인벤토리는 표준 인벤토리의 경량화 버전으로, 스택·유효기간·용량 제한 없이 아이템을 이름과 수량의 단순한 쌍으로 관리합니다.<br>
화폐, 제작 재료 등 수량만 관리하면 되는 아이템에 적합합니다. 예를 들어 "골드: 5000", "철광석: 150", "스태미나 포션: 12"와 같은 용도입니다.<br>
게임에서 어떤 종류의 심플 인벤토리를 사용할 수 있는지 확인할 때 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzSimpleInventoryModel&gt;](#ezsimpleinventorymodel) | 심플 인벤토리 모델 목록|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    var items = await domain.SimpleInventoryModelsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    var it = domain.SimpleInventoryModels(
    );
    List<EzSimpleInventoryModel> items = new List<EzSimpleInventoryModel>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto It = Domain->SimpleInventoryModels(
    );
    TArray<Gs2::UE5::Inventory::Model::FEzSimpleInventoryModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeSimpleInventoryModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeSimpleInventoryModels(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeSimpleInventoryModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeSimpleInventoryModels(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeSimpleInventoryModels(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeSimpleInventoryModels(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getSimpleItemModel

이름을 지정하여 심플 아이템 정의를 취득한다<br>

인벤토리 이름과 아이템 이름을 지정하여 심플 아이템 모델을 1건 취득합니다.<br>
특정 심플 아이템 타입의 정의를 표시하는 데 사용합니다. 예를 들어 게임 UI에서 "골드"나 "철광석"의 속성을 표시할 때 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 심플 인벤토리 모델 이름<br>심플 인벤토리 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| itemName | string |  | ✓|  |  ~ 128자 | 심플 아이템 모델 이름<br>심플 아이템 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzSimpleItemModel](#ezsimpleitemmodel) | |

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    ).SimpleItemModel(
        itemName: "item-master-0001"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    ).SimpleItemModel(
        itemName: "item-master-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->SimpleInventoryModel(
        "item" // inventoryName
    )->SimpleItemModel(
        "item-master-0001" // itemName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).simple_inventory_model(
        "item"
    ).simple_item_model(
        "item-master-0001"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    ).SimpleItemModel(
        itemName: "item-master-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    ).SimpleItemModel(
        itemName: "item-master-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->SimpleInventoryModel(
        "item" // inventoryName
    )->SimpleItemModel(
        "item-master-0001" // itemName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Inventory::Model::FSimpleItemModel> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).simple_inventory_model(
        "item"
    ).simple_item_model(
        "item-master-0001"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### listSimpleItemModels

심플 인벤토리 내 아이템 정의 목록을 취득한다<br>

지정한 심플 인벤토리에 속하는 모든 심플 아이템 모델을 취득합니다.<br>
심플 아이템 모델은 수량만으로 관리되는 아이템 타입을 정의합니다. 스택 규칙이나 유효 기간은 없으며, 이름과 숫자뿐입니다.<br>
심플 인벤토리에 어떤 아이템이 존재할 수 있는지 확인하는 데 사용합니다. 예를 들어 "소재" 인벤토리 내의 "골드", "보석", "철광석", "목재"를 목록으로 표시할 때 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 심플 인벤토리 모델 이름<br>심플 인벤토리 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzSimpleItemModel&gt;](#ezsimpleitemmodel) | 심플 아이템 모델 리스트|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    );
    var items = await domain.SimpleItemModelsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    );
    var it = domain.SimpleItemModels(
    );
    List<EzSimpleItemModel> items = new List<EzSimpleItemModel>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->SimpleInventoryModel(
        "item" // inventoryName
    );
    const auto It = Domain->SimpleItemModels(
    );
    TArray<Gs2::UE5::Inventory::Model::FEzSimpleItemModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeSimpleItemModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeSimpleItemModels(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).SimpleInventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeSimpleItemModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeSimpleItemModels(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->SimpleInventoryModel(
        "item" // inventoryName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeSimpleItemModels(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeSimpleItemModels(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### consumeSimpleItems

플레이어의 인벤토리에서 심플 아이템 사용(소비)<br>

플레이어의 인벤토리에 있는 하나 이상의 심플 아이템 수량을 줄입니다. 한 번의 호출로 여러 종류의 아이템을 한꺼번에 소비할 수 있습니다.<br>
게임 고유의 로직으로 플레이어가 리소스를 소비하는 경우에 사용합니다. 예를 들어, 무기를 제작하기 위해 제작 재료를 소비하거나 전투에서 소모품을 사용하는 경우입니다.<br>
주의: 상품 구매(GS2-Showcase)나 퀘스트 시작(GS2-Quest)의 대가로 아이템을 소비하는 경우에는 해당 시스템이 자동으로 처리하므로, 이 API를 호출할 필요가 없습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 심플 인벤토리 모델 이름<br>심플 인벤토리 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| consumeCounts | [List&lt;EzConsumeCount&gt;](#ezconsumecount) |  | ✓|  | 1 ~ 100 items | 심플 아이템의 소비 수량 리스트 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzSimpleItem&gt;](#ezsimpleitem) | 소비 후 심플 아이템 목록|

#### Error

이 API에는 특별한 예외가 정의되어 있습니다.<br>
GS2-SDK for Game Engine에서는 게임 내에서 핸들링이 필요할 것으로 예상되는 에러를, 일반적인 예외에서 파생된 특수화된 예외로 제공하여 다루기 쉽게 하고 있습니다.<br>
일반적인 에러의 종류와 핸들링 방법은 [여기]() 문서를 참고해 주세요.

| 타입 | 베이스 클래스 | 설명 |
| --- | --- | --- |
| ConflictException | ConflictException | 아이템 조작 처리가 충돌했습니다. 재시도가 필요합니다. |
| InsufficientException | BadRequestException | 아이템 소지 수량이 부족합니다. |

#### 구현 예제




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "inventory-0001"
    );
    var result = await domain.ConsumeSimpleItemsAsync(
        consumeCounts: new List<Gs2.Unity.Gs2Inventory.Model.EzConsumeCount> {
            new Gs2.Unity.Gs2Inventory.Model.EzConsumeCount() {
                ItemName = "item-0001",
                Count = 5,
            },
            new Gs2.Unity.Gs2Inventory.Model.EzConsumeCount() {
                ItemName = "item-0002",
                Count = 3,
            },
        }
    );
    var item = await result.ModelAsync();
} catch(Gs2.Gs2Inventory.Exception.ConflictException e) {
    // Item manipulation process conflicted. Retry required.
} catch(Gs2.Gs2Inventory.Exception.InsufficientException e) {
    // Insufficient quantity of items in your possession.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "inventory-0001"
    );
    var future = domain.ConsumeSimpleItemsFuture(
        consumeCounts: new List<Gs2.Unity.Gs2Inventory.Model.EzConsumeCount> {
            new Gs2.Unity.Gs2Inventory.Model.EzConsumeCount() {
                ItemName = "item-0001",
                Count = 5,
            },
            new Gs2.Unity.Gs2Inventory.Model.EzConsumeCount() {
                ItemName = "item-0002",
                Count = 3,
            },
        }
    );
    yield return future;
    if (future.Error != null)
    {
        if (future.Error is Gs2.Gs2Inventory.Exception.ConflictException)
        {
            // Item manipulation process conflicted. Retry required.
        }
        if (future.Error is Gs2.Gs2Inventory.Exception.InsufficientException)
        {
            // Insufficient quantity of items in your possession.
        }
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->SimpleInventory(
        "inventory-0001" // inventoryName
    );
    const auto Future = Domain->ConsumeSimpleItems(
        []
        {
            auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::Inventory::Model::FEzConsumeCount>>>();
            v->Add(
                MakeShared<Gs2::UE5::Inventory::Model::FEzConsumeCount>()
                ->WithItemName(TOptional<FString>("item-0001"))
                ->WithCount(TOptional<int32>(5))
            );
            v->Add(
                MakeShared<Gs2::UE5::Inventory::Model::FEzConsumeCount>()
                ->WithItemName(TOptional<FString>("item-0002"))
                ->WithCount(TOptional<int32>(3))
            );
            return v;
        }() // consumeCounts
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        auto e = Future->GetTask().Error();
        if (e->IsChildOf(Gs2::Inventory::Error::FConflictError::Class))
        {
            // Item manipulation process conflicted. Retry required.
        }
        if (e->IsChildOf(Gs2::Inventory::Error::FInsufficientError::Class))
        {
            // Insufficient quantity of items in your possession.
        }
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).simple_inventory(
        "inventory-0001"
    )

var async_result = await domain.consume_simple_items(
    [
        Gs2InventoryEzConsumeCount.new()
            .with_item_name("item-0001")
            .with_count(5),
        Gs2InventoryEzConsumeCount.new()
            .with_item_name("item-0002")
            .with_count(3),
    ] # consume_counts
)
if async_result.error != null:
    if async_result.error is Gs2InventoryConflictException:
        # 아이템 조작 처리가 충돌했습니다. 재시도가 필요합니다.
        pass
    if async_result.error is Gs2InventoryInsufficientException:
        # 아이템 소지 수량이 부족합니다.
        pass
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### getSimpleItem

특정 심플 아이템의 소지 수량 조회<br>

플레이어가 특정 심플 아이템을 현재 몇 개 소지하고 있는지 조회합니다.<br>
특정 리소스의 수량을 확인할 때 사용합니다. 예를 들어 상점 화면에서 구매 전에 "골드: 5,000"이라고 표시하거나, 제작 화면에서 "철광석: 150/200개 필요"라고 표시하는 데 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 심플 인벤토리 모델 이름<br>심플 인벤토리 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| itemName | string |  | ✓|  |  ~ 128자 | 심플 아이템 모델 이름<br>이 레코드에 저장된 아이템의 종류를 정의하는 심플 아이템 모델의 이름입니다. 이 소지품이 어떤 아이템 정의에 대응하는지 식별하는 데 사용됩니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzSimpleItem](#ezsimpleitem) | 심플 아이템|
| itemModel | [EzSimpleItemModel](#ezsimpleitemmodel) | 심플 아이템 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "item"
    ).SimpleItem(
        itemName: "item-0001"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "item"
    ).SimpleItem(
        itemName: "item-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->SimpleInventory(
        "item" // inventoryName
    )->SimpleItem(
        "item-0001" // itemName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).simple_inventory(
        "item"
    ).simple_item(
        "item-0001"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "item"
    ).SimpleItem(
        itemName: "item-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "item"
    ).SimpleItem(
        itemName: "item-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->SimpleInventory(
        "item" // inventoryName
    )->SimpleItem(
        "item-0001" // itemName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Inventory::Model::FSimpleItem> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).simple_inventory(
        "item"
    ).simple_item(
        "item-0001"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getSimpleItemWithSignature

소지 증명 서명이 포함된 심플 아이템 조회<br>

심플 아이템과 함께, 플레이어가 API 호출 시점에 이 아이템을 소지하고 있었음을 증명하는 서버 서명을 함께 조회합니다.<br>
외부 서버나 다른 시스템에서 아이템 소지 여부를 검증해야 할 때 유용합니다. 서명은 위변조 방지 증거로 사용됩니다.<br>
예를 들어, 외부 마켓플레이스에서 거래를 처리하기 전에 플레이어가 충분한 화폐나 재료를 가지고 있는지 검증하는 데 사용할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 심플 인벤토리 모델 이름<br>심플 인벤토리 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| itemName | string |  | ✓|  |  ~ 128자 | 심플 아이템 모델 이름<br>이 레코드에 저장된 아이템의 종류를 정의하는 심플 아이템 모델의 이름입니다. 이 소지품이 어떤 아이템 정의에 대응하는지 식별하는 데 사용됩니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| keyId | string |  | | "grn:gs2:{region}:{ownerId}:key:default:key:default" |  ~ 1024자 | 암호화 키 GRN |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzSimpleItem](#ezsimpleitem) | 심플 아이템|
| simpleItemModel | [EzSimpleItemModel](#ezsimpleitemmodel) | 심플 아이템 모델|
| body | string | 서명 대상 심플 아이템 정보|
| signature | string | 서명|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "inventory-0001"
    ).SimpleItem(
        itemName: "item-0001"
    );
    var result = await domain.GetSimpleItemWithSignatureAsync(
        keyId: "key-0001"
    );
    var item = await result.ModelAsync();
    var body = result.Body;
    var signature = result.Signature;

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "inventory-0001"
    ).SimpleItem(
        itemName: "item-0001"
    );
    var future = domain.GetSimpleItemWithSignatureFuture(
        keyId: "key-0001"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;
    var body = future.Result.Body;
    var signature = future.Result.Signature;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->SimpleInventory(
        "inventory-0001" // inventoryName
    )->SimpleItem(
        "item-0001" // itemName
    );
    const auto Future = Domain->GetSimpleItemWithSignature(
        "key-0001" // keyId
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();
    const auto Body = Result->Body;
    const auto Signature = Result->Signature;

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).simple_inventory(
        "inventory-0001"
    ).simple_item(
        "item-0001"
    )

var async_result = await domain.get_simple_item_with_signature(
    "key-0001" # key_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### listSimpleItems

인벤토리 내 플레이어가 소지한 심플 아이템 목록 조회<br>

지정한 심플 인벤토리에서 플레이어가 현재 소지하고 있는 모든 심플 아이템을 조회합니다.<br>
각 아이템은 이름과 수량의 단순한 쌍입니다. 예를 들어 "골드: 5000", "철광석: 150"과 같은 형식입니다.<br>
표준 인벤토리 아이템과 달리, 심플 아이템에는 스택·유효기간·슬롯 제한이 없습니다.<br>
리소스나 재료 목록을 표시할 때 사용합니다. 예를 들어 플레이어의 화폐 잔액, 제작 재료, 소모품 수량을 표시하는 화면에 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 심플 인벤토리 모델 이름<br>심플 인벤토리 모델 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| pageToken | string |  | |  |  ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |
| limit | int |  | | 30 | 1 ~ 1000 | 취득할 데이터 건수 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzSimpleItem&gt;](#ezsimpleitem) | 심플 아이템 리스트|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "item"
    );
    var items = await domain.SimpleItemsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "item"
    );
    var it = domain.SimpleItems(
    );
    List<EzSimpleItem> items = new List<EzSimpleItem>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->SimpleInventory(
        "item" // inventoryName
    );
    const auto It = Domain->SimpleItems(
    );
    TArray<Gs2::UE5::Inventory::Model::FEzSimpleItemPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeSimpleItems(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeSimpleItems(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).SimpleInventory(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeSimpleItems(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeSimpleItems(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->SimpleInventory(
        "item" // inventoryName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeSimpleItems(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeSimpleItems(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getBigInventoryModel

이름으로 특정 대형 인벤토리 타입 정의 조회<br>

이름을 지정하여 대형 인벤토리 모델을 1건 조회합니다.<br>
조회되는 정보에는 이 인벤토리에 속한 대형 아이템 모델의 목록이 포함됩니다.<br>
특정 대형 인벤토리 타입의 상세 정보를 표시할 때 사용합니다. 예를 들어 "메가 화폐"나 "누적 포인트" 인벤토리에서 추적되는 아이템을 확인할 때 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 거대 인벤토리 모델 이름<br>거대 인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzBigInventoryModel](#ezbiginventorymodel) | 거대 인벤토리 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->BigInventoryModel(
        "item" // inventoryName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).big_inventory_model(
        "item"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->BigInventoryModel(
        "item" // inventoryName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Inventory::Model::FBigInventoryModel> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).big_inventory_model(
        "item"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### listBigInventoryModels

대형 인벤토리 타입 정의 목록 조회<br>

이 네임스페이스에 등록된 모든 대형 인벤토리 모델을 조회합니다.<br>
대형 인벤토리는 일반적인 정수로는 다룰 수 없을 만큼 매우 큰 수량(예: 수십억, 수조)을 가지는 아이템을 위해 설계되었습니다.<br>
방치형/인크리멘탈 게임의 재화, 누적 포인트, 매우 큰 수치로 늘어나는 리소스에 유용합니다.<br>
게임에서 어떤 종류의 대형 인벤토리를 사용할 수 있는지 확인할 때 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzBigInventoryModel&gt;](#ezbiginventorymodel) | 거대 인벤토리 모델 목록|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    var items = await domain.BigInventoryModelsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    var it = domain.BigInventoryModels(
    );
    List<EzBigInventoryModel> items = new List<EzBigInventoryModel>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto It = Domain->BigInventoryModels(
    );
    TArray<Gs2::UE5::Inventory::Model::FEzBigInventoryModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeBigInventoryModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeBigInventoryModels(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeBigInventoryModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeBigInventoryModels(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeBigInventoryModels(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeBigInventoryModels(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getBigItemModel

이름으로 특정 대형 아이템 정의 조회<br>

인벤토리 이름과 아이템 이름을 지정하여 대형 아이템 모델을 1건 조회합니다.<br>
특정 대형 아이템 유형의 정의를 표시할 때 사용합니다. 예를 들어 게임 UI에서 "메가 골드"나 "누적 XP"의 속성을 표시할 때 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 거대 인벤토리 모델 이름<br>거대 인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| itemName | string |  | ✓|  |  ~ 128자 | 거대 아이템 모델 이름<br>거대 아이템 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzBigItemModel](#ezbigitemmodel) | |

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    ).BigItemModel(
        itemName: "item-master-0001"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    ).BigItemModel(
        itemName: "item-master-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->BigInventoryModel(
        "item" // inventoryName
    )->BigItemModel(
        "item-master-0001" // itemName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).big_inventory_model(
        "item"
    ).big_item_model(
        "item-master-0001"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    ).BigItemModel(
        itemName: "item-master-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    ).BigItemModel(
        itemName: "item-master-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->BigInventoryModel(
        "item" // inventoryName
    )->BigItemModel(
        "item-master-0001" // itemName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Inventory::Model::FBigItemModel> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).big_inventory_model(
        "item"
    ).big_item_model(
        "item-master-0001"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### listBigItemModels

인벤토리 내 대형 아이템 정의 목록 조회<br>

지정한 대형 인벤토리에 속한 모든 대형 아이템 모델을 조회합니다.<br>
대형 아이템 모델은 임의 정밀도의 수치(정수가 아닌 문자열로 저장)를 사용하여 매우 큰 수량을 가질 수 있는 아이템 유형을 정의합니다.<br>
대형 인벤토리에 어떤 아이템이 존재할 수 있는지 확인할 때 사용합니다. 예를 들어 "메가 골드", "누적 XP", "총 가한 데미지량" 등의 목록 표시에 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 거대 인벤토리 모델 이름<br>거대 인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzBigItemModel&gt;](#ezbigitemmodel) | 거대 아이템 모델 리스트|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    );
    var items = await domain.BigItemModelsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    );
    var it = domain.BigItemModels(
    );
    List<EzBigItemModel> items = new List<EzBigItemModel>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->BigInventoryModel(
        "item" // inventoryName
    );
    const auto It = Domain->BigItemModels(
    );
    TArray<Gs2::UE5::Inventory::Model::FEzBigItemModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeBigItemModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeBigItemModels(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).BigInventoryModel(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeBigItemModels(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeBigItemModels(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->BigInventoryModel(
        "item" // inventoryName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeBigItemModels(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeBigItemModels(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### consumeBigItem

플레이어의 인벤토리에서 대형 아이템 사용(소비)<br>

플레이어의 인벤토리에 있는 특정 대형 아이템의 수량을 줄입니다. 매우 큰 값을 지원하기 위해 소비 수량은 문자열로 지정합니다.<br>
게임 고유의 로직으로 플레이어가 대형 수치 리소스를 소비하는 경우에 사용합니다. 예를 들어, 프레스티지 업그레이드에 "메가 골드 1,000,000,000"을 사용하는 경우나 누적 포인트를 소비하는 경우입니다.<br>
주의: 상품 구매(GS2-Showcase)나 퀘스트 시작(GS2-Quest)의 대가로 아이템을 소비하는 경우에는 해당 시스템이 자동으로 처리하므로, 이 API를 호출할 필요가 없습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 거대 인벤토리 모델 이름<br>거대 인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| itemName | string |  | ✓|  |  ~ 128자 | 거대 아이템 모델 이름<br>거대 아이템 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| consumeCount | string |  | ✓|  |  ~ 1024자 | 거대 아이템의 소비 수량<br>최대 1024자리까지의 정수값 문자열 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzBigItem](#ezbigitem) | 소비 후 거대 아이템|

#### Error

이 API에는 특별한 예외가 정의되어 있습니다.<br>
GS2-SDK for Game Engine에서는 게임 내에서 핸들링이 필요할 것으로 예상되는 에러를, 일반적인 예외에서 파생된 특수화된 예외로 제공하여 다루기 쉽게 하고 있습니다.<br>
일반적인 에러의 종류와 핸들링 방법은 [여기]() 문서를 참고해 주세요.

| 타입 | 베이스 클래스 | 설명 |
| --- | --- | --- |
| ConflictException | ConflictException | 아이템 조작 처리가 충돌했습니다. 재시도가 필요합니다. |
| InsufficientException | BadRequestException | 아이템 소지 수량이 부족합니다. |

#### 구현 예제




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BigInventory(
        inventoryName: "inventory-0001"
    ).BigItem(
        itemName: "item-0001"
    );
    var result = await domain.ConsumeBigItemAsync(
        consumeCount: "1234567890123456789012345678901234567890"
    );
    var item = await result.ModelAsync();
} catch(Gs2.Gs2Inventory.Exception.ConflictException e) {
    // Item manipulation process conflicted. Retry required.
} catch(Gs2.Gs2Inventory.Exception.InsufficientException e) {
    // Insufficient quantity of items in your possession.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BigInventory(
        inventoryName: "inventory-0001"
    ).BigItem(
        itemName: "item-0001"
    );
    var future = domain.ConsumeBigItemFuture(
        consumeCount: "1234567890123456789012345678901234567890"
    );
    yield return future;
    if (future.Error != null)
    {
        if (future.Error is Gs2.Gs2Inventory.Exception.ConflictException)
        {
            // Item manipulation process conflicted. Retry required.
        }
        if (future.Error is Gs2.Gs2Inventory.Exception.InsufficientException)
        {
            // Insufficient quantity of items in your possession.
        }
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->BigInventory(
        "inventory-0001" // inventoryName
    )->BigItem(
        "item-0001" // itemName
    );
    const auto Future = Domain->ConsumeBigItem(
        "1234567890123456789012345678901234567890" // consumeCount
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        auto e = Future->GetTask().Error();
        if (e->IsChildOf(Gs2::Inventory::Error::FConflictError::Class))
        {
            // Item manipulation process conflicted. Retry required.
        }
        if (e->IsChildOf(Gs2::Inventory::Error::FInsufficientError::Class))
        {
            // Insufficient quantity of items in your possession.
        }
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).big_inventory(
        "inventory-0001"
    ).big_item(
        "item-0001"
    )

var async_result = await domain.consume_big_item(
    "1234567890123456789012345678901234567890" # consume_count
)
if async_result.error != null:
    if async_result.error is Gs2InventoryConflictException:
        # 아이템 조작 처리가 충돌했습니다. 재시도가 필요합니다.
        pass
    if async_result.error is Gs2InventoryInsufficientException:
        # 아이템 소지 수량이 부족합니다.
        pass
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### getBigItem

특정 대형 아이템의 소지 수량 조회<br>

플레이어가 소지한 특정 대형 아이템의 현재 수량을 조회합니다. 매우 큰 값을 지원하기 위해 수량은 문자열로 반환됩니다.<br>
특정 대형 수치 리소스를 확인할 때 사용합니다. 예를 들어 게임의 메인 화면에서 "메가 골드: 1,234,567,890"이라고 표시하거나, 플레이어 프로필에서 "누적 XP: 9,876,543,210"이라고 표시하는 데 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 거대 인벤토리 모델 이름<br>거대 인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| itemName | string |  | ✓|  |  ~ 128자 | 거대 아이템 모델 이름<br>이 레코드에 저장된 아이템의 종류를 정의하는 거대 아이템 모델의 이름입니다. 이 거대 아이템 소지품이 어떤 아이템 정의에 대응하는지 식별하는 데 사용됩니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzBigItem](#ezbigitem) | 거대 아이템|
| itemModel | [EzBigItemModel](#ezbigitemmodel) | 거대 아이템 모델|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BigInventory(
        inventoryName: "item"
    ).BigItem(
        itemName: "item-0001"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BigInventory(
        inventoryName: "item"
    ).BigItem(
        itemName: "item-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->BigInventory(
        "item" // inventoryName
    )->BigItem(
        "item-0001" // itemName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).big_inventory(
        "item"
    ).big_item(
        "item-0001"
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BigInventory(
        inventoryName: "item"
    ).BigItem(
        itemName: "item-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BigInventory(
        inventoryName: "item"
    ).BigItem(
        itemName: "item-0001"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->BigInventory(
        "item" // inventoryName
    )->BigItem(
        "item-0001" // itemName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Inventory::Model::FBigItem> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.inventory.namespace_(
        "namespace-0001"
    ).me(game_session).big_inventory(
        "item"
    ).big_item(
        "item-0001"
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### listBigItems

인벤토리 내 플레이어가 소지한 대형 아이템 목록 조회<br>

지정한 대형 인벤토리에서 플레이어가 현재 소지하고 있는 모든 대형 아이템을 조회합니다.<br>
각 아이템의 수량은 매우 큰 수치를 지원하기 위해 문자열로 저장됩니다(예: "1234567890123456789").<br>
한 번도 획득한 적이 없는 아이템은 결과에 포함되지 않습니다.<br>
플레이어의 대형 수치 리소스를 표시할 때 사용합니다. 예를 들어 "메가 골드: 1,234,567,890", "총 데미지: 9,876,543,210,000"과 같은 표시에 유용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| inventoryName | string |  | ✓|  |  ~ 128자 | 거대 인벤토리 모델 이름<br>거대 인벤토리 모델 고유 이름입니다. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| pageToken | string |  | |  |  ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |
| limit | int |  | | 30 | 1 ~ 1000 | 취득할 데이터 건수 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzBigItem&gt;](#ezbigitem) | 거대 아이템 목록|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BigInventory(
        inventoryName: "item"
    );
    var items = await domain.BigItemsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BigInventory(
        inventoryName: "item"
    );
    var it = domain.BigItems(
    );
    List<EzBigItem> items = new List<EzBigItem>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->BigInventory(
        "item" // inventoryName
    );
    const auto It = Domain->BigItems(
    );
    TArray<Gs2::UE5::Inventory::Model::FEzBigItemPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BigInventory(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeBigItems(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeBigItems(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Inventory.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).BigInventory(
        inventoryName: "item"
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeBigItems(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeBigItems(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Inventory->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->BigInventory(
        "item" // inventoryName
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeBigItems(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeBigItems(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---



