From 214c778bac7563ef695ffed11707f9d8af316ab7 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Thu, 17 Jun 2021 18:58:52 +0200 Subject: [PATCH] [unity] Fixed white image at first frame when using multiple canvas renderers. Replaced RawImage at additional SkeletonGraphic renderers with more resource friendly custom component. --- CHANGELOG.md | 1 + .../spine-unity/Components/Internal.meta | 8 ++++ .../Internal/SkeletonSubmeshGraphic.cs | 47 +++++++++++++++++++ .../Internal/SkeletonSubmeshGraphic.cs.meta | 11 +++++ .../spine-unity/Components/SkeletonGraphic.cs | 47 ++++++++++++------- 5 files changed, 97 insertions(+), 17 deletions(-) create mode 100644 spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal.meta create mode 100644 spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal/SkeletonSubmeshGraphic.cs create mode 100644 spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal/SkeletonSubmeshGraphic.cs.meta diff --git a/CHANGELOG.md b/CHANGELOG.md index df1472f66..1c0c915fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ * Corrected all `Outline` shaders outline thickness when `Advanced - Sample 8 Neighbourhood` is disabled (thus using `4 Neighbourhood`). Previously weighting was incorrectly thick (4x as thick) compared to 8 neighbourhood, now it is more consistent. This might require adjustment of all your outline materials where `Sample 8 Neighbourhood` is disabled to restore the previous outline thickness, by adjusting the `Outline Threshold` parameter through adding a `/4` to make the threshold 4 times smaller. * **Linear color space:** Previously Slot colors were not displayed the same in Unity as in the Spine Editor. This is now fixed at all shaders, including URP and LWRP shaders. See section *Additions* below for more details. If you have tweaked Slot colors to look correct in `Linear` color space in Unity but incorrect in Spine, you might want to adjust the tweaked colors. Slot colors displayed in Unity should now match colors displayed in the Spine Editor when configured to display as `Linear` color space in the Spine Editor Settings. * Additive Slots have always been lit before they were written to the target buffer. Now all lit shaders provide an additional parameter `Light Affects Additive` which defaults to `false`, as it is the more intuitive default value. You can enable the old behaviour by setting this parameter to `true`. + * `SkeletonGraphic` now no longer uses a `RawImage` component at each submesh renderer GameObject when `allowMultipleCanvasRenderers` is true. Instead, a new custom component `SkeletonSubmeshGraphic` is used which is more resource friendly. Replacement of these components will be performed automatically through editor scripting, saving scenes or prefabs will persist the upgrade. * **Additions** * Additional **Fix Draw Order** parameter at SkeletonRenderer, defaults to `disabled` (previous behaviour). diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal.meta new file mode 100644 index 000000000..deca6bf2b --- /dev/null +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8459fe8c08b88a84484f2b7ba5f36517 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal/SkeletonSubmeshGraphic.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal/SkeletonSubmeshGraphic.cs new file mode 100644 index 000000000..0ddae609c --- /dev/null +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal/SkeletonSubmeshGraphic.cs @@ -0,0 +1,47 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +using UnityEngine; +using UnityEngine.UI; + +namespace Spine.Unity { + + /// + /// A minimal MaskableGraphic subclass for rendering multiple submeshes + /// at a . + /// + [RequireComponent(typeof(CanvasRenderer))] + public class SkeletonSubmeshGraphic : MaskableGraphic { + public override void SetMaterialDirty () {} + public override void SetVerticesDirty () {} + protected override void OnPopulateMesh (VertexHelper vh) { + vh.Clear(); + } + } +} diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal/SkeletonSubmeshGraphic.cs.meta b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal/SkeletonSubmeshGraphic.cs.meta new file mode 100644 index 000000000..fdaf322fc --- /dev/null +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Internal/SkeletonSubmeshGraphic.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: deeb12332c062954093c24a3fab10b83 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs index ae16f2ed3..76e4e7a90 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs @@ -72,7 +72,7 @@ namespace Spine.Unity { public bool unscaledTime; public bool allowMultipleCanvasRenderers = false; public List canvasRenderers = new List(); - protected List rawImages = new List(); + protected List submeshGraphics = new List(); protected int usedRenderersCount = 0; // Submesh Separation @@ -203,7 +203,7 @@ namespace Spine.Unity { base.Awake (); updateMode = updateWhenInvisible; - SyncRawImagesWithCanvasRenderers(); + SyncSubmeshGraphicsWithCanvasRenderers(); if (!this.IsValid) { #if UNITY_EDITOR // workaround for special import case of open scene where OnValidate and Awake are @@ -262,16 +262,21 @@ namespace Spine.Unity { ApplyAnimation(); } - protected void SyncRawImagesWithCanvasRenderers () { - rawImages.Clear(); + protected void SyncSubmeshGraphicsWithCanvasRenderers () { + submeshGraphics.Clear(); + +#if UNITY_EDITOR + if (!Application.isPlaying) + DestroyOldRawImages(); +#endif foreach (var canvasRenderer in canvasRenderers) { - var rawImage = canvasRenderer.GetComponent(); - if (rawImage == null) { - rawImage = canvasRenderer.gameObject.AddComponent(); - rawImage.maskable = this.maskable; - rawImage.raycastTarget = false; + var submeshGraphic = canvasRenderer.GetComponent(); + if (submeshGraphic == null) { + submeshGraphic = canvasRenderer.gameObject.AddComponent(); + submeshGraphic.maskable = this.maskable; + submeshGraphic.raycastTarget = false; } - rawImages.Add(rawImage); + submeshGraphics.Add(submeshGraphic); } } @@ -481,7 +486,7 @@ namespace Spine.Unity { } } canvasRenderers = newList; - SyncRawImagesWithCanvasRenderers(); + SyncSubmeshGraphicsWithCanvasRenderers(); } public void Initialize (bool overwrite) { @@ -660,7 +665,6 @@ namespace Spine.Unity { var canvasRenderer = canvasRenderers[i]; if (i >= usedRenderersCount) { canvasRenderer.gameObject.SetActive(true); - rawImages[i].Rebuild(CanvasUpdate.PreRender); } canvasRenderer.SetMesh(targetMesh); canvasRenderer.materialCount = 1; @@ -704,10 +708,10 @@ namespace Spine.Unity { go.transform.localPosition = Vector3.zero; var canvasRenderer = go.AddComponent(); canvasRenderers.Add(canvasRenderer); - var rawImage = go.AddComponent(); - rawImage.maskable = this.maskable; - rawImage.raycastTarget = false; - rawImages.Add(rawImage); + var submeshGraphic = go.AddComponent(); + submeshGraphic.maskable = this.maskable; + submeshGraphic.raycastTarget = false; + submeshGraphics.Add(submeshGraphic); } } @@ -731,7 +735,16 @@ namespace Spine.Unity { } } } - #endif + + private void DestroyOldRawImages () { + foreach (var canvasRenderer in canvasRenderers) { + var oldRawImage = canvasRenderer.GetComponent(); + if (oldRawImage != null) { + DestroyImmediate(oldRawImage); + } + } + } +#endif protected void EnsureMeshesCount (int targetCount) { int oldCount = meshes.Count;