Question by
jintaenate · Jul 17, 2019 at 05:02 PM ·
scripting problemdots
How to add component only 1 time in JobComponentSystem
I make code which is multiple units follow multiple enemys and if unit close to enemy, enemy will destroy and unit find another enemy.
unit has 1 component which is "Unit" and when find enemy then add "HasTarget" component to unit and add "Targeted" component to enemy
my problem is when one unit find one enemy and add"Targeted" component to enemy in same time the other unit try to add component to "Targeted" component and i get error this
ArgumentException: The component of type:Targeted has already been added to the entity.
EntityCommandBuffer was recorded in MyECS.CodeMonkey.FindTargetByJECSSystem and played back in Unity.Entities.EndSimulationEntityCommandBufferSystem.
my code is this
public class FindTargetByJECSSystem : JobComponentSystem
{
EndSimulationEntityCommandBufferSystem endSimulationEntityCommandBufferSystem;
//BeginInitializationEntityCommandBufferSystem beginInitializationEntityCommandBufferSystem;
protected override void OnCreate()
{
//beginInitializationEntityCommandBufferSystem = World.GetOrCreateSystem<BeginInitializationEntityCommandBufferSystem>();
endSimulationEntityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
base.OnCreate();
}
struct UnitEntityWithPos
{
public Entity entity;
public float3 pos;
}
struct TargetEntityWithPos
{
public Entity entity;
public float3 pos;
public bool targeted;
}
[RequireComponentTag(typeof(Unit), typeof(JECS))]
[ExcludeComponent(typeof(HasTarget))]
[BurstCompile]
struct FindTargetByJECSBurstJob : IJobForEachWithEntity<Translation>
{
[DeallocateOnJobCompletion] [ReadOnly] public NativeArray<UnitEntityWithPos> targetArray;
//public NativeArray<Entity> closestTargetEntityArray;
public NativeArray<TargetEntityWithPos> closestTargetEntityArray;
public void Execute(Entity entity, int index, ref Translation unitTranslation)
{
float3 unitPos = unitTranslation.Value;
Entity closestTargetEntity = Entity.Null;
float3 closestTargetPos = float3.zero;
for (int i = 0; i < targetArray.Length; i++)
{
//if (targetArray[i].isTargeted == true) continue;
// Cycling through all target entities
UnitEntityWithPos targetEntityWithPosition = targetArray[i];
if (closestTargetEntity == Entity.Null)
{
// No target
closestTargetEntity = targetEntityWithPosition.entity;
closestTargetPos = targetEntityWithPosition.pos;
}
else
{
if (math.distance(unitPos, targetEntityWithPosition.pos) < math.distance(unitPos, closestTargetPos))
{
// This target is closer
closestTargetEntity = targetEntityWithPosition.entity;
closestTargetPos = targetEntityWithPosition.pos;
}
}
}
closestTargetEntityArray[index] = new TargetEntityWithPos {entity = closestTargetEntity, pos = closestTargetPos };
}
}
[RequireComponentTag(typeof(Unit), typeof(JECS))]
[ExcludeComponent(typeof(HasTarget))]
struct AddcomponentJob : IJobForEachWithEntity<Translation>
{
public EntityCommandBuffer.Concurrent endCommandBuffer;
//public NativeArray<Entity> closestTargetEntityArray;
[DeallocateOnJobCompletion] public NativeArray<TargetEntityWithPos> closestTargetEntityArray;
//public ComponentDataFromEntity<Targeted> ComponentDataFromEntity;
public void Execute(Entity entity, int index, ref Translation translation)
{
//if (closestTargetEntityArray[index] != Entity.Null)
//{
// endCommandBuffer.AddComponent(index, entity, new HasTarget { targetEntity = closestTargetEntityArray[index] });
// //endCommandBuffer.AddComponent(index, closestTargetEntityArray[index], new Targeted { });
//}
if (closestTargetEntityArray[index].entity != Entity.Null)
{
if (closestTargetEntityArray[index].targeted == false)
{
endCommandBuffer.AddComponent(index, entity, new HasTarget { targetEntity = closestTargetEntityArray[index].entity, targetPos = closestTargetEntityArray[index].pos });
endCommandBuffer.AddComponent(index, closestTargetEntityArray[index].entity, new Targeted { unit = entity });
try
{
closestTargetEntityArray[index] = new TargetEntityWithPos { entity = closestTargetEntityArray[index].entity, pos = closestTargetEntityArray[index].pos, targeted = true };
}
catch (global::System.Exception)
{
}
}
}
}
}
protected override JobHandle OnUpdate(JobHandle inputDependencies)
{
EntityQuery targetQuery = GetEntityQuery(typeof(Enemy),
typeof(JECS),
ComponentType.Exclude<Targeted>(),
ComponentType.ReadOnly<Translation>());
NativeArray<Entity> targetEntityArray = targetQuery.ToEntityArray(Allocator.TempJob);
NativeArray<Translation> targetTranslationArray = targetQuery.ToComponentDataArray<Translation>(Allocator.TempJob);
NativeArray<UnitEntityWithPos> targetArray = new NativeArray<UnitEntityWithPos>(targetEntityArray.Length, Allocator.TempJob);
for (int i = 0; i < targetEntityArray.Length; i++) {
targetArray[i] = new UnitEntityWithPos
{
entity = targetEntityArray[i],
pos = targetTranslationArray[i].Value,
};
}
targetEntityArray.Dispose();
targetTranslationArray.Dispose();
//var jobHandle = new FindTargetByJECSJob
//{
// targetArray = targetArray,
// endCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent(),
//}.Schedule(this, inputDependencies);
EntityQuery unitQuery = GetEntityQuery(typeof(Unit),
typeof(JECS),
ComponentType.Exclude<HasTarget>());
//NativeArray<Entity> closestTargetEntityArray = new NativeArray<Entity>(unitQuery.CalculateLength(), Allocator.TempJob);
NativeArray<TargetEntityWithPos> closestTargetEntityArray = new NativeArray<TargetEntityWithPos>(unitQuery.CalculateLength(), Allocator.TempJob);
FindTargetByJECSBurstJob findTargetByJECSBurstJob = new FindTargetByJECSBurstJob
{
targetArray = targetArray,
closestTargetEntityArray = closestTargetEntityArray,
};
JobHandle jobHandle = findTargetByJECSBurstJob.Schedule(this, inputDependencies);
//ComponentDataFromEntity<Targeted> componentDataFromEntity = GetComponentDataFromEntity<Targeted>(false);
AddcomponentJob addcomponentJob = new AddcomponentJob
{
endCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent(),
closestTargetEntityArray = closestTargetEntityArray,
//ComponentDataFromEntity = componentDataFromEntity,
};
jobHandle = addcomponentJob.Schedule(this, jobHandle);
//closestTargetEntityArray.Dispose();
endSimulationEntityCommandBufferSystem.AddJobHandleForProducer(jobHandle);
return jobHandle;
}
}
I use unity 2019.2b Please help me to figure out this.
Comment
Your answer
Follow this Question
Related Questions
code not working help plz 2 Answers
ClientRpc not functioning 0 Answers
How to recover scripts 0 Answers
Declaring Array, HELP. 1 Answer
Problem with a Camera Follow Script 1 Answer