public static void DoStrip(ProBuilderMesh pb)
        {
            try
            {
                GameObject go = pb.gameObject;

                Renderer ren = go.GetComponent <Renderer>();

                if (ren != null)
                {
                    EditorUtility.SetSelectionRenderState(ren, EditorSelectedRenderState.Highlight | EditorSelectedRenderState.Wireframe);
                }

                if (EditorUtility.IsPrefabAsset(go))
                {
                    return;
                }

                EditorUtility.SynchronizeWithMeshFilter(pb);

                if (pb.mesh == null)
                {
                    DestroyProBuilderMeshAndDependencies(go, pb, false);
                    return;
                }

                string cachedMeshPath;
                Mesh   cachedMesh;

                // if meshes are assets and the mesh cache is valid don't duplicate the mesh to an instance.
                if (Experimental.meshesAreAssets && EditorMeshUtility.GetCachedMesh(pb, out cachedMeshPath, out cachedMesh))
                {
                    DestroyProBuilderMeshAndDependencies(go, pb, true);
                }
                else
                {
                    Mesh m = UnityEngine.ProBuilder.MeshUtility.DeepCopy(pb.mesh);

                    DestroyProBuilderMeshAndDependencies(go, pb);

                    go.GetComponent <MeshFilter>().sharedMesh = m;
                    if (go.TryGetComponent(out MeshCollider meshCollider))
                    {
                        meshCollider.sharedMesh = m;
                    }
                }
            }
            catch {}
        }
Exemple #2
0
        internal static void TryCacheMesh(ProBuilderMesh pb)
        {
            Mesh mesh = pb.mesh;

            // check for an existing mesh in the mesh cache and update or create a new one so
            // as not to clutter the scene yaml.
            string meshAssetPath = AssetDatabase.GetAssetPath(mesh);

            // if mesh is already an asset any changes will already have been applied since
            // pb_Object is directly modifying the mesh asset
            if (string.IsNullOrEmpty(meshAssetPath))
            {
                // at the moment the asset_guid is only used to name the mesh something unique
                string guid = pb.assetGuid;

                if (string.IsNullOrEmpty(guid))
                {
                    guid         = Guid.NewGuid().ToString("N");
                    pb.assetGuid = guid;
                }

                string meshCacheDirectory = GetMeshCacheDirectory(true);

                string path = string.Format("{0}/{1}.asset", meshCacheDirectory, guid);

                Mesh m = AssetDatabase.LoadAssetAtPath <Mesh>(path);

                // a mesh already exists in the cache for this pb_Object
                if (m != null)
                {
                    if (mesh != m)
                    {
                        // prefab instances should always point to the same mesh
                        if (EditorUtility.IsPrefabInstance(pb.gameObject) || EditorUtility.IsPrefabAsset(pb.gameObject))
                        {
                            // Debug.Log("reconnect prefab to mesh");

                            // use the most recent mesh iteration (when undoing for example)
                            UnityEngine.ProBuilder.MeshUtility.CopyTo(mesh, m);

                            UnityEngine.Object.DestroyImmediate(mesh);
                            pb.gameObject.GetComponent <MeshFilter>().sharedMesh = m;

                            // also set the MeshCollider if it exists
                            pb.Refresh(RefreshMask.Collisions);

                            return;
                        }
                        else
                        {
                            // duplicate mesh
                            // Debug.Log("create new mesh in cache from disconnect");
                            pb.assetGuid = Guid.NewGuid().ToString("N");
                            path         = string.Format("{0}/{1}.asset", meshCacheDirectory, pb.assetGuid);
                        }
                    }
                    else
                    {
                        Debug.LogWarning("Mesh found in cache and scene mesh references match, but pb.asset_guid doesn't point to asset.  Please report the circumstances leading to this event to Karl.");
                    }
                }

                AssetDatabase.CreateAsset(mesh, path);
            }
        }
        /// <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);
                }
            }
        }
        public static void DoStrip(ProBuilderMesh pb)
        {
            try
            {
                GameObject go = pb.gameObject;

                Renderer ren = go.GetComponent <Renderer>();

                if (ren != null)
                {
                    EditorUtility.SetSelectionRenderState(ren, EditorUtility.GetSelectionRenderState());
                }

                if (EditorUtility.IsPrefabAsset(go))
                {
                    return;
                }

                EditorUtility.SynchronizeWithMeshFilter(pb);

                if (pb.mesh == null)
                {
                    DestroyImmediate(pb);

                    if (go.GetComponent <Entity>())
                    {
                        DestroyImmediate(go.GetComponent <Entity>());
                    }

                    return;
                }

                string cachedMeshPath;
                Mesh   cachedMesh;

                // if meshes are assets and the mesh cache is valid don't duplicate the mesh to an instance.
                if (Experimental.meshesAreAssets && EditorMeshUtility.GetCachedMesh(pb, out cachedMeshPath, out cachedMesh))
                {
                    pb.preserveMeshAssetOnDestroy = true;
                    DestroyImmediate(pb);
                    if (go.GetComponent <Entity>())
                    {
                        DestroyImmediate(go.GetComponent <Entity>());
                    }
                }
                else
                {
                    Mesh m = UnityEngine.ProBuilder.MeshUtility.DeepCopy(pb.mesh);

                    DestroyImmediate(pb);

                    if (go.GetComponent <Entity>())
                    {
                        DestroyImmediate(go.GetComponent <Entity>());
                    }

                    go.GetComponent <MeshFilter>().sharedMesh = m;
                    if (go.GetComponent <MeshCollider>())
                    {
                        go.GetComponent <MeshCollider>().sharedMesh = m;
                    }
                }
            }
            catch {}
        }