Hey all, I’m currently trying to figure out how it’s possible to see if a component exists in a job when there is no EntityManager available.
In any IJob struct I pass in a CommandBuffer for adding or removing components, but I don’t see a way to check if a component exists on an entity. This currently makes it difficult when using “Any” on a query filter. Additionally when trying to adopt the approach of SystemStateComponents (SystemStateComponents | Package Manager UI website) a lot of what it recommends for checking the adding or removal of components doesn’t seem obvious to me unless I use a plain ComponentSystem. I’m wondering if I’m just missing something? Any help would be great, thanks!
ComponentDataFromEntity<Test> TestComponents ; // Set with TestComponents = GetComponentDataFromEntity<Test>(bool isReadonly);
if (TestComponents.Exists(entity))
{
}
I gave it a go, but the other odd side effect is I’m getting this error:
This seems to happen on getting the NativeArray:
var chunkQueueAbilities = chunk.GetNativeArray(QueueAbilityType);
The component exists on the entity in the debugger though…this may be beyond this issue, even when putting it in the All part of the query I get this error.
And to clarify I’m using IJobChunk for all of this.
Additionally I seem to get an error if I don’t use [ReadOnly] on my job properties, even when readonly is set to false when calling GetArchetypeChunkComponentType, I’m going to post my source file, if it helps. This issue seems buggy to me almost.
using Sellsword.Components;
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
namespace Sellsword.Systems
{
public class UpdateAbilityQueueSystem : JobComponentSystem
{
private EntityQuery m_Group;
protected override void OnCreate()
{
m_Group = GetEntityQuery(new EntityQueryDesc
{
All = new ComponentType[] { typeof(Character), typeof(InstantAbility), typeof(ChargeAbility) },
Any = new ComponentType[] { typeof(QueueAbility) }
});
}
//[BurstCompile]
struct UpdateAbilityQueueSystemJob : IJobChunk
{
[ReadOnly] public ArchetypeChunkEntityType EntityType;
public ArchetypeChunkComponentType<QueueAbility> QueueAbilityType; // <-- fails without [ReadOnly]
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
{
var entities = chunk.GetNativeArray(EntityType);
NativeArray<QueueAbility> chunkQueueAbilities = new NativeArray<QueueAbility>();
if (chunk.Has<QueueAbility>(QueueAbilityType))
{
chunkQueueAbilities = chunk.GetNativeArray(QueueAbilityType); // <--- Error.
}
for (int i = 0; i < chunk.Count; i++)
{
var entity = entities[i];
var queue = chunkQueueAbilities[i];
}
}
}
protected override JobHandle OnUpdate(JobHandle inputDependencies)
{
var entityType = GetArchetypeChunkEntityType();
var queueAbilityType = GetArchetypeChunkComponentType<QueueAbility>(false);
var job = new UpdateAbilityQueueSystemJob()
{
EntityType = entityType,
QueueAbilityType = queueAbilityType,
};
return job.Schedule(m_Group, inputDependencies);
}
}
}
I found the chunk.Has function, but you can see even if the has passes I get the zero-sized IComponentData error, in addition to the readonly errors.
I remember somebody said that’s because when using the tagComponent, the memory layout cost 0 overhead, so you have to make it ReadOnly.
so the problem might be here var queueAbilityType = GetArchetypeChunkComponentType<QueueAbility>(true);
I’m not very sure though…
Thanks eterlan, that does clarify things. I suppose I just won’t use GetNativeArray on the component until I fill it with data. This is a bit annoying though as chunk.has will evaluate as true for all the entities in a chunk when using Any, unless as stated, I use Exists in ComponentDataFromEntity, which all starts to make things quite unwieldly in an IJobChunk.