Search Unity

Question Editor keeps crashing, what am I doing wrong?

Discussion in 'Entity Component System' started by dCalle, May 14, 2020.

  1. dCalle

    dCalle

    Joined:
    Dec 16, 2013
    Posts:
    55
    Hey folks, so I got this code. instead of .Run() I used Schedule and ScheduleParallel. but whatever I do, the editor keeps crashing, once the System starts. I snayone out there who can give me the right pointers?

    I'm feeling pretty dumb right now :-/

    Code (CSharp):
    1. using System;
    2. using Unity.Collections;
    3. using Unity.Entities;
    4. using Unity.Jobs;
    5. using Unity.Mathematics;
    6. using Unity.Transforms;
    7.  
    8. [GenerateAuthoringComponent]
    9. public struct GravityWell : IComponentData
    10. {
    11.     public float maxDownForce, maxUpForce, desiredDistance, maxDownForceDistance, maxUpForceDistance;
    12.     public bool hasVelocity;
    13. }
    14.  
    15. public struct GravityAssignData
    16. {
    17.     public Entity entity;
    18.     public Translation translation;
    19. }
    20.  
    21. [GenerateAuthoringComponent]
    22. public struct UnassignedGravity : IComponentData { }
    23.  
    24. public struct EntityRelation
    25. {
    26.     public Entity first;
    27.     public Entity second;
    28.  
    29.     public EntityRelation(Entity first, Entity second)
    30.     {
    31.         this.first = first;
    32.         this.second = second;
    33.     }
    34. }
    35.  
    36. [UpdateBefore(typeof(GravitySystem))]
    37. public class GravityAssignSystem : SystemBase
    38. {
    39.     protected override void OnUpdate()
    40.     {
    41.         var buffer = World.GetOrCreateSystem<BeginInitializationEntityCommandBufferSystem>().CreateCommandBuffer()
    42.             .ToConcurrent();
    43.         // var list = new UnsafeList<GravityAssignData>(5, Allocator.TempJob);
    44.         var queue = new NativeQueue<GravityAssignData>(Allocator.TempJob);
    45.         var queueWriter = queue.AsParallelWriter();
    46.         NativeList<GravityAssignData> list = new NativeList<GravityAssignData>(Allocator.TempJob);
    47.         NativeQueue<EntityRelation> entityQueue = new NativeQueue<EntityRelation>(Allocator.TempJob);
    48.         var entityWriter = entityQueue.AsParallelWriter();
    49.  
    50.  
    51.         Entities.ForEach((in Entity entity, in GravityWell well, in Translation translation) =>
    52.         {
    53.             queueWriter.Enqueue(new GravityAssignData
    54.             {
    55.                 entity = entity,
    56.                 translation = translation
    57.             });
    58.         }).Run();
    59.  
    60.  
    61.         while (queue.TryDequeue(out var data))
    62.         {
    63.             list.Add(data);
    64.         }
    65.  
    66.         if (list.Length != 0)
    67.         {
    68.             var array = list.AsDeferredJobArray();
    69.             Entities.ForEach(
    70.                 (in Entity entity, in UnassignedGravity gravity, in Translation translation) =>
    71.                 {
    72.                     var newTarget = Entity.Null;
    73.                     float minDistance = float.MaxValue;
    74.                     for (var i = 0; i < array.Length; i++)
    75.                     {
    76.                         var data = array[i];
    77.                         var distancesq = math.distancesq(translation.Value, data.translation.Value);
    78.                         if (distancesq < minDistance)
    79.                         {
    80.                             minDistance = distancesq;
    81.                             newTarget = data.entity;
    82.                         }
    83.                     }
    84.  
    85.                     entityWriter.Enqueue(new EntityRelation(entity, newTarget));
    86.                 }).Run();
    87.         }
    88.  
    89.         while (entityQueue.TryDequeue(out var tuple))
    90.         {
    91.             EntityManager.RemoveComponent<UnassignedGravity>(tuple.first);
    92.             EntityManager.AddComponentData(tuple.first, new PrivateGravity
    93.             {
    94.                 targetGravityWell = tuple.second
    95.             });
    96.         }
    97.  
    98.         queue.Dispose();
    99.         list.Dispose();
    100.         entityQueue.Dispose();
    101.  
    102.         // Job.WithStructuralChanges().WithCode(() =>
    103.         // {
    104.         // }).Run();
    105.     }
    106. }
     
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    If you disable burst compilation, you see any errors?
     
    dCalle likes this.
  3. dCalle

    dCalle

    Joined:
    Dec 16, 2013
    Posts:
    55
    Nope. 2019.3.13f instantly crashes, 12f doesn't create entities with IComponentData GravitiyWell and UnassignedGravity from their prefabs. pretty weird^^
     
  4. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    991
    .

    UnassignedGravity is a tag component data, I'm not sure you can use that in the foreach lambda expresison.
    From what I understand the foreach labda is reinterpreted through reflection at compile time so maybe it does not like it.
    (disclaimer, I'm absolutly not sure of what I'm saying :p)

    try replacing it with .WithAll<UnassignedGravity>()
     
    dCalle likes this.
  5. dCalle

    dCalle

    Joined:
    Dec 16, 2013
    Posts:
    55
    ok thanks, I look into it ;-)
     
  6. dCalle

    dCalle

    Joined:
    Dec 16, 2013
    Posts:
    55
    ok, it seems, that UpdateBeforeAttribute is giving me this issue in 12f. that means removing it actually lets it appear in the entity manager and it does its job. Have to check it out for 13f though.

    So how can I use something like UpdateBeforeAttribute without using UpdateBeforeAttribute?^^
     
  7. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,759
    A few code comments,

    var array = list.AsDeferredJobArray();
    Why are you doing this.

    var entityWriter = entityQueue.AsParallelWriter();
    Doesn't need to be parallel as you are writing to it in a single threaded job.
     
    dCalle likes this.
  8. dCalle

    dCalle

    Joined:
    Dec 16, 2013
    Posts:
    55
    I actually wrote a different code but I was afraid the multithreaded code was having some errors, that's why I changed the ScheduleParallels to Run (Unity made me use them at that time)

    the code I'm using now is:


    Code (CSharp):
    1.         var queue = new NativeQueue<GravityAssignData>(Allocator.TempJob);
    2.         var queueWriter = queue.AsParallelWriter();
    3.         var list = new NativeList<GravityAssignData>(Allocator.TempJob);
    4.         var array = list.AsDeferredJobArray();
    5.      
    6.      
    7.         JobHandle queueHandle = Entities.ForEach((in Entity entity, in GravityWell well, in Translation translation) =>
    8.         {
    9.             queueWriter.Enqueue(new GravityAssignData(entity, translation));
    10.         }).ScheduleParallel(Dependency);
    11.      
    12.         JobHandle listHandle = Job.WithCode(() =>
    13.         {
    14.             while (queue.TryDequeue(out var data))
    15.             {
    16.                 list.Add(data);
    17.             }
    18.         }).Schedule(queueHandle);
    19.      
    20.      
    21.         var entityHandle = Entities.ForEach(
    22.             (ref PrivateGravity gravity, in Entity entity, in Translation translation) =>
    23.             {
    24.                 if (gravity.targetGravityWell == Entity.Null && array.Length != 0)
    25.                 {
    26.                     var newTarget = Entity.Null;
    27.                     float minDistance = float.MaxValue;
    28.                     for (var i = 0; i < array.Length; i++)
    29.                     {
    30.                         var data = array[i];
    31.                         var distancesq = math.distancesq(translation.Value, data.translation.Value);
    32.                         if (distancesq < minDistance)
    33.                         {
    34.                             minDistance = distancesq;
    35.                             newTarget = data.entity;
    36.                         }
    37.                     }
    38.                     gravity.targetGravityWell = newTarget;
    39.                 }
    40.             }).ScheduleParallel(listHandle);
    41.      
    42.         entityHandle.Complete();
    43.  
    44.         list.Dispose();
    45.         queue.Dispose();
    46.  
    ( I know I should properly setup the components so I can prevent the last foreach, but I'm new to Dots and Entities so I try to get a hang of it^^)