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

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:

However the child looks like this:


The child does not render correctly due LocalToWorld.

If I manually modify it to:
9630494--1368185--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?

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.

1 Like

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?

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.

1 Like

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).