mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +08:00
[Unity] Added BoundingBoxFollower
This commit is contained in:
parent
e5a3cf3070
commit
a4361c6f0c
@ -57,6 +57,8 @@ public class BoneFollower : MonoBehaviour {
|
|||||||
|
|
||||||
|
|
||||||
/// <summary>If a bone isn't set, boneName is used to find the bone.</summary>
|
/// <summary>If a bone isn't set, boneName is used to find the bone.</summary>
|
||||||
|
|
||||||
|
[SpineBone(dataField: "skeletonRenderer")]
|
||||||
public String boneName;
|
public String boneName;
|
||||||
public bool resetOnAwake = true;
|
public bool resetOnAwake = true;
|
||||||
protected Transform cachedTransform;
|
protected Transform cachedTransform;
|
||||||
|
|||||||
160
spine-unity/Assets/spine-unity/BoundingBoxFollower.cs
Normal file
160
spine-unity/Assets/spine-unity/BoundingBoxFollower.cs
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Spine;
|
||||||
|
|
||||||
|
[ExecuteInEditMode]
|
||||||
|
public class BoundingBoxFollower : MonoBehaviour {
|
||||||
|
|
||||||
|
public SkeletonRenderer skeletonRenderer;
|
||||||
|
|
||||||
|
[SpineSlot(dataField: "skeletonRenderer", containsBoundingBoxes: true)]
|
||||||
|
public string slotName;
|
||||||
|
|
||||||
|
//TODO: not this
|
||||||
|
[Tooltip("LOL JK, Someone else do it!")]
|
||||||
|
public bool use3DMeshCollider;
|
||||||
|
|
||||||
|
private Slot slot;
|
||||||
|
private BoundingBoxAttachment currentAttachment;
|
||||||
|
private PolygonCollider2D currentCollider;
|
||||||
|
private string currentAttachmentName;
|
||||||
|
private bool valid = false;
|
||||||
|
private bool hasReset;
|
||||||
|
|
||||||
|
public Dictionary<BoundingBoxAttachment, PolygonCollider2D> colliderTable = new Dictionary<BoundingBoxAttachment, PolygonCollider2D>();
|
||||||
|
public Dictionary<BoundingBoxAttachment, string> attachmentNameTable = new Dictionary<BoundingBoxAttachment, string>();
|
||||||
|
|
||||||
|
public string CurrentAttachmentName {
|
||||||
|
get {
|
||||||
|
return currentAttachmentName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoundingBoxAttachment CurrentAttachment {
|
||||||
|
get {
|
||||||
|
return currentAttachment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PolygonCollider2D CurrentCollider {
|
||||||
|
get {
|
||||||
|
return currentCollider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Slot Slot {
|
||||||
|
get {
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OnEnable () {
|
||||||
|
ClearColliders();
|
||||||
|
|
||||||
|
if (skeletonRenderer == null)
|
||||||
|
skeletonRenderer = GetComponentInParent<SkeletonRenderer>();
|
||||||
|
|
||||||
|
if (skeletonRenderer != null) {
|
||||||
|
skeletonRenderer.OnReset -= HandleReset;
|
||||||
|
skeletonRenderer.OnReset += HandleReset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDisable () {
|
||||||
|
skeletonRenderer.OnReset -= HandleReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Start () {
|
||||||
|
if (!hasReset && skeletonRenderer != null)
|
||||||
|
HandleReset(skeletonRenderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void HandleReset (SkeletonRenderer renderer) {
|
||||||
|
if (slotName == null || slotName == "")
|
||||||
|
return;
|
||||||
|
|
||||||
|
hasReset = true;
|
||||||
|
|
||||||
|
ClearColliders();
|
||||||
|
colliderTable.Clear();
|
||||||
|
|
||||||
|
if (skeletonRenderer.skeleton == null) {
|
||||||
|
skeletonRenderer.OnReset -= HandleReset;
|
||||||
|
skeletonRenderer.Reset();
|
||||||
|
skeletonRenderer.OnReset += HandleReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var skeleton = skeletonRenderer.skeleton;
|
||||||
|
slot = skeleton.FindSlot(slotName);
|
||||||
|
int slotIndex = skeleton.FindSlotIndex(slotName);
|
||||||
|
|
||||||
|
foreach (var skin in skeleton.Data.Skins) {
|
||||||
|
List<string> attachmentNames = new List<string>();
|
||||||
|
skin.FindNamesForSlot(slotIndex, attachmentNames);
|
||||||
|
|
||||||
|
foreach (var name in attachmentNames) {
|
||||||
|
var attachment = skin.GetAttachment(slotIndex, name);
|
||||||
|
if (attachment is BoundingBoxAttachment) {
|
||||||
|
var collider = SkeletonUtility.AddBoundingBoxAsComponent((BoundingBoxAttachment)attachment, gameObject, true);
|
||||||
|
collider.enabled = false;
|
||||||
|
collider.hideFlags = HideFlags.HideInInspector;
|
||||||
|
colliderTable.Add((BoundingBoxAttachment)attachment, collider);
|
||||||
|
attachmentNameTable.Add((BoundingBoxAttachment)attachment, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colliderTable.Count == 0)
|
||||||
|
valid = false;
|
||||||
|
else
|
||||||
|
valid = true;
|
||||||
|
|
||||||
|
if (!valid)
|
||||||
|
Debug.LogWarning("Bounding Box Follower not valid! Slot [" + slotName + "] does not contain any Bounding Box Attachments!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearColliders () {
|
||||||
|
var colliders = GetComponents<PolygonCollider2D>();
|
||||||
|
if (Application.isPlaying) {
|
||||||
|
foreach (var c in colliders) {
|
||||||
|
Destroy(c);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach (var c in colliders) {
|
||||||
|
DestroyImmediate(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
colliderTable.Clear();
|
||||||
|
attachmentNameTable.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LateUpdate () {
|
||||||
|
if (!skeletonRenderer.valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (slot != null) {
|
||||||
|
if (slot.Attachment != currentAttachment)
|
||||||
|
SetCurrent((BoundingBoxAttachment)slot.Attachment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetCurrent (BoundingBoxAttachment attachment) {
|
||||||
|
if (currentCollider)
|
||||||
|
currentCollider.enabled = false;
|
||||||
|
|
||||||
|
if (attachment != null) {
|
||||||
|
currentCollider = colliderTable[attachment];
|
||||||
|
currentCollider.enabled = true;
|
||||||
|
} else {
|
||||||
|
currentCollider = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentAttachment = attachment;
|
||||||
|
|
||||||
|
currentAttachmentName = currentAttachment == null ? null : attachmentNameTable[attachment];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0317ee9ba6e1b1e49a030268e026d372
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
@ -35,6 +35,7 @@ using UnityEngine;
|
|||||||
public class BoneFollowerInspector : Editor {
|
public class BoneFollowerInspector : Editor {
|
||||||
private SerializedProperty boneName, skeletonRenderer, followZPosition, followBoneRotation;
|
private SerializedProperty boneName, skeletonRenderer, followZPosition, followBoneRotation;
|
||||||
BoneFollower component;
|
BoneFollower component;
|
||||||
|
bool needsReset;
|
||||||
|
|
||||||
void OnEnable () {
|
void OnEnable () {
|
||||||
skeletonRenderer = serializedObject.FindProperty("skeletonRenderer");
|
skeletonRenderer = serializedObject.FindProperty("skeletonRenderer");
|
||||||
@ -64,6 +65,12 @@ public class BoneFollowerInspector : Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public void OnInspectorGUI () {
|
override public void OnInspectorGUI () {
|
||||||
|
if (needsReset) {
|
||||||
|
component.Reset();
|
||||||
|
component.DoUpdate();
|
||||||
|
needsReset = false;
|
||||||
|
SceneView.RepaintAll();
|
||||||
|
}
|
||||||
serializedObject.Update();
|
serializedObject.Update();
|
||||||
|
|
||||||
FindRenderer();
|
FindRenderer();
|
||||||
@ -71,26 +78,16 @@ public class BoneFollowerInspector : Editor {
|
|||||||
EditorGUILayout.PropertyField(skeletonRenderer);
|
EditorGUILayout.PropertyField(skeletonRenderer);
|
||||||
|
|
||||||
if (component.valid) {
|
if (component.valid) {
|
||||||
String[] bones = new String[1];
|
EditorGUI.BeginChangeCheck();
|
||||||
try {
|
EditorGUILayout.PropertyField(boneName);
|
||||||
bones = new String[component.skeletonRenderer.skeleton.Data.Bones.Count + 1];
|
if (EditorGUI.EndChangeCheck()) {
|
||||||
} catch {
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
needsReset = true;
|
||||||
|
serializedObject.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bones[0] = "<None>";
|
|
||||||
for (int i = 0; i < bones.Length - 1; i++)
|
|
||||||
bones[i + 1] = component.skeletonRenderer.skeleton.Data.Bones[i].Name;
|
|
||||||
Array.Sort<String>(bones);
|
|
||||||
int boneIndex = Math.Max(0, Array.IndexOf(bones, boneName.stringValue));
|
|
||||||
|
|
||||||
EditorGUILayout.BeginHorizontal();
|
|
||||||
EditorGUILayout.LabelField("Bone");
|
|
||||||
EditorGUIUtility.LookLikeControls();
|
|
||||||
boneIndex = EditorGUILayout.Popup(boneIndex, bones);
|
|
||||||
EditorGUILayout.EndHorizontal();
|
|
||||||
|
|
||||||
boneName.stringValue = boneIndex == 0 ? null : bones[boneIndex];
|
|
||||||
EditorGUILayout.PropertyField(followBoneRotation);
|
EditorGUILayout.PropertyField(followBoneRotation);
|
||||||
EditorGUILayout.PropertyField(followZPosition);
|
EditorGUILayout.PropertyField(followZPosition);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -0,0 +1,53 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
[CustomEditor(typeof(BoundingBoxFollower))]
|
||||||
|
public class BoundingBoxFollowerInspector : Editor {
|
||||||
|
SerializedProperty skeletonRenderer, slotName;
|
||||||
|
BoundingBoxFollower follower;
|
||||||
|
bool needToReset = false;
|
||||||
|
|
||||||
|
void OnEnable () {
|
||||||
|
skeletonRenderer = serializedObject.FindProperty("skeletonRenderer");
|
||||||
|
slotName = serializedObject.FindProperty("slotName");
|
||||||
|
follower = (BoundingBoxFollower)target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnInspectorGUI () {
|
||||||
|
if (needToReset) {
|
||||||
|
follower.HandleReset(null);
|
||||||
|
needToReset = false;
|
||||||
|
}
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
EditorGUILayout.PropertyField(skeletonRenderer);
|
||||||
|
EditorGUILayout.PropertyField(slotName, new GUIContent("Slot"));
|
||||||
|
|
||||||
|
if (EditorGUI.EndChangeCheck()){
|
||||||
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
needToReset = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasBone = follower.GetComponent<BoneFollower>() != null;
|
||||||
|
|
||||||
|
EditorGUI.BeginDisabledGroup(hasBone || follower.Slot == null);
|
||||||
|
{
|
||||||
|
if (GUILayout.Button(new GUIContent("Add Bone Follower", SpineEditorUtilities.Icons.bone))) {
|
||||||
|
var boneFollower = follower.gameObject.AddComponent<BoneFollower>();
|
||||||
|
boneFollower.boneName = follower.Slot.Data.BoneData.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorGUI.EndDisabledGroup();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//GUILayout.Space(20);
|
||||||
|
GUILayout.Label("Attachment Names", EditorStyles.boldLabel);
|
||||||
|
foreach (var kp in follower.attachmentNameTable) {
|
||||||
|
string name = kp.Value;
|
||||||
|
var collider = follower.colliderTable[kp.Key];
|
||||||
|
bool isPlaceholder = name != kp.Key.Name;
|
||||||
|
collider.enabled = EditorGUILayout.ToggleLeft(new GUIContent(!isPlaceholder ? name : name + " [" + kp.Key.Name + "]", isPlaceholder ? SpineEditorUtilities.Icons.skinPlaceholder : SpineEditorUtilities.Icons.boundingBox), collider.enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 670a3cefa3853bd48b5da53a424fd542
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
@ -20,11 +20,8 @@ TextureImporter:
|
|||||||
isReadable: 0
|
isReadable: 0
|
||||||
grayScaleToAlpha: 0
|
grayScaleToAlpha: 0
|
||||||
generateCubemap: 0
|
generateCubemap: 0
|
||||||
cubemapConvolution: 0
|
|
||||||
cubemapConvolutionSteps: 8
|
|
||||||
cubemapConvolutionExponent: 1.5
|
|
||||||
seamlessCubemap: 0
|
seamlessCubemap: 0
|
||||||
textureFormat: -1
|
textureFormat: -3
|
||||||
maxTextureSize: 1024
|
maxTextureSize: 1024
|
||||||
textureSettings:
|
textureSettings:
|
||||||
filterMode: -1
|
filterMode: -1
|
||||||
@ -33,7 +30,6 @@ TextureImporter:
|
|||||||
wrapMode: 1
|
wrapMode: 1
|
||||||
nPOTScale: 0
|
nPOTScale: 0
|
||||||
lightmap: 0
|
lightmap: 0
|
||||||
rGBM: 0
|
|
||||||
compressionQuality: 50
|
compressionQuality: 50
|
||||||
spriteMode: 0
|
spriteMode: 0
|
||||||
spriteExtrude: 1
|
spriteExtrude: 1
|
||||||
@ -49,5 +45,3 @@ TextureImporter:
|
|||||||
sprites: []
|
sprites: []
|
||||||
spritePackingTag:
|
spritePackingTag:
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|||||||
@ -5,8 +5,8 @@ TextureImporter:
|
|||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
mipmaps:
|
mipmaps:
|
||||||
mipMapMode: 0
|
mipMapMode: 0
|
||||||
enableMipMap: 1
|
enableMipMap: 0
|
||||||
linearTexture: 0
|
linearTexture: 1
|
||||||
correctGamma: 0
|
correctGamma: 0
|
||||||
fadeOut: 0
|
fadeOut: 0
|
||||||
borderMipMap: 0
|
borderMipMap: 0
|
||||||
@ -20,20 +20,16 @@ TextureImporter:
|
|||||||
isReadable: 0
|
isReadable: 0
|
||||||
grayScaleToAlpha: 0
|
grayScaleToAlpha: 0
|
||||||
generateCubemap: 0
|
generateCubemap: 0
|
||||||
cubemapConvolution: 0
|
|
||||||
cubemapConvolutionSteps: 8
|
|
||||||
cubemapConvolutionExponent: 1.5
|
|
||||||
seamlessCubemap: 0
|
seamlessCubemap: 0
|
||||||
textureFormat: -1
|
textureFormat: -3
|
||||||
maxTextureSize: 1024
|
maxTextureSize: 1024
|
||||||
textureSettings:
|
textureSettings:
|
||||||
filterMode: -1
|
filterMode: -1
|
||||||
aniso: -1
|
aniso: 1
|
||||||
mipBias: -1
|
mipBias: -1
|
||||||
wrapMode: -1
|
wrapMode: 1
|
||||||
nPOTScale: 1
|
nPOTScale: 0
|
||||||
lightmap: 0
|
lightmap: 0
|
||||||
rGBM: 0
|
|
||||||
compressionQuality: 50
|
compressionQuality: 50
|
||||||
spriteMode: 0
|
spriteMode: 0
|
||||||
spriteExtrude: 1
|
spriteExtrude: 1
|
||||||
@ -42,12 +38,10 @@ TextureImporter:
|
|||||||
spritePivot: {x: .5, y: .5}
|
spritePivot: {x: .5, y: .5}
|
||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
spritePixelsToUnits: 100
|
spritePixelsToUnits: 100
|
||||||
alphaIsTransparency: 0
|
alphaIsTransparency: 1
|
||||||
textureType: -1
|
textureType: 2
|
||||||
buildTargetSettings: []
|
buildTargetSettings: []
|
||||||
spriteSheet:
|
spriteSheet:
|
||||||
sprites: []
|
sprites: []
|
||||||
spritePackingTag:
|
spritePackingTag:
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|||||||
@ -114,8 +114,35 @@ public class SpineSlotDrawer : PropertyDrawer {
|
|||||||
|
|
||||||
for (int i = 0; i < data.Slots.Count; i++) {
|
for (int i = 0; i < data.Slots.Count; i++) {
|
||||||
string name = data.Slots[i].Name;
|
string name = data.Slots[i].Name;
|
||||||
if (name.StartsWith(attrib.startsWith))
|
if (name.StartsWith(attrib.startsWith)) {
|
||||||
menu.AddItem(new GUIContent(name), name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property));
|
if (attrib.containsBoundingBoxes) {
|
||||||
|
|
||||||
|
int slotIndex = i;
|
||||||
|
|
||||||
|
List<Attachment> attachments = new List<Attachment>();
|
||||||
|
foreach (var skin in data.Skins) {
|
||||||
|
skin.FindAttachmentsForSlot(slotIndex, attachments);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasBoundingBox = false;
|
||||||
|
foreach (var attachment in attachments) {
|
||||||
|
if (attachment is BoundingBoxAttachment) {
|
||||||
|
menu.AddItem(new GUIContent(name), name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property));
|
||||||
|
hasBoundingBox = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasBoundingBox)
|
||||||
|
menu.AddDisabledItem(new GUIContent(name));
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
menu.AddItem(new GUIContent(name), name == property.stringValue, HandleSelect, new SpineDrawerValuePair(name, property));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.ShowAsContext();
|
menu.ShowAsContext();
|
||||||
|
|||||||
@ -149,6 +149,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|||||||
public static string editorGUIPath = "";
|
public static string editorGUIPath = "";
|
||||||
static Dictionary<int, GameObject> skeletonRendererTable;
|
static Dictionary<int, GameObject> skeletonRendererTable;
|
||||||
static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable;
|
static Dictionary<int, SkeletonUtilityBone> skeletonUtilityBoneTable;
|
||||||
|
static Dictionary<int, BoundingBoxFollower> boundingBoxFollowerTable;
|
||||||
public static float defaultScale = 0.01f;
|
public static float defaultScale = 0.01f;
|
||||||
public static float defaultMix = 0.2f;
|
public static float defaultMix = 0.2f;
|
||||||
public static string defaultShader = "Spine/Skeleton";
|
public static string defaultShader = "Spine/Skeleton";
|
||||||
@ -172,6 +173,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|||||||
|
|
||||||
skeletonRendererTable = new Dictionary<int, GameObject>();
|
skeletonRendererTable = new Dictionary<int, GameObject>();
|
||||||
skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>();
|
skeletonUtilityBoneTable = new Dictionary<int, SkeletonUtilityBone>();
|
||||||
|
boundingBoxFollowerTable = new Dictionary<int, BoundingBoxFollower>();
|
||||||
|
|
||||||
EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged;
|
EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged;
|
||||||
EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
|
EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
|
||||||
@ -188,15 +190,19 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|||||||
static void HierarchyWindowChanged () {
|
static void HierarchyWindowChanged () {
|
||||||
skeletonRendererTable.Clear();
|
skeletonRendererTable.Clear();
|
||||||
skeletonUtilityBoneTable.Clear();
|
skeletonUtilityBoneTable.Clear();
|
||||||
|
boundingBoxFollowerTable.Clear();
|
||||||
|
|
||||||
SkeletonRenderer[] arr = Object.FindObjectsOfType<SkeletonRenderer>();
|
SkeletonRenderer[] arr = Object.FindObjectsOfType<SkeletonRenderer>();
|
||||||
|
|
||||||
foreach (SkeletonRenderer r in arr)
|
foreach (SkeletonRenderer r in arr)
|
||||||
skeletonRendererTable.Add(r.gameObject.GetInstanceID(), r.gameObject);
|
skeletonRendererTable.Add(r.gameObject.GetInstanceID(), r.gameObject);
|
||||||
|
|
||||||
SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType<SkeletonUtilityBone>();
|
SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType<SkeletonUtilityBone>();
|
||||||
foreach (SkeletonUtilityBone b in boneArr)
|
foreach (SkeletonUtilityBone b in boneArr)
|
||||||
skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b);
|
skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b);
|
||||||
|
|
||||||
|
BoundingBoxFollower[] bbfArr = Object.FindObjectsOfType<BoundingBoxFollower>();
|
||||||
|
foreach (BoundingBoxFollower bbf in bbfArr)
|
||||||
|
boundingBoxFollowerTable.Add(bbf.gameObject.GetInstanceID(), bbf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HierarchyWindowItemOnGUI (int instanceId, Rect selectionRect) {
|
static void HierarchyWindowItemOnGUI (int instanceId, Rect selectionRect) {
|
||||||
@ -226,6 +232,21 @@ public class SpineEditorUtilities : AssetPostprocessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (boundingBoxFollowerTable.ContainsKey(instanceId)) {
|
||||||
|
Rect r = new Rect(selectionRect);
|
||||||
|
r.x -= 26;
|
||||||
|
|
||||||
|
if (boundingBoxFollowerTable[instanceId] != null) {
|
||||||
|
if (boundingBoxFollowerTable[instanceId].transform.childCount == 0)
|
||||||
|
r.x += 13;
|
||||||
|
|
||||||
|
r.y += 2;
|
||||||
|
|
||||||
|
r.width = 13;
|
||||||
|
r.height = 13;
|
||||||
|
|
||||||
|
GUI.DrawTexture(r, Icons.boundingBox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,6 +101,28 @@ public class SkeletonUtility : MonoBehaviour {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PolygonCollider2D AddBoundingBoxAsComponent (BoundingBoxAttachment boundingBox, GameObject gameObject, bool isTrigger = true) {
|
||||||
|
if (boundingBox == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var collider = gameObject.AddComponent<PolygonCollider2D>();
|
||||||
|
collider.isTrigger = isTrigger;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public delegate void SkeletonUtilityDelegate ();
|
public delegate void SkeletonUtilityDelegate ();
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,7 @@ using System.Collections;
|
|||||||
public class SpineSlot : PropertyAttribute {
|
public class SpineSlot : PropertyAttribute {
|
||||||
public string startsWith = "";
|
public string startsWith = "";
|
||||||
public string dataField = "";
|
public string dataField = "";
|
||||||
|
public bool containsBoundingBoxes = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Smart popup menu for Spine Slots
|
/// Smart popup menu for Spine Slots
|
||||||
@ -47,9 +48,11 @@ public class SpineSlot : PropertyAttribute {
|
|||||||
/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
|
/// Valid types are SkeletonDataAsset and SkeletonRenderer (and derivatives).
|
||||||
/// If left empty and the script the attribute is applied to is derived from Component, GetComponent<SkeletonRenderer>() will be called as a fallback.
|
/// If left empty and the script the attribute is applied to is derived from Component, GetComponent<SkeletonRenderer>() will be called as a fallback.
|
||||||
/// </param>
|
/// </param>
|
||||||
public SpineSlot(string startsWith = "", string dataField = "") {
|
/// <param name="containsBoundingBoxes">Disables popup results that don't contain bounding box attachments when true.</param>
|
||||||
|
public SpineSlot(string startsWith = "", string dataField = "", bool containsBoundingBoxes = false) {
|
||||||
this.startsWith = startsWith;
|
this.startsWith = startsWith;
|
||||||
this.dataField = dataField;
|
this.dataField = dataField;
|
||||||
|
this.containsBoundingBoxes = containsBoundingBoxes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user