After AssetPostprocessor meshes seem to be gone.

I think I’m missing something about how the AssetPostprocessor works here. I made a barebones post processor which I’m planning on using for reparenting objects in an imported model. As far as I know, it is not possible to do any reparenting of the model game object I get passed in from the post processor, so it seems the way around it is to instantiate a temp in the scene, modify that, and them make a prefab out of that. But I’ve noticed that with this dummy barebones implementation, the meshes for the model are gone or never loaded in the first place!

public class PathChunks : AssetPostprocessor {
  
  void OnPostprocessModel(GameObject model) {
    GameObject temp = GameObject.Instantiate((UnityEngine.Object)model) as GameObject;
    PrefabUtility.CreatePrefab("Assets/Level1.prefab", temp);
  }
}

After the above code runs, both the clone in the scene and the prefab have all of the objects the imported model have, but none of the objects have meshes. The mesh filter’s meshes are null. I also tried enumerating each object’s meh filter’s sharedMesh inside the code above and they are there. So something in the above code results in them being deleted.

Any thoughts?

It turns out to get a reference to the final imported object with meshes and everything, you have to get it from OnPostprocessAllAssets

For instance, in my case I ended up doing:

static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) {
    UnityEngine.Object model = AssetDatabase.LoadMainAssetAtPath(importedAssets[0]);
    if (model.name != "Level1") {
      return;
    }

    // etc...

Now I still have the problem that attempting to create a prefab out of the instantiated temp apparently causes recursive calls to the importer and so it’s a no go. So for now I’m settling for being able to create the restructured object in the scene and then I manually make it into a prefab.

Sometimes I really wished Unity would be more clear with their documentation.

In case this might help anyone, this is what I do. You have to call this code in OnPostprocessAllAssets(…) with the imported asset path that you care about. The GetGeneratedPrefabPath(…) and PrefabNameAlreadyUsed(…) is just code i use to figure out where to save the prefabs, modify it to be what ever you want.

static void GeneratePrefab(string assetPath)
    {
        string generatedPrefabPath = GetGeneratedPrefabPath(assetPath);
        if (string.IsNullOrEmpty(generatedPrefabPath))  //null means we don't need to generate prefabs (unless there was an error but we will see debug msg in that case)
        {
            return;
        }

        if (PrefabNameAlreadyUsed(generatedPrefabPath))
        {
			Debug.LogError("Prefab name already exist! Rename the " + prefabFBXExtension + " file (" + assetPath + ") to be unique");
            return; 
        }


        GameObject modelGameObject = AssetDatabase.LoadAssetAtPath(assetPath, typeof(GameObject)) as GameObject;
        if (!modelGameObject)
        {
            Debug.Log("Can't load imported game object to create prefab: " + assetPath);
            return;
        }

        GameObject generatedPrefab = AssetDatabase.LoadAssetAtPath(generatedPrefabPath, typeof(GameObject)) as GameObject;

        if (generatedPrefab)
        {
            GameObject modelGameObjectInstance = Object.Instantiate(modelGameObject);
            generatedPrefab = PrefabUtility.ReplacePrefab(modelGameObjectInstance, generatedPrefab, ReplacePrefabOptions.ReplaceNameBased);
            Object.DestroyImmediate(modelGameObjectInstance);
        }
        else
        {
            //Make sure our duplicated folder exist
            string prefabDirectory = Path.GetDirectoryName(generatedPrefabPath);
            if (prefabDirectory != null && !System.IO.Directory.Exists(prefabDirectory))
            {
                Directory.CreateDirectory(prefabDirectory);
                AssetDatabase.Refresh();
            }

            GameObject modelGameObjectInstance = Object.Instantiate(modelGameObject);
            generatedPrefab = PrefabUtility.CreatePrefab(generatedPrefabPath, modelGameObjectInstance);
            Object.DestroyImmediate(modelGameObjectInstance);
        }

        if (generatedPrefab == null)
        {
            Debug.Log("Can't create a prefab for: " + assetPath);
        }        
    }