When looking through tutorials (of course older tutorials because I have not found any yet which are updated past ECS 1.0 for triggers), when using a ITriggerEventsJob and getting components from the entities in the trigger they say to use ComponentDataFromEntity. After 1.0, ComponentDataFromEntity is obsolete and Unity says to use ComponentLookup instead. The problem I have here is how to pass in ComponentLookups into the Job struct, when ComponentLookup must be marked as [ReadOnly]. Is there a different way to get Components from Entities here? Or is this the right method, but I need to do something special to give the jobs the ComponentLookups?
Here is the code that I am using:
[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
[UpdateAfter(typeof(PhysicsSystemGroup))]
public partial class EnemyTriggerEventSystem : SystemBase
{
//private SimulationSingleton simulationSingleton;
protected override void OnUpdate()
{
var triggerJob = new TriggerJob()
{
meleeComponentEntities = GetComponentLookup<MeleeAttackComponent>(true),
healthEntities = GetComponentLookup<HealthComponent>(true),
};
var jobHandle = triggerJob.Schedule(SystemAPI.GetSingleton<SimulationSingleton>(), Dependency);
jobHandle.Complete();
}
public partial struct TriggerJob : ITriggerEventsJob
{
[ReadOnly] public ComponentLookup<MeleeAttackComponent> meleeComponentEntities;
[ReadOnly] public ComponentLookup<HealthComponent> healthEntities;
public void Execute(TriggerEvent triggerEvent)
{
if (meleeComponentEntities.HasComponent(triggerEvent.EntityA) && healthEntities.HasComponent(triggerEvent.EntityB))
{
var melee = meleeComponentEntities.GetRefRO(triggerEvent.EntityA);
var health = healthEntities.GetRefRW(triggerEvent.EntityB);
if (melee.ValueRO.team == health.ValueRO.team)
return;
health.ValueRW.value -= melee.ValueRO.damage;
}
if (meleeComponentEntities.HasComponent(triggerEvent.EntityB) && healthEntities.HasComponent(triggerEvent.EntityB))
{
var melee = meleeComponentEntities.GetRefRO(triggerEvent.EntityB);
var health = healthEntities.GetRefRW(triggerEvent.EntityA);
if (melee.ValueRO.team == health.ValueRO.team)
return;
health.ValueRW.value -= melee.ValueRO.damage;
}
}
}
}
Here is the error if I don’t use the [ReadOnly] tag:
InvalidOperationException: The ComponentLookup
riggerJob.UserJobData.meleeComponentEntities must be marked [ReadOnly] in the job EnemyTriggerEventSystem:TriggerJob, because the container itself is marked read only.
And here is the error if I do use the [ReadOnly] tag:
InvalidOperationException: The ComponentLookup has been declared as [ReadOnly] in the job, but you are writing to it.