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).
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;
}