- Home /
Can anyone help with creating Prefabs for procedural meshes
Hi All I am hoping my be someone in this group or someone at Unity can help with a problem I am having creating Prefabs from objects which have had their meshes changed procedurally. I have tried a dozen or so solutions to get this to work each with varying levels of success. I have one that almost works but when a prefab is added back into a scene the inspector is very sluggish for any changes to the procedural component inspectors (though all runs fine when play pressed). I have worked my way through the docs for things such as the PrefabUtility class and AssetDatabase but it looks a bit of a black art with very little actual examples or explanation of what methods do ie for PrefabUtility.DisconnectPrefabInstance all you get is 'Disconnects the prefab instance from its parent prefab.' Is there a guide somewhere anyone knows of which explains the process a little better or if anyone can offer any help or advice I would be very grateful indeed, spent weeks on and off trying to get this to work and it is the main source of support requests for my asset.
Below is the code snippet for my current most successful attempt at getting this to work. Chris
Code Example:
My asset allows for meshes to be changed by various different methods, so the meshes in the filters are new meshes copied from the original ones so they do not exist in the asset database at the time a prefab is made.
[MenuItem("GameObject/Make My Prefab")]
static void DoCreateSimplePrefab()
{
GameObject obj = Selection.activeGameObject;
if ( obj != null )
{
if ( !Directory.Exists("Assets/MyPrefabs") )
{
AssetDatabase.CreateFolder("Assets", "MyPrefabs");
}
// Some examples say create empty prefab and then use replace?
GameObject prefab = PrefabUtility.CreatePrefab("Assets/MegaPrefabs/" + obj.name + ".prefab", obj);
// Just doing non skinned meshes to start
MeshFilter mf = obj.GetComponent<MeshFilter>();
if ( mf )
{
MeshFilter newmf = prefab.GetComponent<MeshFilter>();
// Create a new mesh from the original
Mesh mesh = CloneMesh(mf.sharedMesh);
mesh.name = obj.name + " copy";
// Do I add or create?
AssetDatabase.AddObjectToAsset(mesh, prefab);
//AssetDatabase.CreateAsset(mesh, "Assets/MegaPrefabs/" + Selection.activeGameObject.name + ".asset");
newmf.sharedMesh = mesh;
MeshCollider mc = prefab.GetComponent<MeshCollider>();
if ( mc )
{
mc.sharedMesh = null;
mc.sharedMesh = mesh;
}
}
// Not sure what this does, caused issues on some Unity versions.
//PrefabUtility.DisconnectPrefabInstance(prefab);
}
}
Answer by dorpeleg · Sep 22, 2013 at 11:54 AM
You are approaching this a bit wrong I think...
What you are trying to do here, is create a prefab then add the new mesh to it (correct me if I'm wrong).
What you should do, is this:
Before creating the prefab, save the new procedurally generated mesh as an asset.
Example:
AssetDatabase.CreateAsset(proceduralMesh, meshPath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Then, set that mesh as your gameobject's mesh
Example:
mf.mesh = proceduralMesh;
Then, create an empty prefab.
Example:
var emptyPrefab = PrefabUtility.CreateEmptyPrefab(endDirectory + ObjectName + "_Prefab.prefab");
Then, replace the empty prefab with your gameobject.
Example:
PrefabUtility.ReplacePrefab(TheGameObject, emptyPrefab);
This is how I do it.
Been looking for a solution to save procedurally generated meshes. Your answer really helped, thanks!!
Your answer
Follow this Question
Related Questions
AssetDatabase.AddObjectToAsset is not persistent? 0 Answers
cannot load GameObject Prefabs using Resources.Load in Android 0 Answers
How to check if an object is asset in build runtime (Not in Editor) ? 4 Answers
How to check what prefabs exist in one of the project folders? (not necessarily in Resources) 1 Answer