[unity] Fixed BoundingBoxFollower exception in editor upon loading. Closes #1696.

This commit is contained in:
Harald Csaszar 2020-06-08 20:18:11 +02:00
parent 1707c8ce42
commit eadce3188c
2 changed files with 36 additions and 29 deletions

View File

@ -55,7 +55,7 @@ namespace Spine.Unity.Editor {
} }
} }
void OnEnable () { void InitializeEditor () {
skeletonRenderer = serializedObject.FindProperty("skeletonRenderer"); skeletonRenderer = serializedObject.FindProperty("skeletonRenderer");
slotName = serializedObject.FindProperty("slotName"); slotName = serializedObject.FindProperty("slotName");
isTrigger = serializedObject.FindProperty("isTrigger"); isTrigger = serializedObject.FindProperty("isTrigger");
@ -64,12 +64,17 @@ namespace Spine.Unity.Editor {
} }
public override void OnInspectorGUI () { public override void OnInspectorGUI () {
#if !NEW_PREFAB_SYSTEM #if !NEW_PREFAB_SYSTEM
bool isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab); bool isInspectingPrefab = (PrefabUtility.GetPrefabType(target) == PrefabType.Prefab);
#else #else
bool isInspectingPrefab = false; bool isInspectingPrefab = false;
#endif #endif
// Note: when calling InitializeEditor() in OnEnable, it throws exception
// "SerializedObjectNotCreatableException: Object at index 0 is null".
InitializeEditor();
// Try to auto-assign SkeletonRenderer field. // Try to auto-assign SkeletonRenderer field.
if (skeletonRenderer.objectReferenceValue == null) { if (skeletonRenderer.objectReferenceValue == null) {
var foundSkeletonRenderer = follower.GetComponentInParent<SkeletonRenderer>(); var foundSkeletonRenderer = follower.GetComponentInParent<SkeletonRenderer>();
@ -80,6 +85,7 @@ namespace Spine.Unity.Editor {
skeletonRenderer.objectReferenceValue = foundSkeletonRenderer; skeletonRenderer.objectReferenceValue = foundSkeletonRenderer;
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
InitializeEditor();
} }
var skeletonRendererValue = skeletonRenderer.objectReferenceValue as SkeletonRenderer; var skeletonRendererValue = skeletonRenderer.objectReferenceValue as SkeletonRenderer;
@ -101,6 +107,7 @@ namespace Spine.Unity.Editor {
EditorGUILayout.PropertyField(slotName, new GUIContent("Slot")); EditorGUILayout.PropertyField(slotName, new GUIContent("Slot"));
if (EditorGUI.EndChangeCheck()) { if (EditorGUI.EndChangeCheck()) {
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
InitializeEditor();
#if !NEW_PREFAB_SYSTEM #if !NEW_PREFAB_SYSTEM
if (!isInspectingPrefab) if (!isInspectingPrefab)
rebuildRequired = true; rebuildRequired = true;
@ -118,6 +125,7 @@ namespace Spine.Unity.Editor {
if (clearStateChanged || triggerChanged) { if (clearStateChanged || triggerChanged) {
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();
InitializeEditor();
if (triggerChanged) if (triggerChanged)
foreach (var col in follower.colliderTable.Values) foreach (var col in follower.colliderTable.Values)
col.isTrigger = isTrigger.boolValue; col.isTrigger = isTrigger.boolValue;

View File

@ -106,7 +106,12 @@ namespace Spine.Unity {
) )
return; return;
DisposeColliders(); slot = null;
currentAttachment = null;
currentAttachmentName = null;
currentCollider = null;
colliderTable.Clear();
nameTable.Clear();
var skeleton = skeletonRenderer.skeleton; var skeleton = skeletonRenderer.skeleton;
slot = skeleton.FindSlot(slotName); slot = skeleton.FindSlot(slotName);
@ -118,13 +123,16 @@ namespace Spine.Unity {
return; return;
} }
int requiredCollidersCount = 0;
var colliders = GetComponents<PolygonCollider2D>();
if (this.gameObject.activeInHierarchy) { if (this.gameObject.activeInHierarchy) {
foreach (var skin in skeleton.Data.Skins) foreach (var skin in skeleton.Data.Skins)
AddSkin(skin, slotIndex); AddCollidersForSkin(skin, slotIndex, colliders, ref requiredCollidersCount);
if (skeleton.skin != null) if (skeleton.skin != null)
AddSkin(skeleton.skin, slotIndex); AddCollidersForSkin(skeleton.skin, slotIndex, colliders, ref requiredCollidersCount);
} }
DisposeExcessCollidersAfter(requiredCollidersCount);
if (BoundingBoxFollower.DebugMessages) { if (BoundingBoxFollower.DebugMessages) {
bool valid = colliderTable.Count != 0; 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; if (skin == null) return;
var skinEntries = new List<Skin.SkinEntry>(); var skinEntries = new List<Skin.SkinEntry>();
skin.GetAttachments(slotIndex, skinEntries); skin.GetAttachments(slotIndex, skinEntries);
@ -151,8 +159,11 @@ namespace Spine.Unity {
if (boundingBoxAttachment != null) { if (boundingBoxAttachment != null) {
if (!colliderTable.ContainsKey(boundingBoxAttachment)) { if (!colliderTable.ContainsKey(boundingBoxAttachment)) {
var bbCollider = SkeletonUtility.AddBoundingBoxAsComponent(boundingBoxAttachment, slot, gameObject, isTrigger); var bbCollider = collidersCount < previousColliders.Length ?
previousColliders[collidersCount] : gameObject.AddComponent<PolygonCollider2D>();
++collidersCount;
SkeletonUtility.SetColliderPointsLocal(bbCollider, slot, boundingBoxAttachment);
bbCollider.isTrigger = isTrigger;
bbCollider.enabled = false; bbCollider.enabled = false;
bbCollider.hideFlags = HideFlags.NotEditable; bbCollider.hideFlags = HideFlags.NotEditable;
bbCollider.isTrigger = IsTrigger; bbCollider.isTrigger = IsTrigger;
@ -178,33 +189,21 @@ namespace Spine.Unity {
currentCollider = null; currentCollider = null;
} }
void DisposeColliders () { void DisposeExcessCollidersAfter (int requiredCount) {
var colliders = GetComponents<PolygonCollider2D>(); var colliders = GetComponents<PolygonCollider2D>();
if (colliders.Length == 0) return; if (colliders.Length == 0) return;
if (Application.isEditor) { for (int i = requiredCount; i < colliders.Length; ++i) {
if (Application.isPlaying) { var collider = colliders[i];
foreach (var c in colliders) { if (collider != null) {
if (c != null) #if UNITY_EDITOR
Destroy(c); if (Application.isEditor && !Application.isPlaying)
} DestroyImmediate(collider);
} else { else
foreach (var c in colliders) #endif
if (c != null) Destroy(collider);
DestroyImmediate(c);
} }
} 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 () { void LateUpdate () {