Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question Transform + Parent issue, not sure if is a bug or not.

Discussion in 'Entity Component System' started by muntes, Feb 7, 2024.

  1. muntes

    muntes

    Joined:
    Nov 24, 2021
    Posts:
    24
    I have quite a simple setup. - Solved.

    Imagine you have a parent GameObject at -48,0,-5with some rotation and scale. I've added it in ECS at runtime.
    The parent has:
    typeof(LocalToWorld),
    typeof(LocalTransform),
    typeof(MeshLODGroupComponent),

    Then I set it's position:
    var localTransform = new LocalTransform{Position = transform.position, Rotation = transform.rotation, Scale = 1};
    entityManager.SetComponentData(entity, localTransform);

    The child is at position 0.something, 0.something, 0.something and has:
    typeof(LocalTransform),
    typeof(Parent),
    typeof(RenderMesh),
    typeof(PostTransformMatrix),
    typeof(RenderBounds),
    typeof(MeshLODComponent));

    foreach (var data in renderData){
    var description = new RenderMeshDescription(ShadowCastingMode.Off, layer: 12, receiveShadows: false);
    var renderMeshArray = new RenderMeshArray(new[] {data.material}, new[] {data.mesh});
    SetupEntities(data.entity, parent, 1);
    }

    In SetupEntities I do:
    entityManagerSetComponentData(e, new PostTransformMatrix {Value = 1f}); // Solved this is not identity.
    entityManager.SetComponentData(e, new Parent {Value = entity});
    entityManager.AddComponentData(e, new LocalToWorld());
    entityManager.SetComponentData(e, new LocalTransform { Position = localMatrix.position, Rotation = localMatrix.rotation, Scale = 1f}); // All positions are local from the gameObject transform 0.03, 0.2, -0.3
    entityManager.SetComponentData(e, new MeshLODComponent {Group = entity, LODMask = lodMask, ParentGroup = entity});

    RenderMeshUtility.AddComponents(
    e,
    entityManager,
    description,
    renderMeshArray,
    MaterialMeshInfo.FromRenderMeshArrayIndices(0, 0, (sbyte) data.meshIndex));

    The parent instantiates valid:
    upload_2024-2-8_0-53-42.png

    However the child looks like this:
    upload_2024-2-8_0-57-17.png
    The child does not render correctly due LocalToWorld.


    If I manually modify it to:
    upload_2024-2-8_0-59-28.png
    And it worked, I don't know what I miss here or what is the problem

    Any idea if I should call something to actualize the value after changing it?
     
    Last edited: Feb 8, 2024
  2. Spy-Master

    Spy-Master

    Joined:
    Aug 4, 2022
    Posts:
    846
    PostTransformMatrix gets applied in the process to generate the LocalToWorld value. Your initial value for PostTransformMatrix doesn't make much sense, you use the implicit operator that copies the value to every element, so you'd have a matrix of all 1's which is very out of place. The typical default you'd want to use for transformations is the identity matrix for the matrix type (1's along the main diagonal, 0's elsewhere), in this case float4x4.identity, to make it so the transformation has no effect on a transformed vector.
     
    muntes likes this.
  3. muntes

    muntes

    Joined:
    Nov 24, 2021
    Posts:
    24
    Thank you for the valuable info, I wrongly assumed that identity would be value 1.
    Another question regarding the scale:

    If I want to get a Parent-Child relationship and a non-uniform scale in the child.
    World.DefaultGameObjectInjectionWorld.EntityManager.AddComponentData(productEntity, new LocalTransform { Position = localMatrix.position, Rotation = localMatrix.rotation});
    World.DefaultGameObjectInjectionWorld.EntityManager.SetComponentData(productEntity, new PostTransformMatrix {Value = float4x4.Scale(localMatrix.scale) });

    Something like this this from what I read in the documentation wouldn't work. (Since LocalTransform only supports uniform scale) Any idea if I need to implement my own system for hierarchy?
     
    Last edited: Feb 8, 2024
  4. Spy-Master

    Spy-Master

    Joined:
    Aug 4, 2022
    Posts:
    846
    Answered your other post. LocalTransform.Scale isn’t set, which is a mistake.
    https://docs.unity3d.com/Packages/com.unity.entities@1.0/manual/transforms-concepts.html
    LocalTransform needs to represent a valid transformation by itself, it’s used to compute LocalToWorld as PostTransformMatrix is, when available.
     
    muntes likes this.
  5. muntes

    muntes

    Joined:
    Nov 24, 2021
    Posts:
    24
    If I let it as 1, initially after which I apply PostTransformMatrix to the new scales, all objects will have (1,1,1) scale even if in the input I provide via PostTransformMatrix to it is valid (0.1,0.2,0.5).