ForEach lambda expression using outside field doesn't accept WithoutBurst()

I am having weird problem in my JobComponentSystem. I have following code:

        Entities.WithNone<ToGenerate,PrototypeTag>().WithAll<UpdateRuleTileTag>().ForEach(
            (Entity e, RuleTileComponent ruleTileComponent,ref Translation t) =>
            {
                ruleTilesGrid.SetCell((int3)t.Value,new RuleTileInfo()
                {
                    entity = e,
                    ruleTileComponent = ruleTileComponent
                });
            }).WithoutBurst().Run();

But Unity throws
error DC0001: Entities.ForEach Lambda expression uses field 'ruleTilesGrid'. Either assign the field to a local outside of the lambda expression and use that instead, or use .WithoutBurst() and .Run()
Moving .WithoutBurst() around doesn’t change anything. Any fix for this?

Why not assign the field to a local outside of the lambda expression ?

var rtg = ruleTilesGrid;

Entities.WithNone<ToGenerate,PrototypeTag>().WithAll<UpdateRuleTileTag>().ForEach(
            (Entity e, RuleTileComponent ruleTileComponent,ref Translation t) =>
            {
                rtg.SetCell((int3)t.Value,new RuleTileInfo()
                {
                    entity = e,
                    ruleTileComponent = ruleTileComponent
                });
            }).WithoutBurst().Run();

It needs to be persistent between each OnUpdate call

EDIT: It works like you mentioned but still there is “OR” in the error so giving WithoutBurst() and Run() should work. It’s still a bug but thank you for solution

1 Like

Glad to hear it! :slight_smile: (Also, here is more info about capturing variables: Using Entities.ForEach | Entities | 0.7.0-preview.19)

And I sadly have no idea why WithoutBurst() and Run() would not help.

I was also thrown off track with this error message a while back

I wasn’t able to repro this error with the latest Entities and following system:

using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;

// This system updates all entities in the scene with both a RotationSpeed_ForEach and Rotation component.

// ReSharper disable once InconsistentNaming
public class RotationSpeedSystem_ForEach : SystemBase
{
    RuleTileGrid ruleTilesGrid;

    // OnUpdate runs on the main thread.
    protected override void OnUpdate()
    {
        float deltaTime = Time.DeltaTime;

        // Schedule job to rotate around up vector
        Entities
            .WithNone<ToGenerate, PrototypeTag>().WithAll<UpdateRuleTileTag>()
            .WithName("RotationSpeedSystem_ForEach")
            .ForEach((Entity e, ref Translation t, in RuleTileComponent ruleTileComponent) =>
            {
                ruleTilesGrid.SetCell(t.Value,
                new RuleTileInfo()
                {
                    entity = e,
                    ruleTileComponent = ruleTileComponent
                });
            }).WithoutBurst().Run();
    }
}

public struct UpdateRuleTileTag : IComponentData { }

public struct PrototypeTag : IComponentData { }

public struct ToGenerate : IComponentData { }

public struct RuleTileGrid
{
    public void SetCell(float3 t2Value, RuleTileInfo ruleTileInfo)
    {}
}

public struct RuleTileComponent : IComponentData { }

public struct RuleTileInfo : IComponentData
{
    public Entity entity;
    public RuleTileComponent ruleTileComponent;
}

Any chance you can create a bug with a minimal repro case. We can take a look as this should work.