static void OnDestroyObject(ProBuilderMesh mesh) { if (Experimental.meshesAreAssets) { if (EditorUtility.IsPrefab(mesh)) { // Debug.Log("will not destroy prefab mesh"); } else { string cache_path; Mesh cache_mesh; // if it is cached but not a prefab instance or root, destroy the mesh in the cache // otherwise go ahead and destroy as usual if (EditorMeshUtility.GetCachedMesh(mesh, out cache_path, out cache_mesh)) { // on entering / exiting play mode unity instances everything and destroys the scene, // which nukes the mesh cache. don't do this. bool isPlaying = EditorApplication.isPlaying; bool orWillPlay = EditorApplication.isPlayingOrWillChangePlaymode; if (isPlaying || orWillPlay) { return; } SelectionUtility.Remove(mesh); AssetDatabase.DeleteAsset(cache_path); } else { Object.DestroyImmediate(mesh.mesh); } } } else { string path = AssetDatabase.GetAssetPath(mesh.mesh); // If the pb_Object is backed by a Mesh asset don't destroy it. if (string.IsNullOrEmpty(path)) { Object.DestroyImmediate(mesh.mesh); } } }
/// <summary> /// Ensure that this object has a valid mesh reference, and the geometry is current. If it is not valid, this function will attempt to repair the sync state. /// </summary> /// <param name="mesh">The component to test.</param> /// <seealso cref="ProBuilderMesh.meshSyncState"/> public static void SynchronizeWithMeshFilter(ProBuilderMesh mesh) { if (mesh == null) { throw new ArgumentNullException("mesh"); } Mesh oldMesh = mesh.mesh; MeshSyncState state = mesh.meshSyncState; bool meshesAreAssets = Experimental.meshesAreAssets; if (state != MeshSyncState.InSync) { if (state == MeshSyncState.Null) { mesh.Rebuild(); mesh.Optimize(); } else /** * If the mesh ID doesn't match the gameObject Id, it could mean two things - * 1. The object was just duplicated, and then made unique * 2. The scene was reloaded, and gameObject ids were recalculated. * If the latter, we need to clean up the old mesh. If the former, * the old mesh needs to *not* be destroyed. */ if (oldMesh) { int meshNo = -1; int.TryParse(oldMesh.name.Replace("pb_Mesh", ""), out meshNo); UnityEngine.Object dup = UnityEditor.EditorUtility.InstanceIDToObject(meshNo); GameObject go = dup as GameObject; if (go == null) { // Debug.Log("scene reloaded - false positive."); mesh.mesh.name = "pb_Mesh" + mesh.id; } else { // Debug.Log("duplicate mesh"); if (!meshesAreAssets || !(EditorUtility.IsPrefabAsset(mesh.gameObject) || IsPrefabInstance(mesh.gameObject))) { // deep copy arrays & ToMesh/Refresh mesh.MakeUnique(); mesh.Optimize(); } } } else { // old mesh didn't exist, so this is probably a prefab being instanced if (EditorUtility.IsPrefabAsset(mesh.gameObject)) { mesh.mesh.hideFlags = (HideFlags)(1 | 2 | 4 | 8); } mesh.Optimize(); } } else { if (meshesAreAssets) { EditorMeshUtility.TryCacheMesh(mesh); } } }
/// <summary> /// Ensure that this object has a valid mesh reference, and the geometry is current. If it is not valid, this function will attempt to repair the sync state. /// </summary> /// <param name="mesh">The component to test.</param> /// <seealso cref="ProBuilderMesh.meshSyncState"/> public static void SynchronizeWithMeshFilter(ProBuilderMesh mesh) { if (mesh == null) { throw new ArgumentNullException("mesh"); } mesh.EnsureMeshFilterIsAssigned(); mesh.EnsureMeshColliderIsAssigned(); MeshSyncState state = mesh.meshSyncState; bool meshesAreAssets = Experimental.meshesAreAssets; if (state != MeshSyncState.InSync) { Mesh oldMesh; if (state == MeshSyncState.Null) { mesh.Rebuild(); mesh.Optimize(); } else // If the mesh ID doesn't match the gameObject Id, it could mean two things: // 1. The object was just duplicated, and then made unique // 2. The scene was reloaded, and gameObject ids were recalculated. // If (2) we need to clean up the old mesh. If the (1) the old mesh needs to *not* be destroyed. if ((oldMesh = mesh.mesh) != null) { int meshNo = -1; int.TryParse(oldMesh.name.Replace("pb_Mesh", ""), out meshNo); UnityEngine.Object dup = UnityEditor.EditorUtility.InstanceIDToObject(meshNo); GameObject go = dup as GameObject; // Scene reload, just rename the mesh to the correct ID if (go == null) { mesh.mesh.name = "pb_Mesh" + mesh.id; } else { // Mesh was duplicated, need to instantiate a unique mesh asset if (!meshesAreAssets || !(IsPrefabAsset(mesh.gameObject) || IsPrefabInstance(mesh.gameObject))) { // deep copy arrays & ToMesh/Refresh mesh.MakeUnique(); mesh.Optimize(); } } } else { // old mesh didn't exist, so this is probably a prefab being instanced if (IsPrefabAsset(mesh.gameObject)) { mesh.mesh.hideFlags = (HideFlags)(1 | 2 | 4 | 8); } mesh.Optimize(); } } else { if (meshesAreAssets) { EditorMeshUtility.TryCacheMesh(mesh); } } }