Some of you might already be familiar with my mega review posts I do of the entire ECS stack every once in a while. You can find the last one in my signature.
Unfortunately, it is difficult for me to review the latest releases because there are some major breaking bugs that prevent me from experimenting. At the same time, the Latios Framework has gathered more and more attention from the Unity team, and I have come to realize the massive hurdle the team faces in trying to identify all the different tech issues I’ve encountered during development.
Rather than have them always reach out to me, I’ve created a living document which I plan to update as I remember issues, run into new issues, or issues get resolved by new releases. Let’s shoot for more of the latter!
The document is grouped into three categories of severity. For convenience, I’ll copy the high-severity items as follows as I would love feedback and discussion from everyone!
Physics and NetCode are not accounted for in this wishlist. Physics is architecturally incapable of fulfilling my use cases, and the below high-severity matters have stolen my time away from experimenting with NetCode.
Subscene Imports
Subscene import workflows have significant usability issues. Because they occur in a separate Unity process, they do not use Burst, cannot easily be debugged, have limited reporting capabilities of memory leaks and the like, and many engine features are not well tested when accessed in this mode (reading audio clips crashes 10-50% of imports for me).
The Latios Framework pushes the boundaries of what can be baked, with new and exciting high-level features. But that only works when baking itself works, which has been a constant pain point.
Currently I cannot use Pre.47 because of some weird serialization bug.
Transforms V2
Transforms V1 in 0.51 were heavy, but intuitive. There were clear rules as to when things were and were not updated. And at the end, everything funneled into LocalToWorld.
Now in Transforms V2, we have TransformAspect which tries to pseudo-synchronize local and world transforms, except sometimes things use or only update LocalToWorld instead, and sometimes they use both but only LocalToWorld is correct, but LocalToWorld isn’t synchronized as frequently. But then WorldTransform can only represent uniform scale, which is extremely limiting. So sometimes TransformAspect is correct, and sometimes it is completely wrong. And trying to replace it in order to extend transforms is impossible because all it takes is one asset to try using TransformAspect directly in order screw everything up.
Then there’s the performance aspects. Root entities have both local and world transforms, along with LocalToWorld, which requires 128 bytes total, enough to ensure that there will never be a full 128 entities in a chunk. LocalToWorld itself is problematic. It’s Rotation property gives incorrect values if there is non-uniform scale baked in the matrix. And why does the bottom row of the matrix even exist if Entities Graphics is going to ignore it?
Transforms V2 is a complete mess, and I ended up resorting to writing my own transform solution in Latios Framework just to have some sanity. But now users are concerned about compatibility with other assets. Please clean up this mess!
IAspect Feature Gaps
Aspect lookups are not only difficult to discover, but using them in IJobEntity requires a ton of boilerplate compared to ComponentLookup. There’s no SystemAPI methods for getting auto-cached handles or lookups.
For performance reasons, the Latios Framework is starting to have really complicated sets of components. A common example is that the Latios Framework triple-buffers animation data so that things like motion vectors and inertial blending can be easily evaluated. Yet rather than copy current to previous and previous to two-ago, these buffers rely on control components to rotate the roles. This behavior should be somewhat abstracted from the user, and IAspect solves this case beautifully. Unfortunately, users struggle to get such aspects from random entities in jobs.
SystemAPI Extensibility
The fact that we can’t use SystemAPI in static methods makes it extremely difficult to build extensions and common patterns. For example, I have a static method Physics.BuildCollisionLayer() that needs to schedule 5 jobs in sequence. While there are several variants, one variant requires the first job to perform chunk iteration. Securing such type handles is extremely problematic. The user has to manually cache and update a struct containing those handles, because this method can’t rely on SystemAPI. That’s a lot of unnecessary boilerplate burdened directly on the user.
Burst Generic Jobs Can’t Be Scheduled in Burst
Psyshock uses generic jobs in Physics.FindPairs() using a pattern that allows Burst to detect and compile the jobs both in the Editor and in builds without having to explicitly register the generic types with attributes. Unfortunately, the ILPP can’t pick up on it and patch these jobs to be Burst-schedulable. There should not be a discrepancy!
Generics and Codegen Accessibility
The previous three items could be potentially solved if the Latios Framework could easily inject itself into the codegen process to add support for these things. Unfortunately, codegen is very inaccessible to most people, and there is no certainty regarding how long such a solution would even last. At the same time, regressions surrounding generics keep popping up, and if they continue, they might prevent the Latios Framework from being able to leverage new versions of ECS, unless codegen became accessible. There are a ton of ways I would love to leverage codegen, so if you know things about this and would like to better understand the specific potential use cases or just want to help me start using them, please reach out to me via Unity forums PMs or Discord!
Skinned Mesh Rendering
The whole Skinned Mesh Rendering solution in Entities Graphics is problematic. It generates GC every frame, it doesn’t scale, and even the public API types of SkinMatrix and BlendShapeWeight fundamentally prevent more efficient algorithms like the ones Kinemation uses. I’ve been told numerous times that the skinned mesh rendering design is “experimental”. If that’s the case, please put that functionality behind an experimental scripting define so that you don’t have to support these flawed APIs long-term when you eventually get around to a better solution.
I’m only asking this because I have a sliver of hope that Entities.Graphics may adopt a design closer to Kinemation in which case I can delegate some features of Kinemation to the official package.