docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    Custom transforms

    You can customize the built-in transform system to address the specific transform functionality needs of your project. This section explains how to create a custom transform system, and uses the 2D custom transform system as a concrete example of one.

    Write groups

    Write groups enable you to override the built-in transform system with your own transforms. The built-in transform system uses write groups internally and you can configure them to make the built-in transform system ignore entities that you want to process with your custom transform system.

    More precisely, write groups exclude specific entities from queries. These queries are passed to the jobs that the built-in transform system uses. You can use write groups on certain components to exclude entities with those components from being processed by the jobs of the built-in transform system, and those entities can instead be processed by your own transform systems. For more information, refer to the documentation on write groups.

    Create a custom transform system

    The following steps outline how to create a custom transform system:

    • Substitute the LocalTransform component.
    • Create an authoring component to receive your custom transforms.
    • Replace the LocalToWorldSystem.

    Substitute the LocalTransform component

    The built-in transform system adds a LocalTransform component to each entity by default. It stores the data that represents an entity's position, rotation, and scale. There are also a variety of static helper methods defined on this component.

    To create your own custom transform system, you have to substitute the LocalTransform component with your own.

    1. Create a .cs file that defines a substitute for the built-in LocalTransform component. You can copy the built-in LocalTransform.cs file from the Entities package into your assets folder and then edit the contents. To do this, go to Packages > Entities > Unity.Transforms in your project, copy the LocalTransform.cs file, and rename it.
    2. Change the properties and methods to suit your needs. See the following example of a custom LocalTransform2D component:
    // By including LocalTransform2D in the LocalToWorld write group, entities
    // with LocalTransform2D are not processed by the standard transform system.
    [WriteGroup(typeof(LocalToWorld))]
    public struct LocalTransform2D : IComponentData
    {
        public float2 Position;
        public float Scale;
        public float Rotation;
    
        public override string ToString()
        {
            return $"Position={Position.ToString()} Rotation={Rotation.ToString()} Scale={Scale.ToString(CultureInfo.InvariantCulture)}";
        }
    
        public float4x4 ToMatrix()
        {
            quaternion rotation = quaternion.RotateZ(math.radians(Rotation));
            return float4x4.TRS(new float3(Position.xy, 0f), rotation, Scale);
        }
    }
    

    The above example modifies the built-in LocalTransform in the following ways:

    • Adds the [WriteGroup(typeof(LocalToWorld))] attribute.
    • Reduces the Position field from a float3 to a float2. This is because in the 2D sample, entities only move along the XY plane.
    • Reduces the Rotation field to a float that represents the number of degrees of rotation around the z-axis. The built-in transform system's Rotation property is a quaternion that represents a rotation in 3D space.
    • Removed all methods apart from ToMatrix and ToString. The ToMatrix method has been modified to work in 2D. The other methods aren't needed for the custom 2D transform system.
    Note

    LocalTransform2D is in the global namespace. In the above linked sample project it's in a sub-namespace to ensure that it doesn't interfere with the other samples in the same project. Both options work as long as all the files of the custom transform system are within the same namespace.

    Create an authoring component

    Each entity that your custom transform system needs to process must fulfill the following criteria:

    • Has a custom replacement for the LocalTransform component, with a different name.
    • Has a LocalToWorld component
    • If the entity has a parent entity, then it must have a Parent component that points to it.

    To meet this criteria, add an authoring component to each entity, and use transform usage flags to prevent the entity from receiving any components from the built-in transform system:

    public class Transform2DAuthoring : MonoBehaviour
    {
        class Baker : Baker<Transform2DAuthoring>
        {
            public override void Bake(Transform2DAuthoring authoring)
            {
                // Ensure that no standard transform components are added.
                var entity = GetEntity(TransformUsageFlags.ManualOverride);
                AddComponent(entity, new LocalTransform2D
                {
                    Scale = 1
                });
                AddComponent(entity, new LocalToWorld
                {
                    Value = float4x4.Scale(1)
                });
    
                var parentGO = authoring.transform.parent;
                if (parentGO != null)
                {
                    AddComponent(entity, new Parent
                    {
                        Value = GetEntity(parentGO, TransformUsageFlags.None)
                    });
                }
            }
        }
    }
    

    The above example adds the custom LocalTransform2D component and the built-in LocalToWorld component to the authoring component. If applicable, it also adds a Parent component that points to the entity's parent entity.

    Replace the LocalToWorldSystem

    The built-in LocalToWorldSystem computes the LocalToWorld matrices of root and child entities in the two corresponding jobs ComputeRootLocalToWorldJob and ComputeChildLocalToWorldJob. You need to replace this system with your own transform system.

    1. Copy the built-in LocalToWorldSystem.cs file into your assets folder and then edit the contents. To do this, go to Packages > Entities > Unity.Transforms in your project, copy the LocalToWorldSystem.cs file, and rename it.
    2. Replace all instances of the LocalTransform component with the name of your custom transform component (LocalTransform2D in the example).
    3. Remove the WithOptions(EntityQueryOptions.FilterWriteGroup); lines from the queries. If you don't remove these lines, your system excludes the corresponding entities like the built-in transform system does.
    Note

    LocalToWorldSystem uses unsafe native code so, to avoid errors, enable the Allow unsafe code property in your project. To enable this property, go to Edit > Project Settings > Player > Other Settings and select Allow unsafe code.

    Additional resources

    • Using transforms
    • Write groups overview
    • TransformUsageFlags API documentation

    Did you find this page useful? Please give it a rating:

    Thanks for rating this page!

    Report a problem on this page

    What kind of problem would you like to report?

    • This page needs code samples
    • Code samples do not work
    • Information is missing
    • Information is incorrect
    • Information is unclear or confusing
    • There is a spelling/grammar error on this page
    • Something else

    Thanks for letting us know! This page has been marked for review based on your feedback.

    If you have time, you can provide more information to help us fix the problem faster.

    Provide more information

    You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:

    You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:

    You've told us there is information missing from this page. Please tell us more about what's missing:

    You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:

    You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:

    You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:

    You've told us this page has a problem. Please tell us more about what's wrong:

    Thank you for helping to make the Unity documentation better!

    Your feedback has been submitted as a ticket for our documentation team to review.

    We are not able to reply to every ticket submitted.

    In This Article
    • Write groups
    • Create a custom transform system
      • Substitute the LocalTransform component
      • Create an authoring component
      • Replace the LocalToWorldSystem
    • Additional resources
    Back to top
    Copyright © 2025 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)