Search Unity

Resolved Setting values on entities instantiated through an ECB

Discussion in 'Entity Component System' started by chemicalcrux, Oct 22, 2022.

  1. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    720
    I'm writing a nested spawning system. Each parent object can produce many child objects. The child objects have the same component as the parent object.

    I want the parent to be able to configure the children.

    The most obvious approach was to use a component lookup to get the component data from the newly-spawned entity, modify it a bit, and then use the lookup to set the new data.

    This doesn't work, since the entity doesn't actually exist yet.

    Is there a nice way to do this?
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    In 1.0 they added a handy new API for this on EntityCommandBuffer

    Code (CSharp):
    1. /// <summary>Records a command that sets a component for an entity's <see cref="LinkedEntityGroup"/> based on an <see cref="EntityQueryMask"/>.
    2. /// Entities in the <see cref="LinkedEntityGroup"/> that don't match the mask will be skipped safely.</summary>
    3. /// <remarks>Behavior at Playback: Will throw an error if the entity is destroyed before playback,
    4. /// if the entity is still deferred, if the entity has the <see cref="Prefab"/> tag, or if any of the matching linked entities do not already have the component.</remarks>
    5. /// <param name="e">The entity whose LinkedEntityGroup will be modified by this command.</param>
    6. /// <param name="mask">The EntityQueryMask that is used to determine which linked entities to set the component for.
    7. /// Note that EntityQueryMask ignores all query filtering (including chunk filtering and enableable components),
    8. /// and may thus match more entities than expected.</param>
    9. /// <param name="component"> The component value to set. </param>
    10. /// <typeparam name="T"> The type of component to add.</typeparam>
    11. /// <exception cref="ArgumentException">Throws if the component has a reference to a deferred entity, requiring fixup within the command buffer.</exception>
    12. /// <exception cref="NullReferenceException">Throws if an Allocator was not passed in when the EntityCommandBuffer was created.</exception>
    13. /// <exception cref="InvalidOperationException">Throws if this EntityCommandBuffer has already been played back.</exception>
    14. public void SetComponentForLinkedEntityGroup<T>(Entity e, EntityQueryMask mask, T component) where T : unmanaged, IComponentData
     
  3. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    720
    Ah, but that's the problem! I needed to get the values first, so that I can then modify and write them.

    I just realized, however, that I can just read the values once from the prefab entity, then go ahead and set them for everything. So, problem solved :p
     
    Antypodish likes this.