I have a “root” entity which places the childs correctly in the world. There exist 100 different childs (different Combination of Datacomponents & number of “sub childs” …)
The problem now is the cleanup of the entites. I have a job which iterates over each root object and decides if it should be removed or not. The thing is that if i destroy a root entity, the childs still exist and are not removed.
I could write a job for each component combination which will cleanup the childs correctly, but this will take alot of time and i wonder if there is an easier way to just say "CommandBuffer.DestroyEntityWithChilds(entity); or not.
EntityCommandBuffer also has this overload but you can’t use it in a job because jobs can’t take reference types (EntityQuery).
If you want to destroy a hierarchy in a job I would go for traversing the hierarchy recursively from root to all the children and destroying them recursively. Heck you can even use bust with that.
I’ve took some time and wrote a Parallel job that will destroy and transform hierarchy as I might also need this in the future.
[BurstCompile]
struct DestroyHierarchyJob<T> : IJobForEachWithEntity<T>
where T: struct, IComponentData {
public EntityCommandBuffer.Concurrent CmdBuffer;
[ReadOnly]
public BufferFromEntity<Child> ChildrenFromEntity;
public void Execute(Entity entity, int index, [ReadOnly]ref T _) {
DestroyHierarchy(CmdBuffer, entity, index, ChildrenFromEntity);
}
void DestroyHierarchy(EntityCommandBuffer.Concurrent cmdBuffer, Entity entity, int index, BufferFromEntity<Child> childrenFromEntity) {
if (!childrenFromEntity.Exists(entity))
return;
var children = childrenFromEntity[entity];
for (var i = 0; i < children.Length; ++i) {
var childEntity = children[i].Value;
cmdBuffer.DestroyEntity(index, childEntity);
DestroyHierarchy(cmdBuffer, childEntity, index, childrenFromEntity);
}
}
}
Now when you want to destroy a hierarch just ForEach → If(root.Value.Equals(XXX)) → AddComponentData(root.Value, DestroyRoot)
DestroyRoot is a IComponentData that you will add to your root entities to trigger the destroy system.
Thank you for your code examples! Can you please talk a little bit about BufferFromEntity ? I have never seen something like that in the ECS examples and i can guess what it does, but a little explanation would be good
EDIT: i played around with your code and found that it doesnt work on my system. My guess is because i never specify any Buffer anywhere so my “Child Buffer” is always empty and doesnt iterate over it.
I create my Entites via code like this:
var parent = CommandBuffer.Instantiate(Entity);
var child= CommandBuffer.Instantiate(Entity);
CommandBuffer.AddComponent(child, new Parent{Value = parent});
EDIT2: I struggle to add something to my buffer here (i guess?):
When you add a children into your transform hierarchy an internal state is added to the parent entity as ISystemStateBufferElementData. Read more about the TransformSystem here.
BufferFromEntity is how you access dynamic buffers inside jobs.
To create your entities you should try to use the entity conversion workflow , but if you really must do it from code you must add LocalToWorld and LocalToParent component after CommandBuffer.AddComponent(child, new Parent{Value = parent}); [quote=“Cell-i-Zenit, post:6, topic: 745296, username:Cell-i-Zenit”] EDIT2: I struggle to add something to my buffer here (i guess?): var buffer = CommandBuffer.AddBuffer(index, entity); buffer.Add(new Child(){Value = child1}); buffer.Add(new Child(){Value = child2}); buffer.Add(new Child(){Value = child3});
*[/quote]
*
You can’t do that (and you don’t need to) because it is the internal system state of TransformSystem.
Thank you for your help, it looks like i had it working before (like you now explained it), but like always the error was on a different part of the code The error was that i used OnStartRunning not as it was intended. I thought its kind of like Start (and OnCreate is awake), but it gets executed every frame(?).
Is there an explanation where i can get information about the overrides? When they are executed etc?