So far I enjoy using ECS very much. Recently I am trying to use jobs to optimize my code and have few concerns about them. I would appreciate if someone experienced answered my questions because it’s hard to understand whether my approach is correct based only on documentation.
When considering complicated system which works on entities grouped by SharedComponent. I use GetAllUniqueSharedComponentData then use EntityQuery to filter by this SharedComponent value and use jobs to calculate how to affect another component (almost exactly like in Boids example) the thing is sometimes calculation need to affect another shared component, so after calculation in jobs I would need to use not job to set newly calculated values for affected shared component in this case previous calculations need to be Completed. Running .Complete() on the calculation job makes it run on main thread and we lose a lot performance. How to cope with changing shared component in this scenario and how to handle dependencies? I thought about creating BlobAsset of newly computed SharedComponents and using this in job but then I still don’t know what to do about dependencies. What’s the best solution to this problem?
Considering scenario from 1. but one that affects IComponentData instead of shared component. How to handle dependencies in case of adding component with commandBuffer(in boids jobHandle is added to EntityQuery)? How to handle dependencies in case of changing component in job, calling Compete() on the end of OnUpdate seems stupid.
What does it exactly mean to add jobHandle to entityCommandBuffer, what’s the difference in case of adding jobHandle to EntityQuery?
What does it mean to use .Dispose(JobHandle) on NativeContainer?
Changing a shared component is a structural change and causes a sync point. You want to split off structural changes to separate systems that run at a dedicated “sync point”. That will typically involve passing a NativeContainer containing the desired changeset to another system.
Are you asking how do you handle the case where you want to make a structural change mid-frame and have the next system react to that change in the same frame? If so, I would first suggest to try not to do that.
You don’t add a JobHandle to an EntityCommandBuffer. You add a JobHandleForProducer to an EntityCommandBufferSystem. What that does is it tells the EntityCommandBufferSystem what jobs it needs to complete before it begins.
This is a job that Disposes the NativeContainer. It takes an input dependency and returns a JobHandle.
I have question about 1). In my 2D tile based game I implemented bitmasking system for tiles. Now it runs in few jobs first getAllNeighboursJob which collects hashes of all neighbour tiles for each Entity that have UpdateTile tag then it goes to calculateTileIndexForNeighbours which outputs index of proper mesh in SharedComponent that those tiles have. The last thing to do is set proper meshes. I can’t figure out how to make job which changes mesh in RenderMesh component of those tiles. I just tried to do it in normal code but in this case I need to call Complete() on calculateTileIndexForNeighbours which makes it run in main thread and it ruins everything. Can you think of any solution in this situation?
Only on frame that world is generated. In this frame when new tiles were spawned they come with UpdateTile and only then this system runs once to evaluate their proper meshes
Ok. Does performance really matter that much on this generation frame? If not, just complete the job and do what you need to do. Will it be fast, maybe not. But it will keep your code clean and maintainable and let you spend more time optimizing code that matters more.
Wait. If this is generation, then you should be instantiating prefabs in batch by shared component and then initializing other values in jobs rather than trying to set each shared component individually on the main thread.
When player comes to the edge of chunk new chunks are created and new Entities instantiated. After instantiating prefab default values of components are set and then comes system for bitmasking and calculates new meshes for tiles on the border of existing chunk and for all newly spawned entities.