/// <summary> /// Export meshes to a Unity asset. /// </summary> /// <param name="meshes"></param> /// <returns></returns> public static string ExportWithFileDialog(IList <ProBuilderMesh> meshes, ExportAssetOptions options) { if (meshes == null || !meshes.Any()) { return(""); } string res = null; if (meshes.Count() < 2) { ProBuilderMesh first = meshes.FirstOrDefault(); if (first == null) { return(null); } res = options.makePrefab ? ExportPrefab(first, options.replaceOriginal) : ExportMesh(first, options.replaceOriginal); } else { string path = UnityEditor.EditorUtility.SaveFolderPanel("Export to Asset", "Assets", ""); if (string.IsNullOrEmpty(path) || !Directory.Exists(path)) { return(null); } meshes = meshes.ToList(); for (int i = 0, c = meshes.Count; i < c; i++) { var pb = meshes[i]; var assetPath = string.Format("{0}/{1}.asset", path, pb.name); if (options.makePrefab) { res = ExportPrefab(assetPath, pb, options.replaceOriginal, true); } else { res = ExportMesh(assetPath, pb, options.replaceOriginal, true); if (options.replaceOriginal) { StripProBuilderScripts.DestroyProBuilderMeshAndDependencies(pb.gameObject, pb, true, true); } } } } ProBuilderEditor.Refresh(); AssetDatabase.Refresh(); return(res); }
static string ExportMesh(ProBuilderMesh mesh, bool replaceOriginal) { string path = AskForPath(mesh.name, "asset"); if (string.IsNullOrEmpty(path)) { return(null); } ExportMesh(path, mesh, replaceOriginal, false); if (replaceOriginal) { StripProBuilderScripts.DestroyProBuilderMeshAndDependencies(mesh.gameObject, mesh, true, true); } else { mesh.mesh = null; EditorUtility.SynchronizeWithMeshFilter(mesh); } return(path); }
static string ExportPrefab(string path, ProBuilderMesh pb, bool replaceOriginal, bool batchExport) { string name = Path.GetFileNameWithoutExtension(path); string basePath = AssetPathFromFullPath(path, null); pb.ToMesh(); pb.Refresh(); pb.Optimize(); string meshPath = string.Format("{0}.asset", basePath); string prefabPath = string.Format("{0}.prefab", basePath); if (batchExport) { // Never overwrite during batch export. meshPath = AssetDatabase.GenerateUniqueAssetPath(meshPath); prefabPath = AssetDatabase.GenerateUniqueAssetPath(prefabPath); } else { var existingMesh = AssetDatabase.LoadAssetAtPath <Mesh>(meshPath); if (existingMesh) { // Overwriting mesh. var existingPrefab = AssetDatabase.LoadAssetAtPath <GameObject>(prefabPath); if (existingPrefab) { // Overwriting prefab as well. var meshFilter = existingPrefab.GetComponent <MeshFilter>(); if (!meshFilter || meshFilter.sharedMesh != existingMesh) { // Prefab and mesh being overwritten are not related, pick different path. meshPath = PickDifferentAssetPath(meshPath); } // Else allow overwrite both as they are related. } else { // Unrelated mesh is being overriden, pick different path. meshPath = PickDifferentAssetPath(meshPath); } } } Mesh meshAsset = pb.mesh; meshAsset.name = name; meshAsset = CreateOrReplaceAsset(meshAsset, meshPath); var go = replaceOriginal ? pb.gameObject : Object.Instantiate(pb.gameObject); var component = go.GetComponent <ProBuilderMesh>(); Undo.RecordObject(component, "Export ProBuilderMesh as Replacement"); StripProBuilderScripts.DestroyProBuilderMeshAndDependencies(go, component, true, true); go.GetComponent <MeshFilter>().sharedMesh = meshAsset; var meshCollider = go.GetComponent <MeshCollider>(); if (meshCollider) { meshCollider.sharedMesh = meshAsset; } if (replaceOriginal) { PrefabUtility.SaveAsPrefabAssetAndConnect(go, prefabPath, InteractionMode.UserAction); } else { // if we're about to overwrite the prefab asset of the source mesh, first disconnect it so that we're not // overwriting the instance if (PrefabUtility.IsPartOfAnyPrefab(pb) && PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(pb) == prefabPath) { PrefabUtility.UnpackPrefabInstance(pb.gameObject, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction); } PrefabUtility.SaveAsPrefabAsset(go, prefabPath); } if (!replaceOriginal) { pb.mesh = null; EditorUtility.SynchronizeWithMeshFilter(pb); Object.DestroyImmediate(go); } return(meshPath); }