Exemple #1
0
        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);
                }
            }
        }