void OnEnable()
        {
            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            m_Mesh = (ProBuilderMesh)target;

            if (!m_Mesh)
            {
                return;
            }

            m_GameObjectsSerializedObject = new SerializedObject(serializedObject.targetObjects.Select(t => ((Component)t).gameObject).ToArray());

            m_UnwrapParameters  = serializedObject.FindProperty("m_UnwrapParameters");
            m_StaticEditorFlags = m_GameObjectsSerializedObject.FindProperty("m_StaticEditorFlags");
            m_MeshRenderer      = m_Mesh.gameObject.GetComponent <Renderer>();

            SelectionRenderState s = EditorUtility.GetSelectionRenderState();

            EditorUtility.SetSelectionRenderState(m_MeshRenderer, editor != null ? s & SelectionRenderState.Outline : s);

            foreach (var mesh in Selection.transforms.GetComponents <ProBuilderMesh>())
            {
                EditorUtility.SynchronizeWithMeshFilter(mesh);
            }

            VertexManipulationTool.beforeMeshModification += OnBeginMeshModification;
            VertexManipulationTool.afterMeshModification  += OnFinishMeshModification;
        }
예제 #2
0
        static void UndoRedoPerformed()
        {
            // material preview when dragging in scene-view is done by applying then undoing changes. we don't want to
            // rebuild the mesh every single frame when dragging.
            if (SceneDragAndDropListener.isDragging)
            {
                return;
            }

            // Synchronize just checks that the mesh is not null, and UV2 is still valid. This should be very cheap except
            // for the FindObjectsOfType call.
            foreach (var mesh in Object.FindObjectsOfType <ProBuilderMesh>())
            {
                var versionID = mesh.versionID;
                EditorUtility.SynchronizeWithMeshFilter(mesh);
                mesh.InvalidateCaches();
                mesh.versionID = versionID;
            }

            foreach (var mesh in InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms))
            {
                var versionID = mesh.versionID;
                mesh.InvalidateCaches();
                mesh.Rebuild();
                mesh.Optimize();
                mesh.versionID = versionID;
            }

            ProBuilderEditor.Refresh();
            SceneView.RepaintAll();
        }
        static void UndoRedoPerformed()
        {
            // material preview when dragging in scene-view is done by applying then undoing changes. we don't want to
            // rebuild the mesh every single frame when dragging.
            if (SceneDragAndDropListener.isDragging)
            {
                return;
            }

            // Two passes
            // 1. Ensure every ProBuilderMesh in the scene has a valid mesh
            // 2. Rebuild every ProBuilderMesh in the selection to reflect undone changes.

            // Synchronize just checks that the mesh is not null, and UV2 is still valid. This should be very cheap except
            // for the FindObjectsOfType call.
            foreach (var mesh in Object.FindObjectsOfType <ProBuilderMesh>())
            {
                EditorUtility.SynchronizeWithMeshFilter(mesh);
                mesh.InvalidateCaches();
            }

            foreach (var mesh in InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms))
            {
                mesh.InvalidateCaches();

                using (new ProBuilderMesh.NonVersionedEditScope(mesh))
                {
                    mesh.Rebuild();
                    mesh.Optimize();
                }
            }

            ProBuilderEditor.Refresh();
        }
        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 {}
        }
예제 #5
0
        static void PrefabInstanceUpdated(GameObject go)
        {
            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            foreach (ProBuilderMesh pb in go.GetComponentsInChildren <ProBuilderMesh>())
            {
                EditorUtility.SynchronizeWithMeshFilter(pb);
                pb.ToMesh();
                pb.Refresh();
                pb.Optimize();
            }
        }
예제 #6
0
        /**
         * Used to catch prefab modifications that otherwise wouldn't be registered on the usual 'Awake' verify.
         *  - Dragging prefabs out of Project
         *  - 'Revert' prefab changes
         *  - 'Apply' prefab changes
         */
        static void HierarchyWindowChanged()
        {
            if (!EditorApplication.isPlaying)
            {
                bool meshesAreAssets = Experimental.meshesAreAssets;

                // on duplication, or copy paste, this rebuilds the mesh structures of the new objects
                foreach (ProBuilderMesh pb in Selection.transforms.GetComponents <ProBuilderMesh>())
                {
                    if (!meshesAreAssets)
                    {
                        EditorUtility.SynchronizeWithMeshFilter(pb);
                    }
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Hide the default unity wireframe renderer
        /// </summary>
        void SetOverrideWireframe(bool overrideWireframe)
        {
            const EditorSelectedRenderState k_DefaultSelectedRenderState = EditorSelectedRenderState.Highlight | EditorSelectedRenderState.Wireframe;

            foreach (var mesh in Selection.transforms.GetComponents <ProBuilderMesh>())
            {
                // Disable Wireframe for meshes when ProBuilder is active
                EditorUtility.SetSelectionRenderState(
                    mesh.renderer,
                    overrideWireframe
                        ? k_DefaultSelectedRenderState & ~(EditorSelectedRenderState.Wireframe)
                        : k_DefaultSelectedRenderState);

                EditorUtility.SynchronizeWithMeshFilter(mesh);
            }

            SceneView.RepaintAll();
        }
예제 #8
0
        public static void OnPostprocessScene()
        {
            var invisibleFaceMaterial = Resources.Load <Material>("Materials/InvisibleFace");

            // Hide nodraw faces if present.
            foreach (var pb in Object.FindObjectsOfType <ProBuilderMesh>())
            {
                if (pb.GetComponent <MeshRenderer>() == null)
                {
                    continue;
                }

                if (pb.GetComponent <MeshRenderer>().sharedMaterials.Any(x => x != null && x.name.Contains("NoDraw")))
                {
                    Material[] mats = pb.GetComponent <MeshRenderer>().sharedMaterials;

                    for (int i = 0; i < mats.Length; i++)
                    {
                        if (mats[i].name.Contains("NoDraw"))
                        {
                            mats[i] = invisibleFaceMaterial;
                        }
                    }

                    pb.GetComponent <MeshRenderer>().sharedMaterials = mats;
                }
            }

            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            foreach (var entity in Resources.FindObjectsOfTypeAll <EntityBehaviour>())
            {
                if (entity.manageVisibility)
                {
                    entity.OnEnterPlayMode();
                }
            }

            foreach (var mesh in Object.FindObjectsOfType <ProBuilderMesh>())
            {
                EditorUtility.SynchronizeWithMeshFilter(mesh);

                if (mesh.mesh == null)
                {
                    continue;
                }

                GameObject gameObject = mesh.gameObject;
                var        entity     = ProcessLegacyEntity(gameObject);

#if ENABLE_DRIVEN_PROPERTIES
                // clear editor-only HideFlags and serialization ignores
                mesh.ClearDrivenProperties();
                var filter = gameObject.DemandComponent <MeshFilter>();
                filter.hideFlags    = HideFlags.None;
                mesh.mesh.hideFlags = HideFlags.None;

                // Reassign the MeshFilter and MeshCollider properties _after_ clearing HideFlags and driven properties
                // to ensure that they are dirtied for serialization and thus included in the build
                filter.sharedMesh = mesh.mesh;
                if (mesh.TryGetComponent(out MeshCollider collider))
                {
                    collider.sharedMesh = mesh.mesh;
                }
#endif

                // early out if we're not planning to remove the ProBuilderMesh component
                if (m_ScriptStripping == false)
                {
                    continue;
                }

                if (mesh.TryGetComponent <BezierShape>(out BezierShape bezier))
                {
                    Object.DestroyImmediate(bezier);
                }

                if (mesh.TryGetComponent <PolyShape>(out PolyShape poly))
                {
                    Object.DestroyImmediate(poly);
                }

                mesh.preserveMeshAssetOnDestroy = true;
                Object.DestroyImmediate(mesh);
                Object.DestroyImmediate(entity);
            }
        }
        internal static void OnObjectSelectionChanged()
        {
            // GameObjects returns both parent and child when both are selected, where transforms only returns the
            // top-most transform.
            s_UnitySelectionChangeMeshes.Clear();
            s_ElementSelection.Clear();
            s_ActiveMesh = null;

            var gameObjects = Selection.gameObjects;

            for (int i = 0, c = gameObjects.Length; i < c; i++)
            {
#if UNITY_2019_3_OR_NEWER
                ProBuilderMesh mesh;
                if (gameObjects[i].TryGetComponent <ProBuilderMesh>(out mesh))
#else
                var mesh = gameObjects[i].GetComponent <ProBuilderMesh>();
                if (mesh != null)
#endif
                {
                    if (gameObjects[i] == Selection.activeGameObject)
                    {
                        s_ActiveMesh = mesh;
                    }

                    s_UnitySelectionChangeMeshes.Add(mesh);
                }
            }

            for (int i = 0, c = s_TopSelection.Count; i < c; i++)
            {
                if (!s_UnitySelectionChangeMeshes.Contains(s_TopSelection[i]))
                {
                    if (s_TopSelection[i] != null)
                    {
                        UndoUtility.RecordSelection(s_TopSelection[i], "Selection Change");
                    }
                    s_TopSelection[i].ClearSelection();
                }
            }

            s_TopSelection.Clear();

            foreach (var mesh in s_UnitySelectionChangeMeshes)
            {
                // don't add prefabs or assets to the mesh selection
                if (string.IsNullOrEmpty(AssetDatabase.GetAssetPath(mesh.gameObject)))
                {
                    EditorUtility.SynchronizeWithMeshFilter(mesh);
                    s_TopSelection.Add(mesh);
                }
            }

            InvalidateCaches();

            if (objectSelectionChanged != null)
            {
                objectSelectionChanged();
            }

            s_UnitySelectionChangeMeshes.Clear();
        }
예제 #10
0
        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 {}
        }
예제 #11
0
        public static void OnPostprocessScene()
        {
            var invisibleFaceMaterial = Resources.Load <Material>("Materials/InvisibleFace");

            var pbMeshes = (ProBuilderMesh[])Resources.FindObjectsOfTypeAll(typeof(ProBuilderMesh));

            // Hide nodraw faces if present.
            foreach (var pb in pbMeshes)
            {
                if (pb.GetComponent <MeshRenderer>() == null || UnityEditor.EditorUtility.IsPersistent(pb))
                {
                    continue;
                }

                if (pb.GetComponent <MeshRenderer>().sharedMaterials.Any(x => x != null && x.name.Contains("NoDraw")))
                {
                    Material[] mats = pb.GetComponent <MeshRenderer>().sharedMaterials;

                    for (int i = 0; i < mats.Length; i++)
                    {
                        if (mats[i].name.Contains("NoDraw"))
                        {
                            mats[i] = invisibleFaceMaterial;
                        }
                    }

                    pb.GetComponent <MeshRenderer>().sharedMaterials = mats;
                }
            }

            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            var renderersToStrip = new List <Renderer>();

            foreach (var entity in Resources.FindObjectsOfTypeAll <EntityBehaviour>())
            {
                if (entity.manageVisibility)
                {
                    entity.OnEnterPlayMode();
                }

                if ((entity is TriggerBehaviour || entity is ColliderBehaviour) && entity.gameObject.TryGetComponent(out MeshRenderer renderer))
                {
                    renderersToStrip.Add(renderer);
                }
            }

            foreach (var mesh in pbMeshes)
            {
                if (UnityEditor.EditorUtility.IsPersistent(mesh))
                {
                    continue;
                }

                EditorUtility.SynchronizeWithMeshFilter(mesh);

                if (mesh.mesh == null)
                {
                    continue;
                }

                GameObject gameObject = mesh.gameObject;
                var        entity     = ProcessLegacyEntity(gameObject);

#if ENABLE_DRIVEN_PROPERTIES
                // clear editor-only HideFlags and serialization ignores
                mesh.ClearDrivenProperties();
                var filter = gameObject.DemandComponent <MeshFilter>();
                filter.hideFlags    = HideFlags.None;
                mesh.mesh.hideFlags = HideFlags.None;

                // Reassign the MeshFilter and MeshCollider properties _after_ clearing HideFlags and driven properties
                // to ensure that they are dirtied for serialization and thus included in the build
                filter.sharedMesh = mesh.mesh;
                if (mesh.TryGetComponent(out MeshCollider collider))
                {
                    collider.sharedMesh = mesh.mesh;
                }
#endif

                // early out if we're not planning to remove the ProBuilderMesh component
                if (m_ScriptStripping == false)
                {
                    continue;
                }

                StripProBuilderScripts.DestroyProBuilderMeshAndDependencies(gameObject, mesh, true);
            }

            foreach (var renderer in renderersToStrip)
            {
                Undo.DestroyObjectImmediate(renderer);
            }
        }