mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 17:56:04 +08:00
Merge pull request #389 from Fenrisul/master
Added BoundingBoxAttachment support to spine-unity
This commit is contained in:
commit
7d52923c84
@ -688,7 +688,9 @@ public class SkeletonDataAssetInspector : Editor {
|
|||||||
if (!EditorApplication.isPlaying)
|
if (!EditorApplication.isPlaying)
|
||||||
m_skeletonAnimation.LateUpdate();
|
m_skeletonAnimation.LateUpdate();
|
||||||
|
|
||||||
if (drawHandles) {
|
|
||||||
|
|
||||||
|
if (drawHandles) {
|
||||||
Handles.SetCamera(m_previewUtility.m_Camera);
|
Handles.SetCamera(m_previewUtility.m_Camera);
|
||||||
Handles.color = m_originColor;
|
Handles.color = m_originColor;
|
||||||
|
|
||||||
@ -697,10 +699,47 @@ public class SkeletonDataAssetInspector : Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.m_previewUtility.m_Camera.Render();
|
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<Renderer>().enabled = false;
|
go.GetComponent<Renderer>().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 () {
|
void Update () {
|
||||||
|
|||||||
@ -528,6 +528,12 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|||||||
|
|
||||||
foreach (KeyValuePair<string, object> attachmentEntry in ((Dictionary<string, object>)slotEntry.Value)) {
|
foreach (KeyValuePair<string, object> attachmentEntry in ((Dictionary<string, object>)slotEntry.Value)) {
|
||||||
var data = ((Dictionary<string, object>)attachmentEntry.Value);
|
var data = ((Dictionary<string, object>)attachmentEntry.Value);
|
||||||
|
if (data.ContainsKey("type")) {
|
||||||
|
if ((string)data["type"] == "boundingbox") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
if (data.ContainsKey("path"))
|
if (data.ContainsKey("path"))
|
||||||
requiredPaths.Add((string)data["path"]);
|
requiredPaths.Add((string)data["path"]);
|
||||||
else if (data.ContainsKey("name"))
|
else if (data.ContainsKey("name"))
|
||||||
|
|||||||
@ -49,7 +49,10 @@ public class SkeletonUtilityBoneInspector : Editor {
|
|||||||
SkeletonUtilityBone utilityBone;
|
SkeletonUtilityBone utilityBone;
|
||||||
SkeletonUtility skeletonUtility;
|
SkeletonUtility skeletonUtility;
|
||||||
bool canCreateHingeChain = false;
|
bool canCreateHingeChain = false;
|
||||||
|
|
||||||
|
Dictionary<Slot, List<BoundingBoxAttachment>> boundingBoxTable = new Dictionary<Slot, List<BoundingBoxAttachment>>();
|
||||||
|
string currentSkinName = "";
|
||||||
|
|
||||||
void OnEnable () {
|
void OnEnable () {
|
||||||
mode = this.serializedObject.FindProperty("mode");
|
mode = this.serializedObject.FindProperty("mode");
|
||||||
boneName = this.serializedObject.FindProperty("boneName");
|
boneName = this.serializedObject.FindProperty("boneName");
|
||||||
@ -69,6 +72,43 @@ public class SkeletonUtilityBoneInspector : Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
canCreateHingeChain = CanCreateHingeChain();
|
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<Attachment> attachments = new List<Attachment>();
|
||||||
|
|
||||||
|
|
||||||
|
skin.FindAttachmentsForSlot(skeleton.FindSlotIndex(slot.Data.Name), attachments);
|
||||||
|
|
||||||
|
List<BoundingBoxAttachment> boundingBoxes = new List<BoundingBoxAttachment>();
|
||||||
|
foreach (var att in attachments) {
|
||||||
|
if (att is BoundingBoxAttachment) {
|
||||||
|
boundingBoxes.Add((BoundingBoxAttachment)att);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boundingBoxes.Count > 0) {
|
||||||
|
boundingBoxTable.Add(slot, boundingBoxes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvaluateFlags () {
|
void EvaluateFlags () {
|
||||||
@ -180,6 +220,25 @@ public class SkeletonUtilityBoneInspector : Editor {
|
|||||||
}
|
}
|
||||||
GUILayout.EndHorizontal();
|
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();
|
serializedObject.ApplyModifiedProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,6 +57,50 @@ public class SkeletonUtility : MonoBehaviour {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PolygonCollider2D AddBoundingBox (Skeleton skeleton, string skinName, string slotName, string attachmentName, Transform parent, bool isTrigger = true) {
|
||||||
|
List<Attachment> attachments = new List<Attachment>();
|
||||||
|
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<PolygonCollider2D>();
|
||||||
|
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 ();
|
public delegate void SkeletonUtilityDelegate ();
|
||||||
|
|
||||||
|
|||||||
@ -287,6 +287,10 @@ public class SkeletonUtilityBone : MonoBehaviour {
|
|||||||
transform.localRotation = Quaternion.Euler(euler);
|
transform.localRotation = Quaternion.Euler(euler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddBoundingBox (string skinName, string slotName, string attachmentName) {
|
||||||
|
SkeletonUtility.AddBoundingBox(bone.skeleton, skinName, slotName, attachmentName, transform);
|
||||||
|
}
|
||||||
|
|
||||||
void OnDrawGizmos () {
|
void OnDrawGizmos () {
|
||||||
if (NonUniformScaleWarning) {
|
if (NonUniformScaleWarning) {
|
||||||
Gizmos.DrawIcon(transform.position + new Vector3(0, 0.128f, 0), "icon-warning");
|
Gizmos.DrawIcon(transform.position + new Vector3(0, 0.128f, 0), "icon-warning");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user