ECS SharedVariables

SharedVariables can be used within ECS tasks as long as long as the SharedVariable type is unmanaged and at most 16 bytes. The steps below show how to use a SharedVariable within an ECS task. This variable will be a SharedVariable<Entity>.

Declare the Variable

Use the same SharedVariable<T> pattern as non-ECS tasks. The biggest change from non-ECS tasks are that the variable must be registered within the ECSVariableRegistry. This registry is a parameter to the AddBufferElement method. The index is stored so the variable can be retrieved later on within the task.

[Tooltip("The entity that should be targeted.")]
[SerializeField] SharedVariable<Entity> m_TargetEntity;

private ECSSharedVariableIndex<Entity> m_TargetEntityIndex;

/// <summary>
/// Registers the target SharedVariable and adds the buffer element to the entity.
/// </summary>
/// <param name="world">The world that the entity exists in.</param>
/// <param name="entity">The entity that the IBufferElementData should be assigned to.</param>
/// <param name="registry">The ECS variable registry for registering SharedVariable fields.</param>
/// <param name="gameObject">The GameObject that the entity is attached to.</param>
/// <returns>The index of the element within the buffer.</returns>
public override int AddBufferElement(World world, Entity entity, ECSVariableRegistry registry, GameObject gameObject)
{
   m_TargetEntityIndex = new ECSSharedVariableIndex<Entity>(registry.Register(m_TargetEntity));
   return base.AddBufferElement(world, entity, registry, gameObject);
}

Store the Buffer Index

Systems need a stable integer index into SharedVariableElement. Persist it on your per-task component:

public override FindTargetComponent GetBufferElement()
{
   return new FindTargetComponent()
   {
      Index = RuntimeIndex,
      TargetEntityVariableIndex = m_TargetEntityIndex.Index,
   };
}

/// <summary>
/// The DOTS data structure for the FindTarget struct.
/// </summary>
public struct FindTargetComponent : IBufferElementData
{
      [Tooltip("The index of the node.")]
      public ushort Index;
      [Tooltip("Buffer index into SharedVariableElement for the target entity.")]
      public int TargetEntityVariableIndex;
}

Query the Buffer

Include DynamicBuffer<SharedVariableElement> in the query (alongside your task buffer and flags). The variable can be read with buffer.Get<T>(index) or written with buffer.Set(index, value):

foreach (var (branchComponents, taskComponents, findTargetComponents, sharedVariables) in
SystemAPI.Query<DynamicBuffer<BranchComponent>, DynamicBuffer<TaskComponent>, DynamicBuffer<FindTargetComponent>, DynamicBuffer<SharedVariableElement>>().WithAll<FindTargetFlag, EvaluateFlag>()) {
   for (int i = 0; i < findTargetComponents.Length; ++i) {
      var fndTargetComponent = findTargetComponents[i];
      // ...
      // Store the found target in the shared variable buffer.
      if (foundAgent) {
         targetEntity = entities[index];
      }
      sharedVariables.Set(fndTargetComponent.TargetEntityVariableIndex, targetEntity);