- Home /
How can I get a component data from an entity inside a JobComponentSystem?
I had this system as an ECS, now I am trying to convert it to a job system. My issue is I was using
World.DefaultGameObjectInjectionWorld.EntityManager.GetComponentData<Translation>( hasTarget.targetEntity );
But this does not work inside of JobSystem. I am new to this and would appreciate any help. Since this job runs on multiple entities, I am unsure of how to pass multiple Translation data to the job and I dont understand how the job will know which Translation data corresponds to each entity.
public class UnitMoveToTargetJobSystem : JobComponentSystem
{
//[ RequireComponentTag( typeof( HasTarget ) ) ]
[ ExcludeComponent( typeof( InCombat ) ) ]
[ BurstCompile ]
private struct MoveToTargetJob : IJobForEachWithEntity<HasTarget , Translation>
{
public EntityCommandBuffer.Concurrent entityCommandBuffer;
public float dt;
public bool entityHasTarget;
public void Execute( Entity unitEntity , int index , ref HasTarget hasTarget , ref Translation translation )
{
if ( hasTarget.targetEntity != null )
{
Translation targetTranslation = World.DefaultGameObjectInjectionWorld.EntityManager.GetComponentData<Translation>( hasTarget.targetEntity );
float3 targetDirection = math.normalize( targetTranslation.Value - translation.Value );
float moveSpeed = 8f;
translation.Value += targetDirection * moveSpeed * dt;
if ( math.distance( translation.Value , targetTranslation.Value ) <= 0.3f )
{
entityCommandBuffer.AddComponent( index , unitEntity , new InCombat { enemy = hasTarget.targetEntity } );
entityCommandBuffer.RemoveComponent( index , unitEntity , typeof( HasTarget ) );
//PostUpdateCommands.AddComponent( unitEntity , new InCombat { enemy = hasTarget.targetEntity } );
//PostUpdateCommands.RemoveComponent( unitEntity , typeof( HasTarget ) );
}
}
else
{
entityCommandBuffer.RemoveComponent( index , unitEntity , typeof( HasTarget ) );
//PostUpdateCommands.RemoveComponent( unitEntity , typeof( HasTarget ) );
}
}
}
private EndSimulationEntityCommandBufferSystem endSimulationEntityCommandBufferSystem;
protected override void OnCreate()
{
endSimulationEntityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
base.OnCreate();
}
protected override JobHandle OnUpdate( JobHandle inputDeps )
{
MoveToTargetJob moveToTargetJob = new MoveToTargetJob
{
entityCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent() ,
dt = Time.DeltaTime
};
JobHandle jobHandle = moveToTargetJob.Schedule( this , inputDeps );
endSimulationEntityCommandBufferSystem.AddJobHandleForProducer( jobHandle );
return jobHandle;
}
}
Answer by mentics · Feb 08, 2020 at 02:44 PM
One solution is to use ComponentDataFromEntity as demonstrated in the answer to this question. That allows you to create a lookup for a component for all the entities. In your case, you would probably want [ReadOnly] public ComponentDataFromEntity<LocalToWorld> localToWorldFromEntityToFollow;
as a field and initialize it to localToWorldFromEntityToFollow = GetComponentDataFromEntity<LocalToWorld>(true)
Your answer
Follow this Question
Related Questions
Threaded procedural animation 0 Answers
How do I assign a public variable inside a JobComponentSystem(ECS)? 1 Answer
Multi threading problem ! 2 Answers
ECS: How to access to separate "groups" of same-archetype entities? 0 Answers
"...can only be called from the main thread" - MultiThreading 1 Answer