AssetPostProcessor Question

I am trying to use the AssetPostProcessor to add things like collision meshes and scripts to my Maya files so that I can retain the ability to edit and modify my files while still applying and testing scripts to them. So I started very simply with this (taken from unifycommunity.com - unifycommunity Resources and Information.)

C# file:

using UnityEngine;
using UnityEditor;
using System.Collections;

public class BoundingBoxAdder : AssetPostprocessor {
    void OnPostprocessModel(GameObject g)
    {
        // filter out only animations.
        string lowerCaseAssetPath = assetPath.ToLower();
       
        if (lowerCaseAssetPath.IndexOf("/environment/") == -1)  //do this ONLY if we are in the ENVIRONMENT FOLDER, assets/environment/...
            return;
        
        Apply(g.transform);
    
    }
    
    
    // Add a mesh collider to each game object that contains collider in its name
    void Apply (Transform transform){
        if (transform.name.ToLower().Contains("collider")){
            transform.gameObject.AddComponent(typeof(MeshCollider));
    
            Object[] smr = transform.gameObject.GetComponentsInChildren(typeof(MeshRenderer), false);
            Object[] mfs = transform.gameObject.GetComponentsInChildren(typeof(MeshFilter), false);
            
             foreach (MeshRenderer o in smr){
                Object.DestroyImmediate(o, true);
            }
            foreach (MeshFilter mf in mfs){
                Object.DestroyImmediate(mf, true);
            }
        }

        // Recurse
        foreach(Transform child in transform)
            Apply(child);
    }
}

With this code I get 2 errors saying

and then I get

and

any suggestions?

Yes, add the type casts so they are instances of the correct classes :slight_smile:

That helps but I still don’t understand how to cast them correctly. I am searching google to see if I can figure this out.

generally the error tells you how, given its casteable at all.
In your case it though isn’t as I realized on the second look.
Your problem is what caused the first error: you assign it to an incorrect array. The return is Component[ ] not Object[ ]so you should not assign it to Object[ ] :slight_smile:

Once thats fixed the rest should commonly work again I think

hey zergcow, i just posted my script in this post, maybe it’s helpful to you.

That Helped Alot, Thanks! So here is what I ended up with. I added loads of comments to help others understand what I did and why. I hope someone can find use for it.

//ZergCow 2010
//Create a C# script and place it in your assets/Editor folder then copy and past this code into that file.

using UnityEngine;
using UnityEditor;
using System.Collections;

public class BoundingBoxAdder : AssetPostprocessor {

	void OnPostprocessModel (GameObject g)
	{
		//Set the file path variable for our models
		string lowerCaseAssetPath = assetPath.ToLower();
		//Apply this script ONLY if we are in our folder
		if (lowerCaseAssetPath.IndexOf("/ertc/models/final/") == -1)  //type your file location with all your models here in lowercase
			return;
		//Now lets go to our Apply function to do things to our models
		Apply(g.transform);
	}
	
	void Apply (Transform transform)
	{
		//lets look for objects with the name "collider" in it.
		if (transform.name.ToLower().Contains("collider"))
		{
			//Apply a collision to the object that we just looked for (collider)
			transform.gameObject.AddComponent(typeof(MeshCollider));
			
			//Now look for our MeshRenderer component in the object that we looked for (collider)
			//Then cast to an array
			Component[] smr = transform.gameObject.GetComponentsInChildren(typeof(MeshRenderer), false);
			//Now look for our MeshFilter component in the object that we looked for (collider)
			//Then cast to an array
			Component[] mfs = transform.gameObject.GetComponentsInChildren(typeof(MeshFilter), false);
			
			//delete each MeshRenderer component in our object 
			//MeshRenderer determins how the mesh is rendered on screen. 
			//We dont want to render the collision object so we delete this.
			foreach (MeshRenderer o in smr)
			{
				Object.DestroyImmediate(o, true);
			}
			//delete each MeshFilter component in our object 
			//MeshFilter determins how the mesh is rendered on screen. 
			//We dont want to render the collision object so we delete this.
			foreach (MeshFilter mf in mfs)
			{
				Object.DestroyImmediate(mf, true);
			}
		}
		
		//lets look for objects with the name "Valve" in it.
		if (transform.name.ToLower().Contains("valve"))
		{
			//Apply a collision to the object that we just looked for (valve)
			transform.gameObject.AddComponent(typeof(MeshCollider));
			
			//Add a script to the object that we just looked for (valve)
			transform.gameObject.AddComponent("ValveMove"); //Our script in this case is in a random folder and the script is named ValveMove
		}
		
		//Recurse
		//This is so that the Apply function will execute on every peice of the model.
		foreach(Transform child in transform)
			Apply(child);
	}
}

How would I combine all components with the name “static” into one mesh with a postprocessing script like this?

any ideas?

There’s an OnPostprocessAllAssets function which is called after all assets have been imported. The function is passed a list of asset pathnames which have changed during the import process. You could cycle through this list, note items with the right name and then combine their meshes.