unity-dots

Entity Query for ISystems and SystemBase in Unity ECS 1.0


I have a tile based building game in Unity ECS 1.0, where I add particular IComponentData to several systems. From a PlayerInput which is a MonoBehavior (because PlayerInput and InputActions are not translated to ECS), I tried to query all systems having that IComponentData. But I found that regular EntityQueries do not match for Entity representation of systems, so I had to use EntityManager.UniversalQueryWithSystems, which returns the Entity representation of all systems. There I do a for loop and check all systems for that particular component. Does anybody know if there is a more performant way to check for these components on systems? I already tried to return EntityManager.UniversalQueryWithSystems.ToComponentDataArray<MyComponent>(), but then it's complaining, that the query have not been initialized using this component (which of course I may not change, as it's not my own query).


Solution

  • I just found it. You can pass options to an EntityQueryBuilder or a call to SystemAPI.Query<>(..) with the method .WithOptions(..) then just pass EntityQueryOptions.IncludeSystems.

    So a complete call could look like this:

    public static NativeArray<Entity> GetSystemsManaged<T>() where T : struct, IComponentData
    {
        if (World.DefaultGameObjectInjectionWorld == null
            || !World.DefaultGameObjectInjectionWorld.IsCreated
            || World.DefaultGameObjectInjectionWorld.EntityManager == null)
        {
            return new NativeArray<Entity>(0, Allocator.Temp);
        }
        EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
        EntityQueryBuilder queryBuilder = new EntityQueryBuilder(Allocator.Temp)
            .WithAll<T>()
            .WithOptions(EntityQueryOptions.IncludeSystems);
        EntityQuery entityQuery = entityManager.CreateEntityQuery(queryBuilder);
        NativeArray<Entity> result = entityQuery.ToEntityArray(Allocator.Temp);
        queryBuilder.Dispose();
        entityQuery.Dispose();
        return result;
    }