protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (minions.Length == 0)
        {
            return(inputDeps);
        }

        Profiler.BeginSample("Clearing buckets");

        if (!minionSystem.CollisionBuckets.IsCreated)
        {
            minionSystem.CollisionBuckets = new NativeMultiHashMap <int, int>(minions.Length, Allocator.Persistent);
        }
        else
        {
            minionSystem.CollisionBuckets.Clear();
        }

        // realloc if needed
        minionSystem.CollisionBuckets.Capacity = math.max(minionSystem.CollisionBuckets.Capacity, minions.Length);

        Profiler.EndSample();

        var prepareBucketsJob = new PrepareBucketsJob
        {
            transforms    = minions.transforms,
            buckets       = minionSystem.CollisionBuckets,
            minionBitmask = minions.bitmask
        };

        var PrepareBucketsFence = prepareBucketsJob.Schedule(inputDeps);

        return(PrepareBucketsFence);
    }
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        int count = m_Group.CalculateEntityCount();

        if (count == 0)
        {
            return(inputDeps);
        }

        if (!translations.IsCreated)
        {
            translations = new NativeArray <float3>(count, Allocator.Persistent);
        }
        else if (translations.Length != count)
        {
            translations.Dispose();
            translations = new NativeArray <float3>(count, Allocator.Persistent);
        }

        if (!velocities.IsCreated)
        {
            velocities = new NativeArray <float3>(count, Allocator.Persistent);
        }
        else if (velocities.Length != count)
        {
            velocities.Dispose();
            velocities = new NativeArray <float3>(count, Allocator.Persistent);
        }

        CopyTranslations copyTranslationsJob = new CopyTranslations
        {
            translations    = translations,
            translationType = GetComponentTypeHandle <Translation>()
        };

        CopyVelocities copyVelocitiesJob = new CopyVelocities
        {
            velocities   = velocities,
            velocityType = GetComponentTypeHandle <Velocity>()
        };

        JobHandle copyTranslationsJobHandle = copyTranslationsJob.Schedule(m_Group, inputDeps);
        JobHandle copyVelocitiesJobHandle   = copyVelocitiesJob.Schedule(m_Group, inputDeps);
        JobHandle copyJobsHandle            = JobHandle.CombineDependencies(copyTranslationsJobHandle, copyVelocitiesJobHandle);

        if (CollisionBuckets.IsCreated)
        {
            CollisionBuckets.Dispose();
        }
        CollisionBuckets = new NativeMultiHashMap <int, int>(count, Allocator.Persistent);

        PrepareBucketsJob prepareBucketsJob = new PrepareBucketsJob
        {
            positions = translations,
            buckets   = CollisionBuckets
        };

        JobHandle prepareBucketsHandle = prepareBucketsJob.Schedule(copyJobsHandle);

        CollisionJob collisionJob = new CollisionJob
        {
            dt             = Time.DeltaTime,
            positions      = translations,
            velocities     = velocities,
            buckets        = CollisionBuckets,
            maxIterations  = m_maxIterations,
            maxClosestDone = m_maxClosestDone,
            maxForce       = m_maxForce,
            damping        = m_damping,
            radiusSqr      = m_radiusSqr,
            maxVelocity    = m_maxVelocity,
            maxVelocitySqr = m_maxVelocitySqr,
            velocityType   = GetComponentTypeHandle <Velocity>()
        };

        return(collisionJob.Schedule(m_Group, prepareBucketsHandle));
    }