Search Unity

Change mesh within imported OBJ or FBX - run AssetPostprocessor manually?

Discussion in 'Asset Importing & Exporting' started by Xarbrough, Jan 29, 2017.

  1. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    How can I change a mesh with a model file after it was imported from editor code? I have tried modifying it via the sharedMesh instance of the prefab, but the changes are not persistent, as if the prefab was giving me only a copy. Next, I've tried to use the AssetPostProcessor, which works, but now I'm interested in knowing, if I can apply custom changes to a mesh in an imported model manually. Maybe by running a custom processor again or via some other method.

    As an example:
    I would like to modify vertex colors and normals via script on meshes of my FBX and OBJ files. Some of these changes apply to all models and can be done via a custom AssetPostProcessor like this:

    Code (CSharp):
    1. public class MeshVertexColorProcessor : AssetPostprocessor
    2. {
    3.     void OnPostprocessModel (GameObject go)
    4.     {
    5.         Mesh mesh = go.GetComponent<MeshFilter>().sharedMesh;
    6.  
    7.         Color[] colors = new Color[mesh.vertexCount];
    8.         for (int i = 0; i < colors.Length; i++)
    9.         {
    10.             colors[i] = new Color(Random.value, Random.value, Random.value, 1f);
    11.         }
    12.         mesh.colors = colors;
    13.     }
    14. }
    Now all models get random vertex colors. It is important to note, that this seems to be the only way to do this kind of modification. When trying to modify the mesh after it was imported by getting a reference to it via the sharedMesh property on a prefab's MeshFilter, it won't persist changes. After reopening Unity, the mesh will be the way it was before in the model file. I've tested different scenarios, making sure that I was getting the correct reference and setting everything as dirty, but after reading the documentation, I realized, that the MeshFilter component associated with the imported model is only some kind of placeholder, which gets recreated on import.

    After running my automated processor, I would still like to be able to select a few models manually and apply custom settings, but the only way seems to be via the OnPostprocessModel method, but this would mean re-importing and therefore the default automated processor also runs.

    Can I somehow create a custom importer object in code and let it run a specific instance of my processor on selected models or am I missing something obvious to make changes to their meshes persist?
     
    Last edited: Jan 29, 2017
    StaffanEk likes this.
  2. mariusz

    mariusz

    Joined:
    Nov 5, 2010
    Posts:
    72
    yy...I'm pretty sure that I don't understand you right... and maybe it is not what you are looking for :)
    Since I'm not a programmer, what I understand was that you want to random change vertex colors of objects.
    So I was thinking how would I do this and (since I'm not a programmer) created houdini engine hda file
    and get this:
    This changed vertex colors of droped mesh, and I also added a seed parameter to get different results on same mesh. But still I'm not sure if this is what you want or maybe just a hint :)
     

    Attached Files:

  3. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    Thanks for answering, but I believe I didn't make my question clear enough. I am looking for a way to modify a mesh that was imported via FBX or OBJ via editor scripting without relying on the automated OnPostprocessModel call.

    What I found out so far:
    Unity imports the models file format and creates a kind of prefab (the blue box with white text file icon on it). When running a custom AssetPostProcessor I can get a reference to this prefab and change it. The changes will be saved. However, when I try to do the same thing from a regular editor script and just get the prefab reference and then call something like

    Code (CSharp):
    1. myModel.GetComponent<MeshFilter>.sharedMesh
    it will return a mesh that I can modify which will show changes in the scene, but then, when restarting Unity, the changes are lost. I know that I need to set an asset dirty or record undo for it, both of which don't work. It appears as if after the model prefab was first created it actually only returns a copy of itself. This would also explain why the preview in the inspector is grayed out when selecting a model and you actually have to instantiate it to make changes.
     
    StaffanEk likes this.
  4. beatsaway

    beatsaway

    Joined:
    Oct 8, 2017
    Posts:
    2
    same problem here. i can see inside some fbx objects contain all the animation files with the mesh while in some other fbx objects are actually a file contain only animation files as a package. i wonder why i cant just simply drag those out if they are within an imported fbx.