Unity DOTS: Using EntityManager with Run() and Burst

Summary

EntityManager is a property of class ComponentSystemBase, which is not allowed with Burst. Assigning the EntityManager to a local variable can solve this problem.

Environment

  • Unity 2019.4.0f1
  • Entities 0.11.1-preview.4
  • Burst 1.3.0-preview.12

Explanation

Assuming we need to use EntityManager in the ForEach lambda with Run():

public struct SampleComponent : IComponentData { }
[AlwaysSynchronizeSystem]
public class SampleSystem : JobComponentSystem
{
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        Entities.ForEach((Entity entity) =>
        {
            if (EntityManager.HasComponent<SampleComponent>(entity))
            {
                Debug.Log($"{entity} has SampleComponent!");
            }
        }).Run();

        return default;
    }
}

However, there is an error in the editor:

D:\Workspace\ecs\Assets\Scripts\SampleSystem.cs(10,9): error DC0002: Entities.ForEach Lambda expression invokes 'get_EntityManager' on a SampleSystem which is a reference type. This is only allowed with .WithoutBurst() and .Run().

That’s because EntityManager is a property of class ComponentSystemBase, which is not allowed with Burst. We can assign EntityManager to a local variable before using it in the lambda:

[AlwaysSynchronizeSystem]
public class SampleSystem : JobComponentSystem
{
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        EntityManager entityManager = EntityManager;
        Entities.ForEach((Entity entity) =>
        {
            if (entityManager.HasComponent<SampleComponent>(entity))
            {
                Debug.Log($"{entity} has SampleComponent!");
            }
        }).Run();

        return default;
    }
}

Leave a Comment