I don’t use ECS anymore, so I can’t comment on that part. But when I ripped ECS out of my game a couple weeks ago, I pulled out BlobAssets in one of my subpackages because they’re extremely useful for regular jobs (launched from MonoBehaviours with no entities involved). What a blob represents is a variable-sized piece of structured data. Within it, you can have arrays of different types/lengths or arrays of arrays. So instead of managing 20 different NativeArray<>s, you have a single blob.
For example, I currently have the following structure which is all stored in one blob (kinda playing loose with C# syntax to help give you an idea, also not exactly how it’s laid out, but close):
struct Building {
public float wallHeight;
public float partialWallHeight;
public MapWalls wallsX;
public MapWalls wallsZ;
public MapTiles tiles;
public PropSet props;
public MaterialSet materials;
public LightmapUVLayout lightmap;
public BlobArray<byte> roomIds; }
struct MapWalls {
public int sizeX, sizeY, sizeZ;
public BlobArray<int> elements; }
struct MapTiles {
public int sizeX, sizeY, sizeZ, xTimesZ;
public BlobArray<ushort> data; }
struct PropSet {
public int propCount;
public BlobArray<int> propIdToHoleId;
public BlobArray<Hole> holes; }
struct Hole {
public bool showWallBottom;
public BlobArray<float2> verticesFace;
public BlobArray<ushort> indicesFace;
public BlobArray<float2> verticesInside;
public BlobArray<ushort> indicesInside; }
struct MaterialSet {
public int count;
public BlobArray<float2> tileUv; }
struct LightmapUVLayout {
public BlobArray<Chart> charts;
public ChartIndexer chartIndexer; }
struct ChartIndexer {
public BlobArray<short> tileChartIndices;
public BlobArray<short> wallChartIndices;
public int sizeX_X, sizeX_Z, sizeY, sizeZ_X, sizeZ_Z, zStart; }
If that were NativeArrays, I might need something like…
NativeArray<int> wallsX_elements;
NativeArray<int> wallsZ_elements;
NativeArray<ushort> tiles_data;
NativeArray<int> props_propIdToHoleId;
NativeArray<float2> materials_tileUv;
NativeArray<Chart> lightmap_charts;
NativeArray<short> lightmap_chartIndexer_tileChartIndices;
NativeArray<short> lightmap_chartIndexer_wallChartIndices;
NativeArray<byte> roomIds;
// NativeArray<> doesn't support arrays-of-arrays, so none of these would work as-is
// can hack around it by storing offsets and stuff, but if the structure were more complex
// that would be more complex also
NativeArray<bool> props_holes_showWallBottom;
NativeArray<NativeArray<float2>> props_holes_verticesFace;
NativeArray<NativeArray<ushort>> props_holes_indicesFace;
NativeArray<NativeArray<float2>> props_holes_verticesInside;
NativeArray<NativeArray<ushort>> props_holes_indicesInside;
Don’t feel like allocating and disposing those individually, and that wouldn’t be performant either. So having a persistent cached blob with all the data bound together in a logical structure is very helpful.
Another thing you can use Blobs for if you’re feeling brave is for psuedo-virtual types. Unity.Physics uses it this way – a box collider, a sphere collider, a mesh collider, or a whole hierarchy of compound colliders – all of them are just a BlobAssetReference<Collider>.
A final piece of blobs is that they’re easy to serialize/deserialize, since they’re literally just a blob of bytes. I think ECS uses that internally for conversion systems. So if you’re saving things to disk or sending it over the network, blobs have a place there.