- Home /
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:
- http://answers.unity3d.com/questions/10610/how-can-i-create-a-custom-import-object
- this one sugests using
OnPostprocessAllAssets()
for custom importer
- this one sugests using
- http://answers.unity3d.com/questions/1197/creating-a-complex-prefab-during-asset-postprocessing
- this one's about catching an imported model and wrapping it into a prefab hierarchy
But these don't seem enough to solve my problem.
Answer by femi · Dec 31, 2010 at 01:03 AM
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:
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); }
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;
mesh data is imported into the mesh
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.
Your answer
Follow this Question
Related Questions
is it possible to have a global/static variable in the AssetPostprocessor script 1 Answer
How to add UserData to FBX 3 Answers
Set Import Setting When an Audio Clip is Dragged into the Project 0 Answers
Editor class "Texture Importer" question (applying settings to multiple texture assets). 2 Answers
How can I make a text file immediately appear in my project from an AssetPostProcessor script? 1 Answer