From 7d0833f881f76777e110dacca40c37e49ad5f33d Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Thu, 13 Apr 2023 17:57:12 +0200 Subject: [PATCH] [unity] Fixed SkeletonGraphic exception when Attachment changed after SkeletonGraphic.LateUpdate. Closes #2275. --- .../spine-unity/Components/SkeletonGraphic.cs | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) 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 ca174711e..d27cbbe0e 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs @@ -116,6 +116,7 @@ namespace Spine.Unity { public bool updateSeparatorPartLocation = true; private bool wasUpdatedAfterInit = true; + private bool requiresInstructionUpate = true; private Texture baseTexture = null; #if UNITY_EDITOR @@ -308,7 +309,10 @@ namespace Spine.Unity { public override void Rebuild (CanvasUpdate update) { base.Rebuild(update); if (canvasRenderer.cull) return; - if (update == CanvasUpdate.PreRender) UpdateMeshToInstructions(); + if (update == CanvasUpdate.PreRender) { + if (requiresInstructionUpate) PrepareInstructionsAndRenderers(isInRebuild : true); + UpdateMeshToInstructions(); + } if (allowMultipleCanvasRenderers) canvasRenderer.Clear(); } @@ -404,8 +408,7 @@ namespace Spine.Unity { if (updateMode != UpdateMode.FullUpdate) return; PrepareInstructionsAndRenderers(); - if (OnInstructionsPrepared != null) - OnInstructionsPrepared(this.currentInstructions); + SetVerticesDirty(); // triggers Rebuild and avoids potential double-update in a single frame } @@ -452,9 +455,11 @@ namespace Spine.Unity { public Skeleton Skeleton { get { Initialize(false); + requiresInstructionUpate = true; return skeleton; } set { + requiresInstructionUpate = true; skeleton = value; } } @@ -690,11 +695,12 @@ namespace Spine.Unity { OnAnimationRebuild(this); } - public void PrepareInstructionsAndRenderers () { + public void PrepareInstructionsAndRenderers (bool isInRebuild = false) { + requiresInstructionUpate = false; if (!this.allowMultipleCanvasRenderers) { MeshGenerator.GenerateSingleSubmeshInstruction(currentInstructions, skeleton, null); if (canvasRenderers.Count > 0) - DisableUnusedCanvasRenderers(usedCount: 0); + DisableUnusedCanvasRenderers(usedCount: 0, isInRebuild); usedRenderersCount = 0; } else { MeshGenerator.GenerateSkeletonRendererInstruction(currentInstructions, skeleton, null, @@ -707,8 +713,10 @@ namespace Spine.Unity { EnsureMeshesCount(submeshCount); EnsureUsedTexturesAndMaterialsCount(submeshCount); EnsureSeparatorPartCount(); - PrepareRendererGameObjects(currentInstructions); + PrepareRendererGameObjects(currentInstructions, isInRebuild); } + if (OnInstructionsPrepared != null) + OnInstructionsPrepared(this.currentInstructions); } public void UpdateMesh () { @@ -922,9 +930,11 @@ namespace Spine.Unity { } } - protected void PrepareRendererGameObjects (SkeletonRendererInstruction currentInstructions) { + protected void PrepareRendererGameObjects (SkeletonRendererInstruction currentInstructions, + bool isInRebuild = false) { + int submeshCount = currentInstructions.submeshInstructions.Count; - DisableUnusedCanvasRenderers(usedCount: submeshCount); + DisableUnusedCanvasRenderers(usedCount: submeshCount, isInRebuild); int separatorSlotGroupIndex = 0; int targetSiblingIndex = 0; @@ -961,13 +971,14 @@ namespace Spine.Unity { usedRenderersCount = submeshCount; } - protected void DisableUnusedCanvasRenderers (int usedCount) { + protected void DisableUnusedCanvasRenderers (int usedCount, bool isInRebuild = false) { #if UNITY_EDITOR RemoveNullCanvasRenderers(); #endif for (int i = usedCount; i < canvasRenderers.Count; i++) { canvasRenderers[i].Clear(); - canvasRenderers[i].gameObject.SetActive(false); + if (!isInRebuild) // rebuild does not allow disabling Graphic and thus removing it from rebuild list. + canvasRenderers[i].gameObject.SetActive(false); } }