Creating a prefab in AssetPostprocessor.OnPostprocessAllAssets().

I import models from custom binary format files in `AssetPostprocessor.OnPostprocessAllAssets()` and would like to build a more complex hierarchy around the mesh and place it in a prefab. But in this method I don't have a GameObject that I could have saved in a prefab and objects that I can construct don't seem to want to go into a prefab. Here is how I'm trying to do this:

    Mesh dummy = (Mesh)AssetDatabase.LoadAssetAtPath(asset_path, typeof(Mesh));
    if (!dummy) {
        dummy = new Mesh();
        dummy.name = name;
        AssetDatabase.CreateAsset(dummy, asset_path);
    }

    // mesh for the editor
    dummy.Clear();

    // [ ... generate/import mesh here ...]

    Object prefab = EditorUtility.CreateEmptyPrefab(base_path + ".prefab");
    GameObject go = new GameObject( name, typeof(MeshFilter));
    EditorUtility.ReplacePrefab( go, prefab, ReplacePrefabOptions.ConnectToPrefab );

    AssetDatabase.SaveAssets();
    AssetDatabase.Refresh(ImportAssetOptions.TryFastReimportFromMetaData);
    Object.DestroyImmediate( go );

but the prefab remains empty. Is what I'm trying to do possible at all?

Some related answers:

But these don't seem enough to solve my problem.

My first workaround was to have `OnPostprocessAllAssets()` generate empty collada files which triggers `OnPostprocessModel(go)`, where I actually load the model from my custom format.

Apparently this was unnecessary. At the moment I do the following:

  1. have a template prefab that contains GameObjects and Components set up as I want them to be
  2. in `OnPostprocessAllAssets()` this template is copied into a new prefab:

    // clone the model template
    Object templatePrefab = 
        AssetDatabase.LoadAssetAtPath(
            modelTemplate, 
            typeof(GameObject));
    GameObject template = (GameObject)EditorUtility.InstantiatePrefab (templatePrefab);
    
    // this way links will persist when we regenerate the mesh
    Object prefab = AssetDatabase.LoadAssetAtPath (prefabPath, typeof(GameObject));
    if (!prefab) {
        prefab = EditorUtility.CreateEmptyPrefab (prefabPath);
    }
    
    
  3. new mesh is loaded form or created in the same prefab:

    Mesh mesh = (Mesh)AssetDatabase.LoadAssetAtPath (prefabPath, typeof(Mesh));
    if (!mesh) {
        mesh = new Mesh ();
        mesh.name = name;
        AssetDatabase.AddObjectToAsset (mesh, prefabPath);
    } else {
        mesh.Clear ();
    }
    // assume that MeshFilter is already there. could check and AddComponent
    template.GetComponent<MeshFilter> ().sharedMesh = mesh;
    
    
  4. mesh data is imported into the `mesh`

  5. and finally:

    // make sure prefab links remain in tact
    EditorUtility.ReplacePrefab (template, prefab, ReplacePrefabOptions.ReplaceNameBased);
    // get rid of the temporary object (otherwise it stays over in scene)
    Object.DestroyImmediate (template);
    
    

The only problem with this code is that if something goes wrong and an exception is thrown between template creation and destruction, it stays in the current scene.

I guess my original code was way too broken due to lack of understanding and could be fixes as well, but i like the flexibility of this new approach and have no desire to test if I could make the initial fragment work.