it could be that RequireForUpdate does not support SetFilterChanged. do you have entities in that query if you remove the filter?
for that system specifically, you don’t want a change filter. if your MovementComponent does not change but its value is != 0, you may want to translate at a constant speed each frame. also filtering is chunk-based, it may not result in what you expect. if you want movement to be one-shot, either remove the component or set the value to 0
Yes, entity with MovementComponent and PlayerComponent appears in debugger
I want to change MovementComponent.Movement when button pressed by one system. If MovementComponent.Movement changed move entity and set value back to zero. I left only one system and put [ReadOnly] just to make sure MovementCompoentn.Movement doesn’t change and understand how EntityQuery works
“set value back to zero” is a change, therefore you access as writable in your other system, therefore the chunk is processed again in the next frame
also:
you could just change the translation in the button press, no need for an additional component.
if you want the additional component, you can add it in the button press and remove it after it is processed (either via ECB or EntityManager.RemoveComponent<T>(query) in the other system). I don’t think you click most of your entities each frame…
I add InputSystem to clear things. If I change MovementComponent value, entityQuery updates and update entity value. But it still runs if no entity available
public class MovementComponentHolder : MonoBehaviour, IConvertGameObjectToEntity
{
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
dstManager.AddComponentData(entity, new PlayerComponent());
dstManager.AddComponentData(entity, new MovementComponent());
}
}
public struct MovementComponent : IComponentData
{
public float3 Movement;
}
public struct PlayerComponent : IComponentData { }
public class MovementSystem : JobComponentSystem
{
EntityQuery entityQuery;
protected override void OnCreate()
{
entityQuery = GetEntityQuery(typeof(Translation), (typeof(MovementComponent)));
entityQuery.SetFilterChanged(typeof(MovementComponent));
RequireForUpdate(entityQuery);
}
[BurstCompile]
struct MovementJob : IJobForEach<Translation, MovementComponent>
{
public void Execute(ref Translation translation, ref MovementComponent movementComponent)
{
translation.Value = translation.Value + movementComponent.Movement;
movementComponent.Movement = float3.zero;
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
var jobHandle = new MovementJob().Schedule(entityQuery, inputDeps);
return jobHandle;
}
}
public class InputSystem : ComponentSystem
{
EntityQuery entityQuery;
protected override void OnCreate()
{
entityQuery = GetEntityQuery(ComponentType.ReadOnly<PlayerComponent>(), typeof(MovementComponent));
RequireForUpdate(entityQuery);
}
[BurstCompile]
struct MovementInputJob : IJobForEach<MovementComponent>
{
public float3 Movement;
public void Execute(ref MovementComponent movement)
{
movement.Movement = Movement;
}
}
protected override void OnUpdate()
{
bool isMovementPressed = Input.GetKeyUp(KeyCode.Space);
if (isMovementPressed)
{
var movementInputJobHandle = new MovementInputJob() { Movement = new float3(1, 0, 0) }.Schedule(entityQuery);
movementInputJobHandle.Complete();
}
}
}
“writing” here means you are declaring it as non-readonly. the engine doesn’t care if you are actually writing to it. also it only tracks per-chunk.
if you remove the filtering, does it show the matching chunk in the debugger?
can you verify if the job actually runs and for which entities? (you can Debug.Log in non-burst jobs. you can also increment a NativeCounter and log that post-completion)
I don’t get it. EntityQuery is empty, but system still runs. But if I change value entity adds to EntityQuery and get changed in system. After it EntityQuery is empty again
Yes, it shows entity
I have only one entity in scene. I print number of entites in EntityQuery and in changes correctly
what is happening is that RFU ignores the change filter, because it involves iterating all chunks (therefore it can be done directly in the job where it will not call execute) (see EntityQuery.IsEmptyIgnoreFilter vs ComponentChunkIterator.CalculateEntityCount)
(I still don’t think filtering is what you want to do in your case. it is more clear to add/remove the component (or a tag) if you don’t want to translate directly in the input system)
It executes only when value changes and IsEmptyIgnoreFilter never retuns true.
Well, I will simply remove component after all systems uses value. Actually, I tried to understand how filtering affects systems, but I leave it for now. If I find what is wrong, I will post it. Thanks for answers