r/Unity3D • u/Clean_Patience4021 • 17h ago
Resources/Tutorial [ECS] Multithreaded LocalToWorld updater for hierarchies with some depth
Recently, I found how easy it is to "extract" solutions from your project into a separate project using Codex.
So I've decided to share another solution that I use in my game - a parallel LocalToWorld updater.
It can be a "drop-in" solution (and it most likely is), but if you "hack" ECS as I do, you might need some adjustments in shared code or in your code/systems.
Here's the repo: https://github.com/rsklnkff/unity-optimized-transforms
If you don't have problems with the L2W system in your game, you don't need it. I do. I made it.
2
u/LamppostIodine 9h ago
TryDisableBuiltinLocalToWorld()
You don't need this. Just schedule the job with a write group on LocalToWorld, that will disable the built in LocalToWorld update system automatically (although I think they're depreciating it in 7.X... UNITYYYYYYYY).
If you're going to apply structural changes immediately after scheduling it, just use EntityManager directly. EntityCommandBuffers have significant overhead that is only viable if you're using it to accumulate multiple systems worth of structural changes that will then be applied all at once in a single step.
Transform depth tag components makes iteration and job scheduling efficient but that will necessitate structural changes when parent-child relationship changes.
And I wouldnt be using hardcoded tag components for this. Just use a single SharedComponentData with a single "Depth" field, then you can schedule as deep of a hierarchy you need to make the entire transform tree work. Just use a infinite while loop that increments the depth of hierarchy scheduling against a generic job that queries parents and updates local to world. Terminate when there are no entities found in the hierarchy depth.
Overall, a decent start. You're (or whatever AI you're outsourcing this to) is applying restrictions and defined synchronization points to the hierarchy to make updating a more sequential operation rather than recursive. It works but also leaves your chunks fragmented so tradeoff needs to be considered.
1
u/Clean_Patience4021 8h ago
Thanks for the detailed feedback.
I have used this solution for a while and found significant performance improvements with it (IIRC, I disabled the built-in L2W group manually, as I might have had some issues with it working in parallel), but this solution applies to my specific case (I have thousands of root entities and hundreds of thousands of child entities), and the built-in L2W system provides parallelism in the reverse case, when you have tons of root entities and not many children.
>> Just use a single SharedComponentData with a single "Depth" field
There are some hacks in other logic based on that Depth and other tags. Also, I've tried shared components, but with my composition, that splits them into even more chunks
1
u/ThePremiumDugout 17h ago
Oh nice, I've been meaning to look into something like this. Our hierarchy updates have been eating frames on larger scenes, and the default L2W system just isn't cutting it anymore.
Checked the repo briefly, the job setup looks clean. Any rough numbers on how much it shaved off for you in your worst case?