I’m creating entities at runtime with one or more children. I have added a parent component (which adds the child components to the child entities) but am struggling to add the LinkedEntityGroup to the parent.
When I add the children to the buffer I get an invalid structural change error.
DynamicBuffer<LinkedEntityGroup> linkedEntityGroup = entityManager.AddBuffer<LinkedEntityGroup>(parentPrefabEntity);
linkedEntityGroup.Add(parentPrefabEntity);
// This generators: ObjectDisposedException: Attempted to access BufferTypeHandle<Unity.Entities.LinkedEntityGroup> which has been invalidated by a structural change.
linkedEntityGroup.Add(childEntity);
Not sure what I’m doing wrong as can’t find any great examples and doco doesn’t seem to give any either. I want to be able to Instantiate my prefab parent entity and have the children be instantiated at the same time.
Using entity manager to add your buffer to your entity caused a structural change, so you need to get the buffer again after you add it. You could use an entity command buffer instead of the entitymanager to avoid this.
1 Like
Are there structural changes between the first and second calls to DynamicBuffer<T>.Add
in your code? Adding the buffer causes a structural change, but the returned buffer will still be valid up to the point where another structural change occurs. The first call succeeds because no new structural changes occurred, and the second call probably throws because you did something causing structural changes. In this case, what you could do is either call GetBuffer each time when adding children, or have a temporary list (NativeList or UnsafeList) store all the entries to add, then add the buffer and fill it all in one go.
This seemed to work, thanks!
NativeList<Entity> linkedEntityList = new NativeList<Entity>(prefabRootTransform.childCount, Allocator.Temp);
linkedEntityList.Add(parentEntity);
// Find non-recursive child transform
foreach (Transform childTfrm in prefabRootTransform)
{
Entity childEntity = entityManager.CreateEntity();
// Add child components...
entityManager.AddComponentData(childEntity, ...
linkedEntityList.Add(childEntity);
}
if (linkedEntityList.Length > 1)
{
// Add a LinkedEntityGroup to the parent
DynamicBuffer<LinkedEntityGroup> linkedEntityGroup = entityManager.AddBuffer<LinkedEntityGroup>(parentEntity);
// Add the parent and children to the LinkedEntityGroup
for (int eIdx = 0; eIdx < linkedEntityList.Length; eIdx++)
{
linkedEntityGroup.Add(linkedEntityList[eIdx]);
}
}
linkedEntityList.Dispose();