#Baking Issue ?

1 messages · Page 1 of 1 (latest)

alpine wing
#

I have an issue I want to understand. Here is some code :

#
    // This being on a GameObject in a subscene
    public class ItemsDbAuthoring : MonoBehaviour
    {
        public class ItemsDbAuthoringBaker : Baker<ItemsDbAuthoring>
        {
            public string GameSettingPath = "Settings/";
            
            public override void Bake(ItemsDbAuthoring authoring)
            {
                // going throught SO to get the prefab               
                foreach (ScriptableObject scriptableObject in Resources.LoadAll<ScriptableObject>(GameSettingPath))
                {
                    Type type = scriptableObject.GetType();
                    if (type != typeof(ItemsSettings)) continue;
                    
                    Entity entity = GetEntity(((ItemsSettings)scriptableObject).Prefab, TransformUsageFlags.Dynamic);
                    Debug.Log(entity);// This will show something like entity:132
                    //Please assume that ItemDBService -> return the instance of it, here it's for the example
                    ItemDBService.Add((ItemsSettings)scriptableObject.GetHashCode(), entity);
                }
            }
        }
    }
#
    // this is a class storing some references, it's needed here because I don't want the designer to create a Tag Component for each single item that is gonna be used.
    public class ItemDBService{
        public Dictionnary<int, Entity> ItemDB = new();

        // do stuff
        public void Initialize();

        //the ID is unique and basically the hascode of the SO 
        public void add(int ID, Entity entity){
            ItemDB.Add(ID, entity);
        }
    }  

    public struct ItemDBSystem : ISystem{
         public void OnUpdate(ref SystemState state)
        {
            //Please assume that ItemDBService -> return the instance of it, here it's for the example          
            foreach (var item in ItemDBService.ItemDB)
            {
               Debug.Log(item.Value); // This will show something like entity:241

               SystemAPI.GetComponentData<SomeComponent>(item.Value); // This will say the entity don't exist anymore
            }

            state.Enabled = false;
        } 
    } 
#

SO here are the issues : Bog Debug.log don't show the same entity ID.
It seems that when baking & adding the reference to the dictionnary everything work as intended

When the system is executing, the Entity in the dictionnary have been replaced by an another one

Confirmed in the hierachy

#

Do someone know what is happening here ?

woven thorn
#

entity id is not supposed to match in baking and in runtime

#

it's similiar to InstanceId of UnityEngine.Object

alpine wing
#

Any ID usable for both cases ?

#

& Any documentation to explain why somewhere they don't match ? Or is it something you are supposed to know ?

woven thorn
#

entity id is only persistent within World instance

alpine wing
#

and because baking use a specific world before sending it the the main world ... this is why , right ?

#

So what about this :

woven thorn
woven thorn
#

don't mind it

alpine wing
#

I Used 2 steps process to store a reference between the world so i'm fine but I wanted to make sure it was the only alternative :/

#

thanks

woven thorn
#

ItemDBService.Add((ItemsSettings)scriptableObject.GetHashCode(), entity);
Btw

#

I have a feeling, that this may not work

#

baking is editor only

alpine wing
#

Welp so far it's working in my project 😄

#

But I do have one more step to make it work in the game world

real yew
#

Have you tested in a build though?

alpine wing
#

Good point

#

I'll try this evening

#

Is there a real difference between the behaviour of baking in a build compared to a editor play ?

#

I would assume that the behaviour is supposed to be the same , on the same plateform

woven thorn
#

at all.

alpine wing
#

Like the bake method is never triggered ?

woven thorn
#

yeah

#

even more

#

authoring scene never makes it into build either

#

only resulting entities do

alpine wing
#

Ah shit

#

So what would be the alternative ?
The idea would be to have a list of the entity instanciable of the items somewhere

#

That's why We tried it this way.

woven thorn
#

bake dynamic buffer of pairs

#

in runtime make a hashmap out of it

alpine wing
#

of pairs ? Like this ? :


public class ItemsDbAuthoring : MonoBehaviour
    {
        public class ItemsDbAuthoringBaker : Baker<ItemsDbAuthoring>
        {
            public string GameSettingPath = "Settings/";
            
            public override void Bake(ItemsDbAuthoring authoring)
            {
                Entity main = GetEntity(TransformUsageFlags.Dynamic);
                AddComponent<ItemBakerTag>(main);
                DynamicBuffer<ItemPrefabComponentData> buffer = AddBuffer<ItemPrefabComponentData>(main);

                foreach (ScriptableObject scriptableObject in Resources.LoadAll<ScriptableObject>(GameSettingPath))
                {           
                    Entity entity = GetEntity(((ItemsSettings)scriptableObject).Prefab, TransformUsageFlags.Dynamic);
                    buffer.Add(new ItemPrefabComponentData()
                    {
                        ID = ((ItemsSettings)scriptableObject).GetHashCode(),
                        ConveyorPrefab = entity
                    });
                }
            }
        }
    }

    public struct ItemBakerTag : IComponentData
    {
    }

    public struct ItemPrefabComponentData : IBufferElementData
    {
        public int ID;
        public Entity ItemsPrefab;
    }
woven thorn
#

yeah

alpine wing
#

and then at runtime get the entity tagged with ItemBakerTag and extract the infos ?

woven thorn
#

yeah, you can just have a system that iterates ItemBakerTag with none ProcessedTag

#

so when one iterated - add to your singleton hashmap

#

and then attach ProcessedTag

#

so system never runs again

alpine wing
#

Yeah that's already what i'm currently doing

#

I wanted to make sure the first option was not possible

#

hence why this topic , the logic is very similar

#

But I do have a subscene with the baker that do what is shown

#

but then I have a system running once to gather the infos from the entity baked that load into the hashmap in the service

#

that is then used by stuff to instantiate items from the prefab references

#

It look like this :

public partial struct PopulateItemsSettingSystem : ISystem
    {
        public void OnUpdate(ref SystemState state)
        {
            EntityQuery query = _.SystemAPI.CreateEntityQuery(ComponentType.ReadOnly<ItemBakerTag>());
            
            Entity result = query.GetSingletonEntity();
            foreach (ItemPrefabComponentData itemPrefabComponentData in _.SystemAPI.GetBuffer<ItemPrefabComponentData>(result))
            {
                _.Settings.AddItemPrefab(itemPrefabComponentData.ID, itemPrefabComponentData.ConveyorPrefab);
            }

            state.Enabled = false;
        }
    }
#

Nothing fancy but does the job.
I need to double check that it work in a build tho