Entity Variables
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 states. The biggest change from non-ECS states 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 state.
[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>
/// <param name="stateMachineID">The ID of the state machine running the state.</param>
/// <param name="index">The runtime index of the state.</param>
/// <returns>The index of the element within the buffer.</returns>
public override int AddBufferElement(World world, Entity entity, ECSVariableRegistry registry, GameObject gameObject, int stateMachineID, ushort index)
{
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-state 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 state buffer and flags). The variable can be read with buffer.Get<T>(index) or written with buffer.Set(index, value):
foreach (var (stateComponents, findTargetComponents, sharedVariables) in
SystemAPI.Query<DynamicBuffer<StateComponent>, 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);