库存系统

介绍
本文介绍库存系统组件以及道具集合的用法,帮助设计师更好地设计你的库存系统布局。
库存的本质是:一个组件,拥有不同的道具集合,以不同的形式存放道具栈。

库存系统组件
库存系统组件是GIS中最核心的组件之一,GIS中的很多其他特性都以此系统为基础构建。一个Actor只需要挂载一个库存系统组件,并根据你的游戏设计,搭配合适的道具集合类型,即可完成各种类型的库存设计。

- CollectionDefinitions:指定了该库存可以具备哪些类型的道具集合,每一个集合用一个GameplayTag进行唯一标识。同时Tag还可用于表达集合的用途,你可以在库存系统组件上配置多个相同类型的道具集合,并用不同的Tag进行区分。
- Collection:即库存系统初始化后,会生成的道具集合实例,在游戏运行时你可以观察到集合中道具的细节。
- DefaultLoadouts:可针对不同集合,添加默认数量的道具及其数量,会在库存系统初始化时添加到集合实例中。
- IgnoredCollection:你可以将某些集合从道具获取API中忽略,适合放置隐藏道具。
参考用例
因此,你可以将该组件添加到任意Actor,根据不同的配置,它可以产生多种用例:
- 角色库存:存储玩家的所有道具。
- 敌人库存:存储敌人的所有道具,或者可能掉落的道具,或者是敌人当前的装备。
- 商店库存:存储商店的所有道具。
- 宝箱库存:可以根据游戏规则随机往宝箱添加道具,供玩家搜刮。
- 仓库库存:可以作为玩家的道具寄存,又或者是营地管理类游戏中的资源存储池子。
游戏中常见的通过商店系统买道具、从地上拾取道具、或者杀死一个敌人获取了遗物,这些游戏机制本质上可以理解为两个不同库存组件之间的道具数据之间的交互。
如果你有任何需要管理一组数据的需求,都可以使用库存系统组件。
道具集合
集合是道具的分组,集合中的道具存储在集合内部的ItemStacks列表中(由FastArraySerializer实现),其中,每一个道具栈(ItemStack)是一个具有道具实例和数量的结构体。默认情况下,唯一道具的数量始终为1,非唯一道具可以数量始终≥1。
集合定义
每一个集合定义是数据资产,可以指定集合的默认参数。在库存系统初始化时,会分别集合定义对应的集合对应实例。
GIS提供三种类型的集合定义,每一种集合,其内部组织和管理道具的方式略有不同。
集合定义 | 集合实例 |
ItemCollectionDefinition | ItemCollection |
MultiStackItemCollectionDefinition | MultiStackItemCollection |
SlotItemCollectionDefinition | SlotItemCollection |
要了解不同类型的道具集合其特性和细节,请访问对应的道具集合文档。
自定义道具集合
GIS默认提供的三种集合类型已经满足大部分需求了,
但出于某种特殊需求,或者你对默认实现并不太满意,你仍然可以完全创建全新的道具集合。
其步骤如下:
- 创建新的GIS_ItemCollectionDefinition子类,并添加新集合类型所需的所有静态配置。
- 创建新的GIS_ItemCollection子类,并覆盖/拓展原始逻辑。
- 覆写新的ItemCollectionDefinition中的
GetCollectionInstanceClass
,并返回新创建的ItemCollection类型。
这样,在库存系统组件上,新的集合类型会出现在配置选项中。
集合限制
在每一个集合定义中,你可以针对复杂用例,为集合添加不同的限制来为该道具集合添加更细致的规则。集合会在针对道具操作前执行这些限制以决定道具是否可以加入集合/从集合中移除。
下图则是一个针对常规道具集合的限制案例,它规定该集合的每个道具栈最多存放99个道具数量;还规定只有具备特定ItemTags的道具才能被加入该集合。

内置限制
- ItemRestriction_TagRequirements:满足特定Tags的道具才能被加入指定集合。
- ItemRestriction_StacksNumLimit:用于限制指定道具集合的容量(能有多少个道具栈)。
- ItemRestirction_StackSizeLimit:用于限制道具在指定集合中的最大数量(比如最多只能包含多少个苹果?)。
- ItemRestriction_UniqueOnly:用于限制指定集合只能存放唯一道具。
自定义限制
限制集中的每一个条目是一个自定义蓝图,你可以通过蓝图/C++继承自GIS_ItemRestriction
以实现新的限制规则。

设计你的库存布局
作为一个设计师,首先你需要想清楚你的游戏中,需要哪些道具集合作为游戏中道具的容器。
游戏中常见的、玩家背包整理、装备武器等行为,其本质上只是一个库存组件中、不同集合之间的道具数据之间的交互。
下面是一个常见的案例:
CollectionTag | 用途 |
---|---|
Main | 常用作默认的库存集合,存放Actor的所有道具,配套项目中的“InventoryMenu”通常会展示该集合中的数据。 |
Equipped | 在此集合中的道具都是“已经装备”的,通常与ItemSlotCollection配合。配套项目中的“EquipmentMenu”通常会展示该集合中的数据。 |
Hidden | 一些不被玩家可见的道具可以存放在此集合中。 |
库存系统API
所有的API都有良好的分类以方便查询,每一个API也有详细的注释。它们的本质功能是对道具进行增删改查。
这些API本质上是针对道具集合的API的封装,不同类型的集合在底层的内部逻辑会有所不同,但它们的API是非常相似的,库存系统组件暴露出来的API即可满足大部分需求,更具体的集合API会在单独的道具集合文档中有说明。

关于道具信息
你可能注意到了,尽管集合内部是以ItemStack的形式存储每一个道具栈,但是增删改查的API都是通过ItemInfo进行操作。
这是因为ItemInfo不仅具有对道具实例和数量的信息,还具有对ItemStackId和ItemCollection的引用。这允许你在添加道具前,指定道具的来源。
以MultiStackItemCollection举例,若你从ActorA的库存添加100个苹果到ActorB的库存,但由于ActorB的库存限制(最多只能容纳99个苹果),那么你还可以通过ItemInfo中的ItemCollection将多出的1个苹果返回到ActorA的库存。
同样的,通过StackId,你也可以从指定的道具栈上添加道具。