I was looking into Unity’s default running systems, trying to find (generic) ways to speed up ‘my’ usage of those systems.
Whenever I’m moving an entity, I attach a Heading-Component to it. Thus, all of my Entities which do not have a Heading do not move. However, they are still processed by a lot of Unity’s systems, racking up CPU-time.
I saw that the RenderBoundsUpdateSystem had a subtractivecomponent used for filtering objects which do not move (Frozen), and thus, I added a system which adds the Frozen-Component to any of my static Entities (at the very end of the frame).
However, the TransformSystems (particularly EndFrameTRSToLocalToWorldSys) and the InitializationSystems (particularly CopyInitialTransformFromGO) don’t seem to make use of this Component, nor use any change-filter. As a result, all of my Entities are still being processed by these systems every frame (doing the exact same work).
Is this intended behaviour? How would one go about dealing with static (as in non-moving) Entities?
For static objects you should use Static component, Frozen is internal component which adds after handle Static.
namespace Unity.Transforms
{
/// <summary>
/// When added, TransformSystem will process transform compomnnts once
/// to update LocalToWorld. Once that is resolved, the Frozen
/// component will be added and LocalToWorld will no longer be updated.
/// </summary>
public struct Static : IComponentData
{
}
}
Adding the static-component to my ArcheTypes does not seem to run any Systems (and thus no Frozen-Component appears)
Do the systems check for change (addition)?
Originally it was actually created from the transform system but as you point out isn’t used anymore, and pretty much only used on legacy or hybrid systems.
Look into the static component and the StaticOptimizeEntity monobehaviour for entity conversion.
Not removed (yet) and still uses in
EntitySceneOptimization (Unity.Entities.Streaming)
Also for LOD’s, RenderBoundsUpdateSystem, FrozenStaticRendererSystem in presentation system group as subtractive component (may be rudiment) (Unity.Rendering).
Also they added FrozenRenderSceneTag which uses in may places in v2 renderer for optimization sub scenes rendering I guess.
Yeah I’m currently mainly using Frozen to skip the RenderBoundsUpdateSystem, as most of my entities hardly ever move.
Would love to skip the TRSToLtW etc. as well (as it’s currently just copying the same values over & over)
Sorry I meant to say removed in the future. At the very least what it does now is a lot different than what it used to do and doesn’t seem to be something you should use directly anymore because of this.
I have the same problem with TRSToLocalToWorld (it takes up ~8ms every frame on a scene that only contains lots of entities that don’t move) - is the conclusion here that for now there’s no way to prevent that? Or is there some system I can use that will add the FrozenRenderSceneTag for me? This post suggests it might have something to do with SubScenes, but my entities are created at runtime so I don’t think that’s useful to me.
This looks promising, though I got distracted with other experiments today and didn’t get a chance to try it out. I notice that RenderMeshSystemV2 doesn’t use the WriteGroup attribute, though, so I wonder if it will work in this case? Hopefully I’ll get to try it tomorrow!
What I actually ended up doing for now is making a job that removes the Translation, Rotation and Scale components from my “static” entities after the first frame. This prevents RenderMeshSystemV2 from trying to update LocalToWorld more than once.
It feels a little hacky but I think it’s likely that this is a more correct solution for me, because leaving the components around but preventing them from updating LocalToWorld might cause confusion in the future. If someone has a better suggestion for achieving a similar goal (maybe I should never be adding the TRS components in the first place, and there’s a way to set LocalToWorld directly??) then I’d love to hear it!
My entities are created manually at runtime, no conversion (so I can’t use the StaticOptimizeEntity MonoBehaviour component suggestion from earlier in the thread). I am purposely adding the Translation and Rotation components initially, but only because I don’t know any other way to make sure they end up rendering at the right place!
Whats the update on this? I have ~10,000+ unique meshes I am creating and the update seems to take 1000ms to run, therefore unusable. I tried to add the component FrozenRenderSceneTag - but nothing renders when that is added. I even tried adding it a frame after I add my mesh, and still nothing…
From what I read the only other solution is to remove the LocalToWorld component after its been placed? That does sound quite hacky…