docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    A system reads stale transform data

    This scenario demonstrates a common problem with reading a position, and how to use the Systems window to identify and fix it. A system reads transform data from LocalToWorld and gets the previous frame's value, instead of the current one.

    Symptoms

    A system in your project reads the world-space position of moving entities. The values it reads seem wrong or one frame behind. An example of such a system:

    public partial struct AnchorPositionSystem : ISystem
    {
        public void OnUpdate(ref SystemState state)
        {
            foreach (var localToWorld in
                SystemAPI.Query<RefRO<LocalToWorld>>())
            {
                // If TransformSystemGroup hasn't updated yet,
                // this is the previous frame's position
                float3 worldPos = localToWorld.ValueRO.Position;
                // ... use worldPos for calculations
            }
        }
    }
    

    Cause

    The system doesn't declare its update order explicitly, or the declared order is wrong.

    Unity calculates the LocalToWorld data in LocalToWorldSystem, which updates inside the TransformSystemGroup. A system that doesn't declare a group updates in the SimulationSystemGroup, and so does TransformSystemGroup. The system in this example doesn't declare an execution order relative to TransformSystemGroup, so Unity chooses one. Unity might place your system before or after the transform systems. If your system runs first, it reads the LocalToWorld values that Unity calculated on the previous frame.

    Diagnosis

    To check whether the issue is caused by the incorrect execution order:

    1. Open the Systems window: select Window > Entities > Systems.

    2. Expand the Simulation System Group and find your system and Transform System Group. Systems higher in the list update first.

      A custom system that executes before Transform System Group

    3. If your system appears above Transform System Group, it reads the previous frame's values.

    4. Select your system and check the Scheduling column. If no label appears next to Transform System Group, then your system doesn't set an order explicitly, and the position you see is the one Unity chose.

    Note

    Without an explicit order attribute, Unity might place your system below Transform System Group, but it's not guaranteed to remain there. Renaming your system, moving it to another namespace, or adding an unrelated system to the same group can move it above the transform systems.

    Resolution

    The example system only reads transform data, so it can update after the transform systems. Add the UpdateAfter attribute to it:

    [UpdateAfter(typeof(TransformSystemGroup))]
    public partial struct AnchorPositionSystemFixed : ISystem
    {
        public void OnUpdate(ref SystemState state)
        {
            foreach (var localToWorld in
                SystemAPI.Query<RefRO<LocalToWorld>>())
            {
                // TransformSystemGroup has updated at this point,
                // so this is this frame's current position
                float3 worldPos = localToWorld.ValueRO.Position;
                // ... use worldPos for calculations
            }
        }
    }
    

    To check the fix, open the Systems window again.

    A custom system with execution order attribute that executes after Transform System Group

    The system now appears below Transform System Group, and the Scheduling column displays an UpdateAfter label next to Transform System Group when the system is selected.

    After Transform System Group updates, LocalToWorld reflects this frame's transforms, unless a later system modifies them. It can also contain offsets that Unity applies for graphical smoothing. If you need an exact world transform for simulation purposes rather than a fast approximation, use TransformHelpers.ComputeWorldTransformMatrix. For more information, refer to Transform concepts.

    Note

    Don't use this solution for a system that writes LocalTransform. Such a system has to keep updating before Transform System Group, otherwise the transforms it writes don't reach LocalToWorld until the next frame. To read an exact world position from such a system, use ComputeWorldTransformMatrix. For more information, refer to Transform helper overview.

    Additional resources

    • Systems window reference
    • System groups
    • Transform concepts
    In This Article
    Back to top
    Copyright © 2026 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)