Blob 与数据约定
HYC 的数据核心是 Blob:配置、本地化、行为树全部在生成 / 编辑期烘焙成不可变的 BlobAssetReference,运行期零分配查询。本篇汇总「怎么写才不会烘焙失败、怎么读才对」。
相关命名空间:数据模型 HYC.Framework.Data、跨端加载 HYC.Framework.IO.StreamingAssets、[LocKey] 属 HYC.Framework.Config。
blittable 铁律
✕
托管对象(类 /
Vector2/3/4 不能进 Blob(非 blittable)——用 Unity.Mathematics 的 float2/float3。string 必须换成 BlobString / FixedString——ConfigValidator 放行是假象,烘焙才报错。托管对象(类 /
string)不能进 Blob,否则烘焙失败。配置行类型 TRow 必须是 blittable 结构体(unmanaged)。
自建 Blob 表(低层参考)
public unsafe struct ConfigBlobTable<TRow> : IDisposable where TRow : unmanaged
{
BlobAssetReference<BlobRoot<TRow>> _ref;
NativeHashMap<long, int> _index; // id → 行号
NativeHashMap<long, int> _secondary; // 备用索引(未用)
}
public struct BlobRoot<TRow> where TRow : unmanaged { public BlobArray<TRow> Rows; }
bool ok = table.TryGet(id, out TRow row); // ID 0 不算索引(tryAdd 时 key != 0 才加)
TRow r = table.Get(id); // 找不到返回 default
int n = table.Count;
table.Dispose(); // 释放 _ref + 两个 NativeHashMap
取行必须 ref(EA0001)
行结构含 BlobString / BlobArray,其偏移是自相对的(相对字段自身地址,不是 blob 基址)。把行值拷贝到栈上后,拷贝里的偏移量相对栈地址解析即寻址错位:开发构包直接抛 InvalidOperationException,正式包静默读出垃圾数据。
ref var row = ref ConfigManager.FashionRow.GetByID(1001); // ✅
var row = ConfigManager.FashionRow.GetByID(1001); // ❌ EA0001 编译错
BakerGlue(authoring 样板削减)
BakerGlue.AddItems<MyBuffer>(baker, entity, items); // 批量 AddBuffer + 逐个 Add
BakerGlue.AddIfPresent<MyComp>(baker, entity, value, present); // present 才 AddComponent + SetComponent
跨端数据加载契约
⚠
WebGL 没有文件系统、Android 的 StreamingAssets 在 APK 压缩包内(
· 读字节 / 文本:
· 判存在:
· 平台判据是
· 时序:读取发生在建 World 时(
jar:file://),不能用 System.IO.File 直接读。· 读字节 / 文本:
StreamingAssets.ReadBytes(相对路径) / ReadText(相对路径)· 判存在:
StreamingAssets.Exists(相对路径);列目录:StreamingAssets.GetKeysUnder(相对目录)· 平台判据是
StreamingAssets.NeedsPreload(= IsWebGL || IsAndroid),不是 IsWebGL· 时序:读取发生在建 World 时(
System.OnCreate),所以引导必须 await FrameworkBootstrap.InitializeAsync(...)
其它坑
- 本地化版本号
3写死两处,改一边必须改另一边。 - CJK 文本不能走内置
BlobString分配(Unity 2022.3 已按 UTF-8 真实字节数分配,不再截断);用极老版本时才需要LocalizedExcelReader.AllocateString那套自定义写法。 ConfigBlobTable.FromBlob的idSelector返回 0 会被跳过——确保 ID 从非 0 起。- 配置 Blob 落点只有一个真值:
ConfigDataSettings.BlobOutputDir,运行期读取路径由它派生,别去单独配「加载路径」。 NewItemFlagSystem.OnUpdate目前是空的——「B9 之前清标」的设计意图没落地,红点标记不会被这个系统自动清,要宿主或 UI 自己处理。_secondary永远是空NativeHashMap(0),框架没用它——目前没法做二级索引查询。