Search Unity

ComponentData using EntityQuery in Bootstrap

Discussion in 'Entity Component System' started by RoughSpaghetti3211, Jul 2, 2019.

  1. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,705
    Wondering if there is a way to get component data in my bootstrap class from a cache entity using a EntityQuery.

    Code (CSharp):
    1.            
    2.  
    3.             query = new EntityQueryDesc
    4.             {
    5.                 Any = new ComponentType[] { typeof(HexSphereBuildDataComponent) }, // any
    6.                 None = Array.Empty<ComponentType>(), // none
    7.                 All = Array.Empty<ComponentType>(), // all
    8.             };
    9.  
    10.             qBuildData = em.CreateEntityQuery(query);
    11.            
    12.              // ??????????????
    13.              // egHexSphereBuildDataComponent bdc =  EmtilyManager.GetComponentDataFromEntityQuery
    14.              // ??????????
    15.  
    Thanks
     
  2. psuong

    psuong

    Joined:
    Jun 11, 2014
    Posts:
    126
    You can use World.Active.EntityManager.GetComponentData<T>(cachedEntity). This will return a copy of the component data you'd like to process on in your bootstrapper.
     
  3. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,705
    Thanks for the reply, I thing I tried going down that path but wasn’t able to workout how to get the Entity outside of a system.

    Any help would be appreciated
     
  4. psuong

    psuong

    Joined:
    Jun 11, 2014
    Posts:
    126
    Well if you wanted to get an entity outside of a system:

    You can create an EntityQuery via the EntityManager:

    EntityQuery query = World.Active.EntityManager.CreateEntityQuery(<some component types>);


    Or by getting it from a system

    EntityQuery query = World.Active.GetExistingSystem<T>().Some_Public_Query_Youve_Made;
    EntityQuery[] dependencyQueries = World.Active.GetExistingSystem<T>().EntityQueries;


    And from there you can get a NativeArray of Entities:

    NativeArray<Entity> entities = query.ToEntityArray(Allocator.TempJob);


    Once you have your entities you can grab the component data via EntityManager.
     
    RoughSpaghetti3211 likes this.
  5. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,705
    Thanks heaps for this
     
  6. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,705
    Im going to go with an EntityQuery via the EntityManager.

    But wanted to learn how going through the system works in particular World.Active.GetExistingSystem<T>().Some_Public_Query_Youve_Made

    Ive tried searching web and doc to educate myself but no luck, where did you find information no how this works? Make me think there is a whole bunch of stuff I can handle better
     
  7. psuong

    psuong

    Joined:
    Jun 11, 2014
    Posts:
    126
    So what I mean with Some_Public_Query_Youve_Made is you create a public EntityQuery in OnCreate() callback, so e.g

    Code (CSharp):
    1. public ASystem : ComponentSystem {
    2.   public EntityQuery uniqueQuery;
    3.  
    4.   protected override void OnCreate() {
    5.     uniqueQuery = CreateEntityQuery(<component-types>);
    6.   }
    7.   ...
    8. }
    Because you're storing the query as a public variable you can access it like so in a bootstrapper.

    var query = World.Active.GetExistingSystem<ASystem>().uniqueQuery;
     
    Last edited: Jul 3, 2019
  8. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,705
    Ahh ok got it. Thanks for clarifying
     
  9. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,705
    Do I need to do something special for Entities that were created with subscenes. I can see them in the editor before I hit play but cant access them in my bootstrap class. My EntityQuery is always 0. Are they in a different world and if so how do I access another world?

    View attachment 444872
    Screen Shot 2019-07-03 at 12.47.35 AM.png

    Code (CSharp):
    1.      
    2.  
    3.         [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    4.         public static void InitializeBeforeScene()
    5.         {
    6.             em = World.Active.EntityManager;// EntityManager manages all entities in world
    7.             EntityQuery query = World.Active.EntityManager.CreateEntityQuery(typeof(HexSphereBuildDataComponent));
    8.  
    9.             NativeArray<Entity> entities = query.ToEntityArray(Allocator.TempJob);
    10.             Debug.Log(entities.Length + "______"); // This is 0 ?????
    11.        
    12.             for (int i = 0; i < entities.Length; i++)
    13.             {
    14.                 HexSphereBuildDataComponent data =        World.Active.EntityManager.GetComponentData<HexSphereBuildDataComponent>(entities[i]);
    15.             }
    16.             entities.Dispose();
    17.         }
    18.  
     
  10. psuong

    psuong

    Joined:
    Jun 11, 2014
    Posts:
    126
    I haven't played around with subscenes yet. But I'm wondering if using
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    runs before the subscene has been loaded which can potentially be your problem. What happens if you tried the query in an update loop? How many entities do you get?
     
  11. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,705
    Im using liveLink so the entities are in the scene before run time. What is weird is if you look at the image i posted you can see im not in play mode and the entities are in "Editor Word". Im a bit loss on this one.

    EDIT query returns 0 length
     
  12. psuong

    psuong

    Joined:
    Jun 11, 2014
    Posts:
    126
    So I just went over the basic docs on subscenes: https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/Samples/Assets/HelloCube/4. SubScene

    Since you have the RuntimeInitializationLoadType.BeforeSceneLoad attribute, would it be the fact that the subscene hasn't been streamed in yet?

    Taken from the docs
    "You can load a Sub Scene automatically on play. You can also defer loading until you stream the SubScene in from code (Using the RequestSceneLoaded component)

    By default, Sub Scenes are loaded from the Entity binary files, even in the editor."

    The EditorWorld entities would be the subscene streamed into the editor so you can edit, make tweaks and eventually save to.

    But I can try in a few days so I can actually play with Subscenes and give you a better answer.
     
  13. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,705
    Ive tried everything I can think of. Everything from RequestSceneLoaded tag to

    var sys = GetOrCreateSystem<Unity.Scenes.SubSceneStreamingSystem>();
    EntityQuery query = sys.World.EntityManager.CreateEntityQuery(typeof(HexSphereBuildDataComponent));

    I either get 0 or I get the Entity subScene, Any ideas, seems like it should be straight forward getting existing entities created w sub-scenes using live link