From eadce3188c788ae78ccec487c3a0a290d0ec18d9 Mon Sep 17 00:00:00 2001 From: Harald Csaszar Date: Mon, 8 Jun 2020 20:18:11 +0200 Subject: [PATCH] [unity] Fixed BoundingBoxFollower exception in editor upon loading. Closes #1696. --- .../BoundingBoxFollowerInspector.cs | 10 +++- .../Following/BoundingBoxFollower.cs | 55 +++++++++---------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/BoundingBoxFollowerInspector.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/BoundingBoxFollowerInspector.cs index 260a90150..294882945 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/BoundingBoxFollowerInspector.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Components/BoundingBoxFollowerInspector.cs @@ -55,7 +55,7 @@ namespace Spine.Unity.Editor { } } - void OnEnable () { + void InitializeEditor () { skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); slotName = serializedObject.FindProperty("slotName"); isTrigger = serializedObject.FindProperty("isTrigger"); @@ -64,12 +64,17 @@ namespace Spine.Unity.Editor { } public override void OnInspectorGUI () { + #if !NEW_PREFAB_SYSTEM bool isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab); #else bool isInspectingPrefab = false; #endif + // Note: when calling InitializeEditor() in OnEnable, it throws exception + // "SerializedObjectNotCreatableException: Object at index 0 is null". + InitializeEditor(); + // Try to auto-assign SkeletonRenderer field. if (skeletonRenderer.objectReferenceValue == null) { var foundSkeletonRenderer = follower.GetComponentInParent(); @@ -80,6 +85,7 @@ namespace Spine.Unity.Editor { skeletonRenderer.objectReferenceValue = foundSkeletonRenderer; serializedObject.ApplyModifiedProperties(); + InitializeEditor(); } var skeletonRendererValue = skeletonRenderer.objectReferenceValue as SkeletonRenderer; @@ -101,6 +107,7 @@ namespace Spine.Unity.Editor { EditorGUILayout.PropertyField(slotName, new GUIContent("Slot")); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); + InitializeEditor(); #if !NEW_PREFAB_SYSTEM if (!isInspectingPrefab) rebuildRequired = true; @@ -118,6 +125,7 @@ namespace Spine.Unity.Editor { if (clearStateChanged || triggerChanged) { serializedObject.ApplyModifiedProperties(); + InitializeEditor(); if (triggerChanged) foreach (var col in follower.colliderTable.Values) col.isTrigger = isTrigger.boolValue; diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollower.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollower.cs index 63e5e30d9..570a2cc78 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollower.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/Following/BoundingBoxFollower.cs @@ -106,7 +106,12 @@ namespace Spine.Unity { ) return; - DisposeColliders(); + slot = null; + currentAttachment = null; + currentAttachmentName = null; + currentCollider = null; + colliderTable.Clear(); + nameTable.Clear(); var skeleton = skeletonRenderer.skeleton; slot = skeleton.FindSlot(slotName); @@ -118,13 +123,16 @@ namespace Spine.Unity { return; } + int requiredCollidersCount = 0; + var colliders = GetComponents(); if (this.gameObject.activeInHierarchy) { foreach (var skin in skeleton.Data.Skins) - AddSkin(skin, slotIndex); + AddCollidersForSkin(skin, slotIndex, colliders, ref requiredCollidersCount); if (skeleton.skin != null) - AddSkin(skeleton.skin, slotIndex); + AddCollidersForSkin(skeleton.skin, slotIndex, colliders, ref requiredCollidersCount); } + DisposeExcessCollidersAfter(requiredCollidersCount); if (BoundingBoxFollower.DebugMessages) { bool valid = colliderTable.Count != 0; @@ -137,7 +145,7 @@ namespace Spine.Unity { } } - void AddSkin (Skin skin, int slotIndex) { + void AddCollidersForSkin (Skin skin, int slotIndex, PolygonCollider2D[] previousColliders, ref int collidersCount) { if (skin == null) return; var skinEntries = new List(); skin.GetAttachments(slotIndex, skinEntries); @@ -151,8 +159,11 @@ namespace Spine.Unity { if (boundingBoxAttachment != null) { if (!colliderTable.ContainsKey(boundingBoxAttachment)) { - var bbCollider = SkeletonUtility.AddBoundingBoxAsComponent(boundingBoxAttachment, slot, gameObject, isTrigger); - + var bbCollider = collidersCount < previousColliders.Length ? + previousColliders[collidersCount] : gameObject.AddComponent(); + ++collidersCount; + SkeletonUtility.SetColliderPointsLocal(bbCollider, slot, boundingBoxAttachment); + bbCollider.isTrigger = isTrigger; bbCollider.enabled = false; bbCollider.hideFlags = HideFlags.NotEditable; bbCollider.isTrigger = IsTrigger; @@ -178,33 +189,21 @@ namespace Spine.Unity { currentCollider = null; } - void DisposeColliders () { + void DisposeExcessCollidersAfter (int requiredCount) { var colliders = GetComponents(); if (colliders.Length == 0) return; - if (Application.isEditor) { - if (Application.isPlaying) { - foreach (var c in colliders) { - if (c != null) - Destroy(c); - } - } else { - foreach (var c in colliders) - if (c != null) - DestroyImmediate(c); + for (int i = requiredCount; i < colliders.Length; ++i) { + var collider = colliders[i]; + if (collider != null) { +#if UNITY_EDITOR + if (Application.isEditor && !Application.isPlaying) + DestroyImmediate(collider); + else +#endif + Destroy(collider); } - } else { - foreach (PolygonCollider2D c in colliders) - if (c != null) - Destroy(c); } - - slot = null; - currentAttachment = null; - currentAttachmentName = null; - currentCollider = null; - colliderTable.Clear(); - nameTable.Clear(); } void LateUpdate () {