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

Get Component Array

Discussion in 'Entity Component System' started by sebas77, Feb 14, 2019.

  1. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    Hi,

    What are the way to explicitly get component arrays in UnityECS without resorting injection? Currently I use this:

    var positions = _unityECSgroup.GetComponentDataArray<Position>();

    where

    var manager = World.Active.GetOrCreateManager<EntityManager>();
    var archetype = manager.CreateArchetype(typeof(Position),
    typeof(Rotation),
    typeof(RenderMesh));

    _unityECSGroup = manager.CreateComponentGroup(archetype.ComponentTypes);

    however I couldn't find a GetComponentGroup so everytime I have to pass this group reference around. Is there a way to avoid that?
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,752
    sebas77 likes this.
  3. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    so there is no way to access to the data from the "main" thread or outside a job?
     
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,752
  5. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,752
  6. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    thanks a lot! Is there a way to know when a Job completed to iterate over all the entities or chunks?
     
  7. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    they also have this syntax, but it only works in a component system not in a jobcomponent system (dont know why)
    Code (CSharp):
    1.             ForEach( (ref DummyData data) =>
    2.             {
    3.                 data.Value = 1;
    4.             }, GetComponentGroup(typeof(DummyData)));

    edit: i used this for the first time today, not well documented or i did not find it
     
  8. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,752
    ^ yeah that's quite useful. My tutorial was out before that api existed so I don't have an example.
     
  9. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    so there is no way to access that data inside a class that is not a UnityECS based class?
     
  10. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,154
    i have not tried that, but it should. You can grab the EntityManger from anywhere as far as I know
     
  11. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    I wouldn't be that surprised if it is not possible, actually it makes sense that I shouldn't rely on a static class to get the data.
     
  12. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    Can ComponentSysttem be newed manually instead to rely on reflection for its creation?
     
  13. AndesSunset

    AndesSunset

    Joined:
    Jan 28, 2019
    Posts:
    60
    Yes, but it won’t be part of a World, and won’t be considered for the update loop.
     
  14. elcionap

    elcionap

    Joined:
    Jan 11, 2016
    Posts:
    138
    Code (CSharp):
    1. var system = new FooSystem(parameter);
    2.  
    3. world.AddManager(system);
    []'s
     
    AndesSunset and sebas77 like this.
  15. Tony_Max

    Tony_Max

    Joined:
    Feb 7, 2017
    Posts:
    349
    You can use dependencies with job, so if job A depends on a job B the A job will run only after B complete.

    Example
    Code (CSharp):
    1. var moveJob = new MoveJob { ... };
    2. JobHandle moveHandle = moveJob.Schedule(this, inputDeps);
    3.  
    4. var hexCrossingJob = new HexCrossingJob {...};
    5. JobHandle hexCrossingHandle = hexCrossingJob.Schedule(this, moveHandle);
     
    sebas77 likes this.
  16. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    Another question, hope last one: do you know how Unity guarantees the thread safety of the entities data? I may be able to guess what's going on if the entities are accessed only by jobs, but I am not sure how it works since I can access the data from the mainthread as well. I don't think the containers are thread safe per se right?
     
  17. Tony_Max

    Tony_Max

    Joined:
    Feb 7, 2017
    Posts:
    349
    "Managing dependencies is hard. This is why in JobComponentSystem we are doing it automatically for you. The rules are simple: jobs from different systems can read from IComponentData of the same type in parallel. If one of the jobs is writing to the data then they can't run in parallel and will be scheduled with a dependency between the jobs."

    From documentation
     
  18. elcionap

    elcionap

    Joined:
    Jan 11, 2016
    Posts:
    138
    They "don't".
    The system is designed to chained execution based on dependencies based on what data a system need and what they would do to it (read/write). There is no safety check in the release, only in the editor to help you to debug errors and dependencies.
    You can look in the Job System, that can be used outside ECS, to get an idea how it works. The difference is the ECS automatic take care of creating the dependencies, adding sync points and scheduling jobs.

    []'s
     
  19. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    does it mean that jobs writing to data must also wait for the main thread to finish or something (if the main thread is accessing to that data)?
     
  20. elcionap

    elcionap

    Joined:
    Jan 11, 2016
    Posts:
    138
    Yes. You can't write in the same data at the same time that a Job is reading or writing. One of them will need to wait. For now the systems can read at the same time but writing needs to be isolated. You can disable the safety check if you now what you are doing but an error give you a hard crash.

    Example of disabling a safety check:
    Code (CSharp):
    1. struct RandomPosition: IJobParallelFor {
    2.     [NativeDisableParallelForRestriction]
    3.     public NativeArray<Position> Positions;
    4.  
    5.     [ReadOnly]
    6.     public NativeHashMap<Entity, int> EntitiesPosition;
    7.  
    8.     [ReadOnly]
    9.     public NativeArray<Entity> Entities;
    10.  
    11.     public void Execute(int index) {
    12.         var entity = Entities[index];
    13.         var random = new Random((uint)entity.Index);
    14.  
    15.         if (Entities.TryGet(entity, out var postionIndex)) {
    16.             Positions[positionIndex] = random.NextFloat3();
    17.         }
    18.     }
    19. }
    In the example above the safety check will only let me write in the index received. But I know that there is no duplicate entities in the Entities array and the same position is not referenced to more than one entity. So I can assume that there is no concurrency and can use NativeDisableParallelForRestriction to write in the Positions array.

    Obs.: This code wasn't tested but written directly here.

    []'s
     
  21. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    thanks a lot you all have been very helpful
     
    AndesSunset likes this.
  22. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    I tried this, but the system callbacks, like OnUpdate are not called. Any clue?
     
  23. elcionap

    elcionap

    Joined:
    Jan 11, 2016
    Posts:
    138
    Did you update the player loop?
    If you are using the default world try this.

    Code (CSharp):
    1. Unity.Entities.ScriptBehaviourUpdateOrder.UpdatePlayerLoop(World.Active)
    This will recreate the entire player loop and is costly.

    []'s
     
  24. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    Doesn't sound right to me, why should I do that? Anyway there are other callbacks that are not called either.
     
  25. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,752
    That is 100% right.

    You have to update the player loop after adding a system manually as systems aren't automatically added. Just add all your managers then update it.
     
  26. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,640
    Ok thanks I'll check tomorrow