From 4a9f7b8a7b7c1c90ad45eef89bb00d75e6e5d281 Mon Sep 17 00:00:00 2001 From: Vladislav Hristov Date: Fri, 6 Aug 2021 11:12:46 +0300 Subject: [PATCH] [unity] Implement build preprocessor for prefabs cleanup With the new prefab processing there is an issue where the mesh tries to get into the build. To prevent this a build pre/post process is introduced that will clean up the prefab from the meshes before the build and restore the prefab meshes after the build. This change reverts bf70a62f1 and is related to #1273,#1931. --- .../Editor/Utility/SpineBuildProcessor.cs | 132 ++++++++++++++++++ .../Utility/SpineBuildProcessor.cs.meta | 11 ++ .../Editor/Utility/SpineEditorUtilities.cs | 32 ++++- 3 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineBuildProcessor.cs create mode 100644 spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineBuildProcessor.cs.meta diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineBuildProcessor.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineBuildProcessor.cs new file mode 100644 index 000000000..47972c356 --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineBuildProcessor.cs @@ -0,0 +1,132 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated January 1, 2020. Replaces all prior versions. + * + * Copyright (c) 2013-2020, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + + +#if UNITY_2018_1_OR_NEWER +#define HAS_BUILD_PROCESS_WITH_REPORT +#endif + +#if UNITY_2020_2_OR_NEWER +#define HAS_ON_POSTPROCESS_PREFAB +#endif + +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using UnityEditor.Build; +#if HAS_BUILD_PROCESS_WITH_REPORT +using UnityEditor.Build.Reporting; +#endif + +namespace Spine.Unity.Editor { + public class SpineBuildProcessor + { + internal static bool isBuilding = false; + +#if HAS_ON_POSTPROCESS_PREFAB + static List prefabsToRestore = new List(); +#endif + + internal static void PreprocessBuild() + { + isBuilding = true; +#if HAS_ON_POSTPROCESS_PREFAB + var assets = AssetDatabase.FindAssets("t:Prefab"); + foreach(var asset in assets) { + string assetPath = AssetDatabase.GUIDToAssetPath(asset); + GameObject g = AssetDatabase.LoadAssetAtPath(assetPath); + if (SpineEditorUtilities.CleanupSpinePrefabMesh(g)) { + prefabsToRestore.Add(assetPath); + } + } + AssetDatabase.SaveAssets(); +#endif + } + + internal static void PostprocessBuild() + { + isBuilding = false; +#if HAS_ON_POSTPROCESS_PREFAB + foreach (string assetPath in prefabsToRestore) { + GameObject g = AssetDatabase.LoadAssetAtPath(assetPath); + SpineEditorUtilities.SetupSpinePrefabMesh(g, null); + } + AssetDatabase.SaveAssets(); +#endif + } + } + + public class SpineBuildPreprocessor : +#if HAS_BUILD_PROCESS_WITH_REPORT + IPreprocessBuildWithReport +#else + IPreprocessBuild +#endif + { + public int callbackOrder { + get { return -2000; } + } +#if HAS_BUILD_PROCESS_WITH_REPORT + void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report) + { + SpineBuildProcessor.PreprocessBuild(); + } +#else + void IPreprocessBuild.OnPreprocessBuild(BuildTarget target, string path) + { + SpineBuildProcessor.PreprocessBuild(); + } +#endif + } + + public class SpineBuildPostprocessor : +#if HAS_BUILD_PROCESS_WITH_REPORT + IPostprocessBuildWithReport +#else + IPostprocessBuild +#endif + { + public int callbackOrder { + get { return 2000; } + } + + +#if HAS_BUILD_PROCESS_WITH_REPORT + void IPostprocessBuildWithReport.OnPostprocessBuild(BuildReport report) + { + SpineBuildProcessor.PostprocessBuild(); + } +#else + void IPostprocessBuild.OnPostprocessBuild(BuildTarget target, string path) + { + SpineBuildProcessor.PostprocessBuild(); + } +#endif + } +} diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineBuildProcessor.cs.meta b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineBuildProcessor.cs.meta new file mode 100644 index 000000000..09f96e801 --- /dev/null +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineBuildProcessor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ca21cb19ac5068ee796e6cb09ff11e5d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs index b5cb25e5a..c469e0ed7 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs @@ -102,8 +102,18 @@ namespace Spine.Unity.Editor { #if HAS_ON_POSTPROCESS_PREFAB // Post process prefabs for setting the MeshFilter to not cause constant Prefab override changes. void OnPostprocessPrefab (GameObject g) { + if (SpineBuildProcessor.isBuilding) + return; + + SetupSpinePrefabMesh(g, context); + } + + public static bool SetupSpinePrefabMesh(GameObject g, UnityEditor.AssetImporters.AssetImportContext context) + { + bool wasModified = false; var skeletonRenderers = g.GetComponentsInChildren(true); foreach (SkeletonRenderer renderer in skeletonRenderers) { + wasModified = true; var meshFilter = renderer.GetComponent(); if (meshFilter == null) meshFilter = renderer.gameObject.AddComponent(); @@ -114,9 +124,27 @@ namespace Spine.Unity.Editor { var mesh = meshFilter.sharedMesh; string meshName = string.Format("Skeleton Prefab Mesh \"{0}\"", renderer.name); mesh.name = meshName; - mesh.hideFlags = HideFlags.DontSaveInEditor; // removed flag DontSaveInBuild, prevents a build error when the prefab is referenced - context.AddObjectToAsset(meshName, mesh); + if (context != null) + context.AddObjectToAsset(meshFilter.sharedMesh.name, meshFilter.sharedMesh); } + return wasModified; + } + + public static bool CleanupSpinePrefabMesh(GameObject g) + { + bool wasModified = false; + var skeletonRenderers = g.GetComponentsInChildren(true); + foreach (SkeletonRenderer renderer in skeletonRenderers) { + var meshFilter = renderer.GetComponent(); + if (meshFilter != null) { + if (meshFilter.sharedMesh) { + wasModified = true; + meshFilter.sharedMesh = null; + meshFilter.hideFlags = HideFlags.None; + } + } + } + return wasModified; } #endif