Trying to grab a singel entity with EntityQuery from object pool

Hello

I am trying to shoot projectiles, for that I would use a pool of inactive projectiles instead of instantiate a new projectile every time. With EntityQuery and EntityCommandBuffer I try to get a single projectile that is inactive and activate it. My current approach is to ether use a bool in the component to disable and enable it or adding or removing component tags. But I am failing to access a single entity with projectile component and DeactivateTag. This feels like a simple problem.

I think i am not using the EntityQuery incorrecly and i get a error when i try to run.
Error

ArgumentException: EntityQuery.CompareComponents may not include typeof(Entity), it is implicit
Unity.Entities.EntityQueryManager.CompareComponents (Unity.Entities.ComponentType* componentTypes, System.Int32 componentTypesCount, Unity.Entities.EntityQueryData* queryData) (at Library/PackageCache/com.unity.entities@0.17.0-preview.42/Unity.Entities/Iterators/EntityQueryManager.cs:332)

When I checked the unity GitHub samples, they just instantiate a new entity in most examples. So mabye my approach is wrong and i should just spawn new projectiles and then destroy them.

https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/ECSSamples

System

    protected override void OnUpdate()
    {
        var beginCommandbuffer = beginECB.CreateCommandBuffer();
        var endCommandbuffer = endECB.CreateCommandBuffer().AsParallelWriter();
        EntityQuery projectileQuery = GetEntityQuery(ComponentType.ReadOnly<Entity>(), ComponentType.ReadWrite<ProjectileComponent>(), ComponentType.ReadWrite<DeactivateTag>());


        var projectileGroup = projectileQuery.ToComponentDataArray<ProjectileComponent>(Allocator.Temp);
        var deactivatedProjectiles = projectileQuery.ToEntityArray(Allocator.Temp);

        //Fire weapon
        Entities.ForEach((ref WeaponFire weaponFire) =>
        {

            if (weaponFire.fire)
            {
                beginCommandbuffer.RemoveComponent<DeactivateTag>(deactivatedProjectiles[0]);
               
            }

            //var test = projectileQuery.ToComponentDataArray<ProjectileComponent>(Allocator.TempJob);






        }).Schedule();

        deactivatedProjectiles.Dispose();
    }

Components

public struct ProjectileComponent : IComponentData
{
    public float maxLifeTime;
    public float lifeTime;

    public float projectileSpeed;
    public float damage;

    public bool active;
    //Enum for dmg Type

    public float3 direction;
    public float3 position;



}


public struct WeaponFire : IComponentData
{
    public bool fire;
    public float3 barrelPosition;

}

Any help or examples would be appreciated

From here :

So I would just instantiate what I need and ONLY try optimizations when there is a real performance problem. I remember a conference video where someone created thousands of bullets in ECS. So there should be enough room for you to instantiate “some” projectiles out of the box without worrying too much.
Keep in mind that you would probably also have to serialize your pool. So managing all this becomes difficult. Also enabling and disabling entities has an overhead and may get them copyied around (until enabling components becomes a thing). So don’t make your life more complicated than it needs to be. Just create what you need and destroy what has served it’s purpose.

2 Likes

Thanks, i might just be over think this. I am planning to use lots of projectiles, but i will test and then see what needs tweaking.

1 Like

For the reference the video I mentioned was Unity ECS Angry Bots demo - full code walkthrough by Brian Will.

1 Like

Looked through the video, and he does a good breakdown that i can understand. Will save that as a referens.

1 Like

Tried that demo on my machine, and it was able to handle around 30 000 bullets at 60-90 fps. Going to try and build a stress test with characters shooting and se if its enough for my usage

PC Specs:
2080ti
ryzen 5900