Use AssetPostProcessor to replace dummies with prefabs?

Am editing a level in our 3D tool of choice and using placeholder dummies for various things.

Adding components to the dummies works fine in AssetPostProcessor, but instead of delineating every tweaked variable on a component in the AssetPostProcessor script, would prefer to just swap out the dummy object for an existing prefab and make any changes to the prefab.

Can the AssetPostProcessor pipeline be used to swap out gameObjects with prefabs?

Have made an attempt using OnPostprocessModel(), but either the “swap with prefab” code gets ignored, or the attempt goes splat!

Anyone doing this successfully?

I would try using EditorUtility.InstantiatePrefab… :roll:

Guess I should have been more clear eh? :slight_smile: Am using OnPostprocessModel() of course Editor.InstantiatePrefab (!) but am getting null refs on the prefab var when I think I shouldn’t.

Here is the relevant test code…

var assetPrefab : Transform;

if (transform.name.ToLower().Contains("half")) {
	assetPrefab = EditorUtility.FindAsset("Prefabs/Level/Disc_half.prefab", Transform);
}
if (!assetPrefab)
	Debug.Log (Time.time.ToString("f2") + ": "
	+ "Error processing imported file: " + "Prefab is null!"
	);
}

And every import, the log is being hit for each occurrence of “half” in a model name. Have verified the path as valid, have included the extension, but it yet fails. No idea why.

Any other thoughts?

I also have problems using FindAsset.

Let’s try using Resources.LoadAssetAtPath instead? :slight_smile:

or maybe use AssetDatabase.LoadAssetAtPath(…)?

info: Ive never gotten AssetDatabase.Load__All__AssetsAtPath(…) to work as it returned null all the time.

Hmm…

Got it to instantiate the prefab using the original code (changed only the code layout, due to the previous spitting errors when not desired) but still am not able to replace the dummy object exactly.

For example adding:

var modelObj : Transform;

if (assetPrefab) {
	modelObj = EditorUtility.InstantiatePrefab(assetPrefab);
	modelObj.position = transform.position;
	modelObj.rotation = transform.rotation;
	modelObj.localScale = transform.localScale;
	modelObj.name = transform.name;
	modelObj.parent = transform.parent;
}

The last line causes Unity to crash horribly horribly.

So it seems there isn’t a way to swap a dummy with a prefab cleanly, unless I want to ignore my nice, clean and helpful hierarchy (which is like trading useful features for each other; why do I have to pick choose?)

Inherently using AssetPreProcessor has strengths, but when trying to replace an imported dummy with a prefab (keeping it in the same hierarchy as in the fbx), find I am fighting Unity to do this…

If it takes this much hoop-jumping to replace a dummy with a prefab, thinking a ReplaceWithPrefab() method would do nicely! Otherwise, seems AssetPreProcessor doesn’t play nicely with prefabs :frowning:

Could you paste the exact code use use in your attempt to use OnPostprocessModel ?

It should work, as long as you don’t try to replace the top level game object which was imported.

Bye, Lucas

Here it is!

#pragma strict

class MyModelPostprocessor extends AssetPostprocessor {
    function OnPostprocessModel (g : GameObject) {
        Apply(g.transform);
    }

    function Apply (transform : Transform) {
		// cache apply vars
		var modelObj : Transform;
		var assetPrefab : Transform;
		
		// do half wall
		if (transform.name.ToLower().Contains("half")) {
			assetPrefab = EditorUtility.FindAsset("Prefabs/Level/Disc-half.prefab", Transform);
			// instantiate prefab  set transform data
			if (assetPrefab) {
				modelObj = EditorUtility.InstantiatePrefab(assetPrefab);
				modelObj.position = transform.position;
				modelObj.rotation = transform.rotation;
				modelObj.localScale = transform.localScale;
				modelObj.name = transform.name;
				modelObj.parent = transform.parent;
				Debug.Log (Time.time.ToString("f2") + ": "
					+ "Processed imported file: " + transform.name
					);
			}
			// error out if no prefab
			else {
				Debug.Log (Time.time.ToString("f2") + ": "
					+ "Error processing imported file: " + transform.name + ", Prefab cannot be found!"
					);
			}
		}
		// Recurse on all transforms
		for (var child : Transform in transform)
			Apply(child);
	}
}

100% repro crash here. Will sub a bug on your confirm.

Hope this helps!

on a quick look, this seems to make an infinite recursion, because the object that you add actually has the word “half” in it, and after you add that, you recurse over all children again.

Not saying there is no bug here, just the first thing that comes to mind when looking at this code, please post your casenumber in this thread for reference.

Thanks, Lucas

If I understood you, you’re saying that instantiating a prefab as transform causes Apply to run “over all children” again?

Otherwise, not sure where the “over all children again” part comes into it. Though I’m recursing over each child, but don’t see how adding a prefab causes that to repeat for all children.

Your code does this:

if (name contains "half")
    add child with same name;

recurse over all children; // includes the new child with "half" in name

Since you just added a child with the name half in it, the recursion will add an infinite number of prefab children.

Ahh, interesting. So indeed my assumptions about how new transforms are integrated into the current hierarchy being recursed were off.

Will work around this, using the new understanding.

I think OnPostProcessModel is a lost cause for now, but I have come up with a solution that uses a Menu Item.

http://forum.unity3d.com/viewtopic.php?p=205121

Just bumping this thread to find out whether anyone has been able to make progress on this workflow. Any takers??