概述
通用库存系统(GIS)提供了一个灵活的机制——数据混入系统,允许为任意对象(如 UObject)附加动态运行时数据(通过 FInstancedStruct),并支持序列化(有限制)和网络复制。这种设计非常适合在不修改原始对象的情况下,为目标对象扩展动态数据。
仅供C++用户
本文仅针对希望利用该系统开发其它游戏系统的C++用户,蓝图用户不需要阅读此文章。
使用场景
数据混入系统适用于需要动态管理对象状态的场景。例如,在一个游戏任务(Quest)系统中,使用不同的 DataAsset 定义每个任务(Task,如目标、描述、奖励等静态数据)。通过接入数据混入系统,每个任务类型可使用任意数据结构管理其内部状态。
示例
假设有一个任务要求“杀死5个强盗和3匹狼”,可以定义一个结构体 TaskState_KillEnemy(包含 BanditKilled 和 WolfKilled 字段)来跟踪任务状态。
数据混入容器
GIS 通过 GIS_MixinContainer 提供数据混入功能,内部维护 Object->InstancedStruct 键值对数组,由 FastArraySerializer 实现,支持高效的网络复制和简化的数据变化通知回调。
使用数据混入容器的步骤
以道具实例(ItemInstance)为例:
1.在类中添加 GIS_MixinContainer 字段。
2.在构造函数中设置容器的 OwningObject 为当前对象(对于 ActorComponent,在 InitializeComponent 中设置)。
3.确保该字段支持网络同步,同步条件可根据项目需求自定义。
4.使类实现 IGIS_MixinOwnerInterface 接口,并通过接口函数响应数据变化。
5.目标对象(如 Item_Fragment)需实现 IGIS_MixinTargetInterface 接口,以定义运行时数据类型、默认值及序列化需求。
API
GIS_MixinContainer 提供添加、移除、保存和加载等 API,具体用法请参考项目源码。
使用限制
数据混入容器支持为任意对象附加运行时状态,但若需支持存档,请注意:
- 目标对象(TargetObject)必须是从 Package 加载的资产(如 DataAsset)。
- 自定义结构体需支持 SaveGame 属性,且字段类型必须为虚幻引擎支持的可序列化类型。
示例
参考下图,注意查看字段的工具提示(Tooltip)。
验证与恢复
先用 Fragment 配置静态数据,再让兼容的状态结构承载可变数据;只有符合保存条件的状态才应期望恢复。分别检查服务器修改、客户端复制通知和存档往返,并在自定义 Factory 或状态结构变更时验证旧记录兼容性。