Using SubScene as Prefab loader

Is anyone successful in using SubScenes as a form of loading prefabs?

I can only set it up for simple entities without any hierarchy and putting a Prefab component on them manually.

GameObjects in the SubScene which have many renderers and childs aren’t converted into entities and Prefab + LinkedEntityGroup components.

Is there an easy way to add these components? There are so many utility methods but I can’t seem to find the right one.

I am using a subscene for prefab loading and followed this thread for setting up parent-child relationsionships which discusses setting it all up manually.

Although, I didn’t have to add the Prefab component manually, Unity appeared to have added that automatically.

Thanks for the answer. I had hopes is wasn’t that complicated. Biggest problem is that I don’t know how to get Convert calls on children (without putting a dedicated IConvertGameObjectToEntity component on it) to get their entity and to find out if they are part of a prefab and then add Prefab/LinkedEntityGroup.

Looks quite complicated for something that, dare I say, is that integral to the current workflow.

Say, would you mind sharing your code?

Heh, I actually deleted this and took another approach in the end as it was for a custom translation gizmo that was going to have scaling colliders, which DOTs physics doesn’t support in a nice way. I just wrote an IMGUI style gizmo instead of jumping through the various DOTs hoops.

Here’s the code anyway, though I’m not sure how helpful it will be. There was no embedded prefabs, only the root object was a prefab. The SetParent is in the previous linked thread.

public class TranslationGizmoAuthoring : MonoBehaviour, IConvertGameObjectToEntity
{
  public GameObject x_axis;
  public GameObject y_axis;
  public GameObject z_axis;
  public GameObject xz_grab_plane;
  public GameObject xy_grab_plane;
  public GameObject zy_grab_plane;

  public void Convert (Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
  {
    // Children
    Entity x_axis_c = conversionSystem.GetPrimaryEntity (x_axis);
    Entity y_axis_c = conversionSystem.GetPrimaryEntity (y_axis);
    Entity z_axis_c = conversionSystem.GetPrimaryEntity (z_axis);
    Entity xz_grab_plane_c = conversionSystem.GetPrimaryEntity (xz_grab_plane);
    Entity xy_grab_plane_c = conversionSystem.GetPrimaryEntity (xy_grab_plane);
    Entity zy_grab_plane_c = conversionSystem.GetPrimaryEntity (zy_grab_plane);

    dstManager.AddComponentData (entity, new TranslationGizmoParent
    {
      x_axis = x_axis_c,
      y_axis = y_axis_c,
      z_axis = z_axis_c,
      xz_grab_plane = xz_grab_plane_c,
      xy_grab_plane = xy_grab_plane_c,
      zy_grab_plane = zy_grab_plane_c,
    });

    dstManager.AddComponentData (entity, new Unity.Transforms.Scale ());

    var buffer = dstManager.AddBuffer<LinkedEntityGroup> (entity);
    buffer.Add (entity);
    buffer.Add (x_axis_c);
    buffer.Add (y_axis_c);
    buffer.Add (z_axis_c);
    buffer.Add (xz_grab_plane_c);
    buffer.Add (xy_grab_plane_c);
    buffer.Add (zy_grab_plane_c);

    TransformExtensions.SetParent (dstManager, entity, x_axis_c, x_axis.transform.localPosition, x_axis.transform.localRotation, x_axis.transform.localScale.x);
    TransformExtensions.SetParent (dstManager, entity, y_axis_c, y_axis.transform.localPosition, y_axis.transform.localRotation, y_axis.transform.localScale.x);
    TransformExtensions.SetParent (dstManager, entity, z_axis_c, z_axis.transform.localPosition, z_axis.transform.localRotation, z_axis.transform.localScale.x);
    TransformExtensions.SetParent (dstManager, entity, xz_grab_plane_c, xz_grab_plane.transform.localPosition, xz_grab_plane.transform.localRotation, xz_grab_plane.transform.localScale.x);
    TransformExtensions.SetParent (dstManager, entity, xy_grab_plane_c, xy_grab_plane.transform.localPosition, xy_grab_plane.transform.localRotation, xy_grab_plane.transform.localScale.x);
    TransformExtensions.SetParent (dstManager, entity, zy_grab_plane_c, zy_grab_plane.transform.localPosition, zy_grab_plane.transform.localRotation, zy_grab_plane.transform.localScale.x);
  }
}

I’ve put this together but I’m still missing some functionality.

using Unity.Collections;
using Unity.Entities;
using UnityEngine;

public struct RegisterAsPrefabComponent : IComponentData
{
    public int nameHash;
    public FixedString512 nameText;
}

public class RegisterAsPrefab_Authoring : MonoBehaviour, IConvertGameObjectToEntity
{
    public bool preview;

    public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    {
        dstManager.AddComponentData(entity, new RegisterAsPrefabComponent
        {
            nameHash = preview ? (name + "_PREVIEW").GetHashCode() : name.GetHashCode(),
            nameText = name
        });

        dstManager.AddComponentData(entity, new Prefab());

        ProcessChildren(transform, dstManager, conversionSystem);
    }

    public void ProcessChildren(Transform transform, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    {
        if (transform.childCount > 0)
        {
            for (int i =0; i < transform.childCount;i++)
            {
                var child = transform.GetChild(i);

                var childEntity = conversionSystem.GetPrimaryEntity(child);

                dstManager.AddComponentData(childEntity, new Prefab());

                if (child.childCount > 0)
                {
                    var childBuffer = dstManager.AddBuffer<LinkedEntityGroup>(childEntity);

                    for (int ii =0; ii < child.childCount;ii++)
                    {
                        var tmpEnt = conversionSystem.GetPrimaryEntity(child.GetChild(ii));
                        childBuffer.Add(new LinkedEntityGroup()
                        {
                            Value = tmpEnt
                        });
                    }
                }

                ProcessChildren(child, dstManager, conversionSystem);
            }
        }
    }
}

The conversion seems to go okay. At least the expected components (Prefab, LinkedEntityGroup) are on the entities. GameObjects with this component won’t be rendered anymore in the scene so that’s quite suboptimal.
On some gameobjects which have no child, it bugs out (sometimes) so maybe its missing the LinkedEntityGroup? Haven’t tried that.

Where it completely breaks down, is when those entities get instantiated. The Prefab component is not removed so it won’t be rendered. I’m not finding the piece of code that handles this.

To check if my assumptions are wrong somewhere.
When using GameObjectConversionUtility.ConvertGameObjectHierarchy, the converted entities have a Prefab tag on them. When they are instantiated in any way, the Prefab tag is not copied.
How does this happen and why does it differ?