- Home /
Create a prefab in editor from children objects of a model without alter scene
I have a model (modified with a custom postprocessor), and I want to modify it saving just some of the children of the object as prefabs. This works and in particular the following is the code:
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
foreach (var importedAsset in importedAssets)
{
var rootPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(importedAsset);
if (rootPrefab == null)
break;
if (rootPrefab.GetComponentsInChildren<GenerateClothes>().Count() == 0)
break;
var unpackedPrefab = PrefabUtility.InstantiatePrefab(rootPrefab) as GameObject;
PrefabUtility.UnpackPrefabInstance(unpackedPrefab, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
var dirName = Path.GetDirectoryName(importedAsset) + "/" + "Clothes";
Directory.CreateDirectory(dirName);
var generateClothes = unpackedPrefab.GetComponentsInChildren<GenerateClothes>().Where(d => d != null).ToList();
for (int i = 0; i < generateClothes.Count; i++)
{
var gameObject = generateClothes[i].gameObject;
UnityEngine.Object.DestroyImmediate(generateClothes[i]);
PrefabUtility.SaveAsPrefabAsset(gameObject, dirName + "/" + gameObject.name + ".prefab");
}
UnityEngine.Object.DestroyImmediate(unpackedPrefab);
}
}
The problem is that I need to instantiate the prefab to manipulate and save it, but doing this the script alters the scene. It removes the changes it made in the scene with a DestroyImmediate, but there are some caveats doing this. The first one is that if the script, for any reason, fails the scene will be altered. Surely I could surround anything with a try-catch clause but it doesn't seem an optimal solution.
The second one is even worse, the scene will result as altered (or in the case I undo the changes I'd loss the ones in the undo stack after the point I'm editing).
Is there a way to resolve this problem, maybe manipulating a prefab in memory somehow but without creating it in scene?
EDIT:
After I wrote the question I found the function PrefabUtility.LoadPrefabContents, that would do exactly what I need, but it is not usable with fbx, but just with prefabs, so it is not useful in this very case.