Skip to content

Instantly share code, notes, and snippets.

@phobos2077
Last active April 14, 2019 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phobos2077/5cc09cac2bc2cbe5c877d3cd11aac9db to your computer and use it in GitHub Desktop.
Save phobos2077/5cc09cac2bc2cbe5c877d3cd11aac9db to your computer and use it in GitHub Desktop.
ProBuilder fixed export
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.ProBuilder;
using UnityEditor;
using UnityEditor.ProBuilder;
/// <summary>
/// Custom tools for working with ProBuilder.
/// </summary>
[InitializeOnLoad]
public static class ProBuilderUtils
{
const string DEFAULT_EXPORT_PATH = "Assets/[game]/Meshes/";
[MenuItem("Tools/ProBuilder/Export/Export Asset FIXED", true)]
public static bool ExportAssetValidate()
{
return MeshSelection.top.Any();
}
/// <summary>
/// An improved version of "Export Asset" command with improved workflow and .NET 4.x - related crash fixed.
/// </summary>
[MenuItem("Tools/ProBuilder/Export/Export Asset FIXED")]
public static void ExportAsset()
{
var meshes = MeshSelection.top;
if (meshes == null || !meshes.Any())
return;
if (meshes.Count() < 2)
{
ProBuilderMesh first = meshes.FirstOrDefault();
if (first == null)
return;
string path1 = UnityEditor.EditorUtility.SaveFilePanel("Export to Asset", DEFAULT_EXPORT_PATH, !(first != null) ? "Mesh" : first.name, "asset");
if (string.IsNullOrEmpty(path1))
return;
DoExport(path1, first);
}
else
{
string path = UnityEditor.EditorUtility.SaveFolderPanel("Export to Asset", DEFAULT_EXPORT_PATH, "");
if (string.IsNullOrEmpty(path) || !Directory.Exists(path))
return;
foreach (var mesh in meshes)
{
DoExport(string.Format("{0}/{1}.asset", path, mesh.name), mesh);
}
}
AssetDatabase.Refresh();
}
private static string DoExport(string path, ProBuilderMesh pb)
{
string directoryName = Path.GetDirectoryName(path).Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
string withoutExtension = Path.GetFileNameWithoutExtension(path);
string meshFilePath = string.Format("{0}/{1}.asset", directoryName, withoutExtension);
string prefabFilePath = string.Format("{0}/{1}.prefab", directoryName, withoutExtension);
string meshAssetPath = meshFilePath.Replace(Application.dataPath, "Assets");
string prefabAssetPath = prefabFilePath.Replace(Application.dataPath, "Assets");
pb.ToMesh();
pb.Refresh(RefreshMask.All);
pb.Optimize(true);
var pbMeshCopy = Object.Instantiate(pb.GetComponent<MeshFilter>().sharedMesh);
pbMeshCopy.name = withoutExtension;
pbMeshCopy = CreateOrReplaceAsset(pbMeshCopy, meshAssetPath);
GameObject go = new GameObject();
go.AddComponent<MeshFilter>().sharedMesh = pbMeshCopy;
go.AddComponent<MeshRenderer>().sharedMaterials = pb.gameObject.GetComponent<MeshRenderer>().sharedMaterials;
if (File.Exists(prefabFilePath))
{
var existingPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabAssetPath);
PrefabUtility.ReplacePrefab(go, existingPrefab, ReplacePrefabOptions.ReplaceNameBased);
}
else
{
PrefabUtility.SaveAsPrefabAsset(go, prefabAssetPath);
}
Object.DestroyImmediate(go);
return meshAssetPath;
}
static T CreateOrReplaceAsset<T>(T asset, string path) where T : Object
{
T existingAsset = AssetDatabase.LoadAssetAtPath<T>(path);
if (existingAsset == null)
{
AssetDatabase.CreateAsset(asset, path);
existingAsset = asset;
}
else
{
var uniquePath = AssetDatabase.GenerateUniqueAssetPath(path);
AssetDatabase.CreateAsset(asset, uniquePath);
FileUtil.ReplaceFile(uniquePath, path);
AssetDatabase.DeleteAsset(uniquePath);
}
return existingAsset;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment