Apply multiple added GameObjects to a prefab

In a editor, I’m creating multiple gameobjects and I need to apply them directly to the prefab. So basically what I did is :

GameObject prefab = GetPrefab();
string prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab);

for (int i = 0; i < 10; i++)
{
     GameObject instance = new GameObject();
     ....
     PrefabUtility.ApplyAddedGameObject(instance, prefabPath, InteractionMode.AutomatedAction);
}

Problem is, each ApplyAddedGameObject() is very slow : the full process is taking minutes of loading at this point.

So I’m looking for a function to apply gameobjects in bulk, but it doesn’t seem to exist publicly in the API (please correct me if I’m wrong !).

In the Unity CS reference github, I found the following function, called internally by ApplyAddedGameObject() like this :
PrefabUtility.AddGameObjectsToPrefabAndConnect(
new GameObject[ ] { gameObject },
prefabSourceGameObjectParent);

Could we have something like this in the API ?

Thank you for your time.

Hi,

While a batch API would be nice I think it would be better to edit the prefab directly in this case

GameObject prefab = GetPrefab();
string prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab);

// The editing scope will automatically save, reimport prefab and unload contents
using (var editingScope = new PrefabUtility.EditPrefabContentsScope(prefabPath))
{
    var rootTransform = editingScope.prefabContentsRoot.GetComponent<Transform>();
    for (int i = 0; i < 10; ++i)
    {
        var newGo = new GameObject();
        newGo.GetComponent<Transform>().parent = rootTransform;
    }
}
1 Like

Hi, alternatively if you do need to use the Apply API, have you tried wrapping your multiple calls to ApplyAddedGameObject inside calls to

Unity - Scripting API: AssetDatabase.StopAssetEditing ?

1 Like

Hey thank you guys, for the quick replies !

Interesting ! Unfortunately, we are stuck in Unity 2019.3 for what-it-seems the rest of the production of our game and this function is only available in Unity 2020.1 (unless it will be backported to 2019.4), but I will keep that in mind !

It works ! The process now only takes a few seconds. Thanks ! :slight_smile:

@TacticalShader

It is just a simple wrapper around PrefabUtility.LoadPrefabContents that you can easily implement in your project. It looks like this

        public struct EditPrefabContentsScope : IDisposable
        {
            public readonly string assetPath;
            public readonly GameObject prefabContentsRoot;

            public EditPrefabContentsScope(string assetPath)
            {
                this.assetPath = assetPath;
                prefabContentsRoot = PrefabUtility.LoadPrefabContents(assetPath);
            }

            public void Dispose()
            {
                PrefabUtility.SaveAsPrefabAsset(prefabContentsRoot, assetPath);
                PrefabUtility.UnloadPrefabContents(prefabContentsRoot);
            }
        }

Makes editing prefabs directly a little easier. We implemented this with permission from someone who posted it in this forum.

But I am glad the other solution also worked.

1 Like