Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

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

Discussion in 'Burst' started by Zylkowski_a, Jun 6, 2020.

  1. Zylkowski_a

    Zylkowski_a

    Joined:
    Jul 27, 2019
    Posts:
    157
    I am having weird problem in my JobComponentSystem. I have following code:
    Code (CSharp):
    1.         Entities.WithNone<ToGenerate,PrototypeTag>().WithAll<UpdateRuleTileTag>().ForEach(
    2.             (Entity e, RuleTileComponent ruleTileComponent,ref Translation t) =>
    3.             {
    4.                 ruleTilesGrid.SetCell((int3)t.Value,new RuleTileInfo()
    5.                 {
    6.                     entity = e,
    7.                     ruleTileComponent = ruleTileComponent
    8.                 });
    9.             }).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?
     
  2. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Why not
    assign the field to a local outside of the lambda expression
    ?
    Code (CSharp):
    1. var rtg = ruleTilesGrid;
    2.  
    3. Entities.WithNone<ToGenerate,PrototypeTag>().WithAll<UpdateRuleTileTag>().ForEach(
    4.             (Entity e, RuleTileComponent ruleTileComponent,ref Translation t) =>
    5.             {
    6.                 rtg.SetCell((int3)t.Value,new RuleTileInfo()
    7.                 {
    8.                     entity = e,
    9.                     ruleTileComponent = ruleTileComponent
    10.                 });
    11.             }).WithoutBurst().Run();
     
  3. Zylkowski_a

    Zylkowski_a

    Joined:
    Jul 27, 2019
    Posts:
    157
    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
     
    Last edited: Jun 6, 2020
    florianhanke likes this.
  4. florianhanke

    florianhanke

    Joined:
    Jun 8, 2018
    Posts:
    426
    Glad to hear it! :) (Also, here is more info about capturing variables: https://docs.unity3d.com/Packages/c...ecs_entities_foreach.html#capturing-variables)

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

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,695
  6. joepl

    joepl

    Unity Technologies

    Joined:
    Jul 6, 2017
    Posts:
    85
    I wasn't able to repro this error with the latest Entities and following system:

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Mathematics;
    3. using Unity.Transforms;
    4.  
    5. // This system updates all entities in the scene with both a RotationSpeed_ForEach and Rotation component.
    6.  
    7. // ReSharper disable once InconsistentNaming
    8. public class RotationSpeedSystem_ForEach : SystemBase
    9. {
    10.     RuleTileGrid ruleTilesGrid;
    11.  
    12.     // OnUpdate runs on the main thread.
    13.     protected override void OnUpdate()
    14.     {
    15.         float deltaTime = Time.DeltaTime;
    16.  
    17.         // Schedule job to rotate around up vector
    18.         Entities
    19.             .WithNone<ToGenerate, PrototypeTag>().WithAll<UpdateRuleTileTag>()
    20.             .WithName("RotationSpeedSystem_ForEach")
    21.             .ForEach((Entity e, ref Translation t, in RuleTileComponent ruleTileComponent) =>
    22.             {
    23.                 ruleTilesGrid.SetCell(t.Value,
    24.                 new RuleTileInfo()
    25.                 {
    26.                     entity = e,
    27.                     ruleTileComponent = ruleTileComponent
    28.                 });
    29.             }).WithoutBurst().Run();
    30.     }
    31. }
    32.  
    33. public struct UpdateRuleTileTag : IComponentData { }
    34.  
    35. public struct PrototypeTag : IComponentData { }
    36.  
    37. public struct ToGenerate : IComponentData { }
    38.  
    39. public struct RuleTileGrid
    40. {
    41.     public void SetCell(float3 t2Value, RuleTileInfo ruleTileInfo)
    42.     {}
    43. }
    44.  
    45. public struct RuleTileComponent : IComponentData { }
    46.  
    47. public struct RuleTileInfo : IComponentData
    48. {
    49.     public Entity entity;
    50.     public RuleTileComponent ruleTileComponent;
    51. }
    52.  
    Any chance you can create a bug with a minimal repro case. We can take a look as this should work.