Search Unity

Entity inside Blobs

Discussion in 'Entity Component System' started by rsodre, Oct 26, 2019.

  1. rsodre

    rsodre

    Joined:
    May 9, 2012
    Posts:
    229
    I'm organizing my project, creating blobs to hold my immutable data based on the BlobData example from Unite 2019 - Converting Scene Data to DOTS, but there's one error bugging me for a couple of days. Finally, I found the cause, by replicating what I'm doing in the original example.

    What I do differently is to create multiple prefabs (using
    CreatePrimatuEntity()
    and
    CreateAdditionalEntity()
    of course), and storing them in the Blob data array. But when I use that blob in a system, the prefab is never instantiated correctly, it always instantiate some other random entity.

    As an example, I log the Prefab I get from
    GetPrimaryEntity(network.Prefab)
    during conversion, and it's
    Entity(6:1)
    . In GraphSystem, the
    graph.Prefab
    I use to instantiate is actuallly
    Entity(8:1)
    , and that's expected because the original SubScene Entity Id was reindexed when the game loads it, and it instantiates ok. But If I get the prefab stored on the blob array, it's still
    Entity(6:1)
    , which is some random entity. It was not translated to the game World. I have no idea where this translation happens, but it's not happenign for prefabs stored in the Blob.

    Is that a limitation, a bug, or still to be implemented in a future release?

    This is my atered data from the example:

    Code (CSharp):
    1. struct Node
    2. {
    3.     public BlobArray<int> Links;
    4.     public float3 Position;
    5.     public Entity Prefab;  // <<<< THIS PREFAB DOES NOT TRANSLATE TO THE GAME WORLD
    6. }
    7. struct NodeGraph
    8. {
    9.     public BlobArray<Node> Nodes;
    10. }
    11. struct NodeGraphSpawner : IComponentData
    12. {
    13.     public BlobAssetReference<NodeGraph> Graph;
    14.     public float NextSpawnInSeconds;
    15.     public Entity Prefab;  // <<<< This prefab instantiates Ok!
    16. }
     
  2. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    I think this is about right. What you did is you just remember a pair of integer in a blob. There is no other data than these 2 integers. The preferred way seems to be to keep converting from authoring game object inside a subscene. Why do you need to pre-create a blob for it instead of keeping the whole chain as GameObject prefab inside a subscene? (Subscene works the same way as blob IIRC, as the entire content will be serialized efficiently and also spawned as properly converted/linked entity. At runtime then you just place chunks in memory.)

    How instantiation works is that it (the EntityManager) take these integer (Entity) to find the data related to this entity inside its entity component store (at this current state, and therefore you do it when the world is different because entity index always moves around, it no longer point to the same thing), duplicate the data, then find some chunk still with free space and put those in. This works for a single entity.

    The impression of "Prefab Entity" instantiating a whole bunch of other connected entity is actually that a buffer component named LinkedEntityGroup exists on that main Entity you give it to instantiate. Makes it go through that list and do the same and make sure the resulting instantiation also contains the same LinkedEntityGroup populated with newly instantiated members. CreatePrimaryEntity you called prepares this buffer.

    One more related component is called Prefab, which I think just make it not able to be queried. (Kind of hidden it to be exclusively a blueprint, function the same way as Disabled component but with different purpose)
     
  3. rsodre

    rsodre

    Joined:
    May 9, 2012
    Posts:
    229
    Btw, if it was not clear, my conversion is already on a SubScene. I'm converting a Scriptable Object that contains an array with more Scriptable Objects, each one is converted to a different Entity and stored on the blob array. During the game I can instantiate them.

    I think that in the same way the indices of Entities stored on components are updated when a SubScene is loaded (no idea if it's in in deserialization or when we need it), the same could be done for Entities inside blob data. I know it's immutable, but it is fair to update them, or else in a SubScene context they becomes useless. I spent two days banging my head over this, at least it could generate some kind of warning.

    I switched it easily to a Buffer.
     
    JonasMumm likes this.
  4. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    An Entity can't be stored in a Blob asset. That is not if you want to be able to serialize it. So generally speaking i would simply not do that and find an alternative, because it will likely come back to haunt you.

    Blob assets are immutable compared to their representation on disk. Entity ids get remapped on deserialize to make everything match up correctly.
     
    JonasMumm and MNNoxMortem like this.
  5. felipin

    felipin

    Joined:
    Nov 18, 2015
    Posts:
    49
    Joachim, I'm using Blobs to store animation data (frame rate, frame count, avatar, wrap mode, etc.) and the position, scale and rotation buffers are sent to the GPU (ComputeBuffer) and I need to know where these data are stored (index), should I store the index in the Blob or this is not the purpose of Blobs? because it couldn't be serialized.
     
  6. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Storing indices in a blob makes sense. Just keep it in mind that the data needs to be immutable.
    Sometimes you might have indices in a blob and a DynamicBuffer on the entity that references the blob, giving you a lookup table into referenced Entity's
     
    felipin likes this.