diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs index 5774d09be..07c439dfd 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs +++ b/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs @@ -688,7 +688,9 @@ public class SkeletonDataAssetInspector : Editor { if (!EditorApplication.isPlaying) m_skeletonAnimation.LateUpdate(); - if (drawHandles) { + + + if (drawHandles) { Handles.SetCamera(m_previewUtility.m_Camera); Handles.color = m_originColor; @@ -697,10 +699,47 @@ public class SkeletonDataAssetInspector : Editor { } this.m_previewUtility.m_Camera.Render(); + + if (drawHandles) { + Handles.SetCamera(m_previewUtility.m_Camera); + foreach (var slot in m_skeletonAnimation.skeleton.Slots) { + if (slot.Attachment is BoundingBoxAttachment) { + + DrawBoundingBox(slot.Bone, (BoundingBoxAttachment)slot.Attachment); + } + } + } + go.GetComponent().enabled = false; } + } + + void DrawBoundingBox (Bone bone, BoundingBoxAttachment box) { + float[] worldVerts = new float[box.Vertices.Length]; + box.ComputeWorldVertices(bone, worldVerts); + + Handles.color = Color.green; + Vector3 lastVert = Vector3.back; + Vector3 vert = Vector3.back; + Vector3 firstVert = new Vector3(worldVerts[0], worldVerts[1], -1); + for (int i = 0; i < worldVerts.Length; i += 2) { + vert.x = worldVerts[i]; + vert.y = worldVerts[i + 1]; + + if (i > 0) { + Handles.DrawLine(lastVert, vert); + } + + + lastVert = vert; + } + + Handles.DrawLine(lastVert, firstVert); + + + } void Update () { diff --git a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs index 4d88cf642..0ee6a02c9 100644 --- a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs +++ b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs @@ -528,6 +528,12 @@ public class SpineEditorUtilities : AssetPostprocessor { foreach (KeyValuePair attachmentEntry in ((Dictionary)slotEntry.Value)) { var data = ((Dictionary)attachmentEntry.Value); + if (data.ContainsKey("type")) { + if ((string)data["type"] == "boundingbox") { + continue; + } + + } if (data.ContainsKey("path")) requiredPaths.Add((string)data["path"]); else if (data.ContainsKey("name")) diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs index f8d6d7340..4e00582f5 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs @@ -49,7 +49,10 @@ public class SkeletonUtilityBoneInspector : Editor { SkeletonUtilityBone utilityBone; SkeletonUtility skeletonUtility; bool canCreateHingeChain = false; - + + Dictionary> boundingBoxTable = new Dictionary>(); + string currentSkinName = ""; + void OnEnable () { mode = this.serializedObject.FindProperty("mode"); boneName = this.serializedObject.FindProperty("boneName"); @@ -69,6 +72,43 @@ public class SkeletonUtilityBoneInspector : Editor { } canCreateHingeChain = CanCreateHingeChain(); + + boundingBoxTable.Clear(); + + if (multiObject) + return; + + if (utilityBone.bone == null) + return; + + var skeleton = utilityBone.bone.Skeleton; + int slotCount = skeleton.Slots.Count; + Skin skin = skeleton.Skin; + if (skeleton.Skin == null) + skin = skeleton.Data.DefaultSkin; + + currentSkinName = skin.Name; + for(int i = 0; i < slotCount; i++){ + Slot slot = skeletonUtility.skeletonRenderer.skeleton.Slots[i]; + if (slot.Bone == utilityBone.bone) { + List attachments = new List(); + + + skin.FindAttachmentsForSlot(skeleton.FindSlotIndex(slot.Data.Name), attachments); + + List boundingBoxes = new List(); + foreach (var att in attachments) { + if (att is BoundingBoxAttachment) { + boundingBoxes.Add((BoundingBoxAttachment)att); + } + } + + if (boundingBoxes.Count > 0) { + boundingBoxTable.Add(slot, boundingBoxes); + } + } + } + } void EvaluateFlags () { @@ -180,6 +220,25 @@ public class SkeletonUtilityBoneInspector : Editor { } GUILayout.EndHorizontal(); + EditorGUI.BeginDisabledGroup(multiObject || boundingBoxTable.Count == 0); + EditorGUILayout.LabelField(new GUIContent("Bounding Boxes", SpineEditorUtilities.Icons.boundingBox), EditorStyles.boldLabel); + + foreach(var entry in boundingBoxTable){ + EditorGUI.indentLevel++; + EditorGUILayout.LabelField(entry.Key.Data.Name); + EditorGUI.indentLevel++; + foreach (var box in entry.Value) { + GUILayout.BeginHorizontal(); + GUILayout.Space(30); + if (GUILayout.Button(box.Name, GUILayout.Width(200))) { + utilityBone.AddBoundingBox(currentSkinName, entry.Key.Data.Name, box.Name); + } + GUILayout.EndHorizontal(); + } + } + + EditorGUI.EndDisabledGroup(); + serializedObject.ApplyModifiedProperties(); } diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs index 519c0e313..e924a452a 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtility.cs @@ -57,6 +57,50 @@ public class SkeletonUtility : MonoBehaviour { #endif } + public static PolygonCollider2D AddBoundingBox (Skeleton skeleton, string skinName, string slotName, string attachmentName, Transform parent, bool isTrigger = true) { + List attachments = new List(); + Skin skin; + + if (skinName == "") + skinName = skeleton.Data.DefaultSkin.Name; + + skin = skeleton.Data.FindSkin(skinName); + + if (skin == null) { + Debug.LogError("Skin " + skinName + " not found!"); + return null; + } + + var attachment = skin.GetAttachment(skeleton.FindSlotIndex(slotName), attachmentName); + if (attachment is BoundingBoxAttachment) { + GameObject go = new GameObject("[BoundingBox]" + attachmentName); + go.transform.parent = parent; + go.transform.localPosition = Vector3.zero; + go.transform.localRotation = Quaternion.identity; + go.transform.localScale = Vector3.one; + var collider = go.AddComponent(); + collider.isTrigger = isTrigger; + var boundingBox = (BoundingBoxAttachment)attachment; + float[] floats = boundingBox.Vertices; + int floatCount = floats.Length; + int vertCount = floatCount / 2; + + Vector2[] verts = new Vector2[vertCount]; + int v = 0; + for (int i = 0; i < floatCount; i += 2, v++) { + verts[v].x = floats[i]; + verts[v].y = floats[i+1]; + } + + collider.SetPath(0, verts); + + return collider; + + } + + return null; + } + public delegate void SkeletonUtilityDelegate (); diff --git a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs index dc42d4677..0a3cfa410 100644 --- a/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs +++ b/spine-unity/Assets/spine-unity/SkeletonUtility/SkeletonUtilityBone.cs @@ -287,6 +287,10 @@ public class SkeletonUtilityBone : MonoBehaviour { transform.localRotation = Quaternion.Euler(euler); } + public void AddBoundingBox (string skinName, string slotName, string attachmentName) { + SkeletonUtility.AddBoundingBox(bone.skeleton, skinName, slotName, attachmentName, transform); + } + void OnDrawGizmos () { if (NonUniformScaleWarning) { Gizmos.DrawIcon(transform.position + new Vector3(0, 0.128f, 0), "icon-warning");