Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question How to iterate over all entities in a query during Entity.ForEach()

Discussion in 'Entity Component System' started by Parlay-Creative, Sep 30, 2020.

  1. Parlay-Creative

    Parlay-Creative

    Joined:
    Sep 14, 2013
    Posts:
    7
    I'm trying to convert this Solar System simulator by Sabastian Lague to DOTS and need help when it comes to iterating over the component values for all entities in a query during Entity.ForEach().

    I think I need to complete the following steps:
    1. Write an EntityQuery()
    2. Use the query to populate a NativeArray<component>
    3. During Entity.ForEach() iterate over the NativeArray<component> to read the values
    I'm hung up on step 2. If anyone could point me in the right direction it would be appreciated.
     
  2. varnon

    varnon

    Joined:
    Jan 14, 2017
    Posts:
    52
    I forget if Sabastian uses a compute shader here. I really think its time he tries out the job system. It is very similar in use, and burst jobs are very, very good. That would also be a good transition for you into DOTS if you decide ECS is too much.

    It has been a while since I've looked at the logic of this, but if I recall correctly, you need to update each body based on the information from every other body.
    I did something similar with a boids situation. I actually ditched the separate EntiyQuery and just used two Entities.ForEach() (this does perform a query). I make a NativeArray to contain the information I want, then I do an Entities.ForEach() to fill that array with data from every entity. I use int entityInQueryIndex as a parameter in the ForEach lambda function, before any refs or ins, to use the index of each Entity in the ForEach to assign data to a corresponding index in the NativeArray. Then I used a second ForEach() to use the data collected from every Entity to update every Entity. Again I used int entityInQueryIndex in the lambda function. This way if I was on say, Entity 7 in ForEach, I would skip using the data from index 7 in my NativeArray to update Entity 7's components. I used ScheduleParallel() for both jobs, though I haven't checked how parallel things actually were. Performance is very similar to a highly optimized GameObjectless MonoBehavior + Burst Jobs approach.
     
    Parlay-Creative likes this.
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,217
    Code (CSharp):
    1. //Sync
    2. var arrayOfComponents = query.ToComponentDataArray<CustomComponent>(Allocator.TempJob);
    3.  
    4. //Async
    5. var arrayOfComponents = query.ToComponentDataArrayAsync<CustomComponent>(Allocator.TempJob, out JobHandle jh);
    6. Dependency = JobHandle.CombineDependencies(Dependency, jh);
     
    Parlay-Creative likes this.