I cannot figure out when i should use the IJobChunk workflow or the Entities.ForEach workflow when iterating over entities in a system. The reason that this concerns me, is that i see many examples employing both. I tried finding an answer in the ECS manual but all i found is this, which is quite vague. The one clear point it makes is that optional components can be processed with the IJobChunk workflow. This is not something i have seen used though.
Just wanted to add a personal opinion that I think IJobChunk are great when learning - Entities.ForEach feels a lot less magical after getting comfortable with them. In particular things like how you pass a CDFE to a static method and how it relates to GetComponent<> in SystemBase. Also, like DreamingImLatios hinted at - optional components - when you want to branch logic on e.g. the presence of a Tag and are in the hot path and donât want to duplicate code to solve it. As IJobChunk iterates the chunks (rather than entities) you can branch or early out on the chunk level.
They are a lot more verbose so I wouldnât recommend you write a lot of them but I think they are a good fundamental part of Unityâs ECS to understand - itâs what the Entities.ForEach compiles to. Good luck
I can chime in to say that we use IJobChunk for most of our jobs. Here are the main reasons:
You can schedule more than one IJobChunk per system update. Thatâs not supported (or at least didnât used to be supported) for Entities.ForEach.
we make good use of generic jobs in our code. They live in a shared namespace, and explicit instances of them are scheduled by multiple systems. Thatâs not possible with Entities.ForEach.
IJobChunk gives you lower level control over how a job functions. Unity does a good job of translating Entities.ForEach jobs into high performance jobs for you. But working directly at the IJobChunk level can give you more awareness and peace of mind. Personal preference, this one.
I believe there may still be some equivalent things you canât do in Entities.ForEach, like decorating job variables with edge-case attributes. But time has passed since I ran into that, so maybe that part has changed.
itâs funny that people have described them as a learning tool to use at the beginning. Because Iâve seen them as the opposite - Entities.ForEach is the one to use early on, since it does a lot of things magically. It tries to be more convenient, but sacrifices some control, visibility, and features to get there.
Then when you want to do something ForEach doesnât support, you drop down to a lower level and start writing more IJobChunks, since they give you more visibility and control.
In my opinion, the lambda part of ForEach was a good idea for a way to make writing jobs more convenient. But in order for ForEach jobs to capture variables, you end up needing to write unintuitive code, like define them above the ForEach declaration without actually doing anything with them until later. I donât think itâs a convention you would design into your code for any other reason, other than to make the capturing work.
And personally, I think that variables defined in an IJob or IJobChunk struct are much more readable than stacking a dozen â.With()â functions as part of the ForEach syntax. Personal opinion there.
Sometimes I wonder how much time you have⌠I wish I had the time to do things like these as well. Iâve been spending a year on a mesh builder that if given a full-time treatment would have been finished already. However, I have a 9-5 that takes up more than enough of my time.
Unless you are referring to the framework as a whole? In that case, link to the forum thread is in my signature.
Also, I did a dig through my public repos and this is actually my only usage of IJobChunk currently in those. I have one case where I use IJobFor on a NativeArray using DynamicComponentTypeHandles, but otherwise I use Entities.ForEach way more often.
You may want to verify (or hopefully someone else where can verify) that my claim is even true anymore.
but when Entities.ForEach was first introduced, I believe you could only schedule one of them in a systemâs update function. At the time, if you needed to schedule several, sequential jobs from a single system, Unity was advising people to use IJobChunk and other explicit job structs.
If youâre able to use multiple, sequential Entities.ForEach calls from a single system Update function, then maybe this limitation has been removed. My apologies - I canât test this at the moment or Iâd verify it as well.
I donât ever remember any requirement of a single ForEach, could be wrong. Either way, no there is no limitation on how many ForEachs. AFAIK ForEach gets converted into an IJobChunk during codegen.
If anything Entities.ForEach lets you ignore job handles most of the time. I suggest you read up on it.
Thank you @Sarkahn_1 ! I was referencing needing to pass data in and out of these .ForEach()'s (like this ) where you need to be mindful of when jobs are completed and what data you reference.
(Get)ComponentDataFromEntity - what backs the Has/Get/SetComponent calls inside a SystemBase - sometimes useful for example to capture and pass to a static method within the lambda when working with Entities.ForEach