Instantiating prefabs by respecting scale and rotation

Howdy. I have the below prefabs. They are identical except for rotation. I want to be able to instantiate these at different coordinates - I do not want to set rotation programmatically.

I have a system that spawns the correct instantiated prefab at the correct position. However, all the rotations are set to zero. If I have a CorridorX and a CorridorY at different positions, they both have a rotation of zeros, but the CorridorX entity should have a rotation of 90deg about the Y axis as can be seen in the image.

The pertinent system code snippet is below. Shouldn’t LocalTransform.FromPosition respect both scale and rotation?

EntityCommandBuffer ecb = new(Allocator.Persistent);
       
for (int index = 0; index < mazeProperties.MazeSegmentProperties.Length; index++)
{
    MazeSegmentProperties mazeSegmentProperties = mazeProperties.MazeSegmentProperties[index];

    Entity mazeSegmentPrefab = GetPrefabForMazeSegmentType(mazeSegmentProperties.SegmentType, mazeRenderConfig);
    Entity mazeSegment = ecb.Instantiate(mazeSegmentPrefab);

    float3 newPosition = new float3(
        mazeSegmentProperties.PathCell.x * mazeRenderConfig.MazeSegmentSize,
        0,
        mazeSegmentProperties.PathCell.y * mazeRenderConfig.MazeSegmentSize
    ) + mazeProperties.MazeCenter;

    ecb.SetComponent(mazeSegment, LocalTransform.FromPosition(newPosition));
    ecb.SetName(mazeSegment, mazeSegmentProperties.SegmentType.ToString());
}

Any help would be greatly appreciated. Thank you.

The LocalTransform FromXXX static methods need to construct a whole LocalTransform value, so the values that aren’t passed along are inferred to be the best default. For rotation, that’s quaternion.identity. For scale, that’s 1. If you want to preserve parts of the original entity’s LocalTransform, you might instead consider reading the rotation and scale from the prefab itself, or baking the desired rotation and scale as properties accessible to you from the point where you instantiate the entity. Either way, you would be setting a full LocalTransform value including position, rotation, and scale through the ECB all at once.

Thanks for that info. This follow-up question may sound naive. Whenever I set components, do I generally need to hydrate the entire component? If this is the case, I may need to redesign my authoring scripts to bake prefab “state” data that I can access when setting components, as you suggested. Cheers

In some cases, you can take a reference to a component in memory through a RefRW then write to the fields you want, but that doesn’t apply for cases where the entity has yet to exist, like when using an entity instantiated with EntityCommandBuffer. Methods prefixed with “Add” and “Set” populate the whole component as given, so you should indeed have the requisite data somewhere else at instantiation time.