diff --git a/spine-tk2d/Assets/Gizmos.meta b/spine-tk2d/Assets/Gizmos.meta
new file mode 100644
index 000000000..a7b083b0c
--- /dev/null
+++ b/spine-tk2d/Assets/Gizmos.meta
@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: a260a1ff5965c2c4f88aea3e7d433965
+folderAsset: yes
+DefaultImporter:
+ userData:
diff --git a/spine-tk2d/Assets/Gizmos/SkeletonDataAsset Icon.png b/spine-tk2d/Assets/Gizmos/SkeletonDataAsset Icon.png
new file mode 100644
index 000000000..7fd5473c1
Binary files /dev/null and b/spine-tk2d/Assets/Gizmos/SkeletonDataAsset Icon.png differ
diff --git a/spine-tk2d/Assets/Gizmos/SkeletonDataAsset Icon.png.meta b/spine-tk2d/Assets/Gizmos/SkeletonDataAsset Icon.png.meta
new file mode 100644
index 000000000..22239ca4b
--- /dev/null
+++ b/spine-tk2d/Assets/Gizmos/SkeletonDataAsset Icon.png.meta
@@ -0,0 +1,46 @@
+fileFormatVersion: 2
+guid: 68defdbc95b30a74a9ad396bfc9a2277
+TextureImporter:
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/BoneComponent.cs b/spine-tk2d/Assets/spine-tk2d/BoneFollower.cs
similarity index 80%
rename from spine-tk2d/Assets/spine-tk2d/BoneComponent.cs
rename to spine-tk2d/Assets/spine-tk2d/BoneFollower.cs
index acfe183cb..e900ba8ee 100644
--- a/spine-tk2d/Assets/spine-tk2d/BoneComponent.cs
+++ b/spine-tk2d/Assets/spine-tk2d/BoneFollower.cs
@@ -36,14 +36,14 @@ using Spine;
/// Sets a GameObject's transform to match a bone on a Spine skeleton.
[ExecuteInEditMode]
-[AddComponentMenu("Spine/BoneComponent")]
-public class BoneComponent : MonoBehaviour {
- [System.NonSerialized]
- public bool valid;
+[AddComponentMenu("Spine/BoneFollower")]
+public class BoneFollower : MonoBehaviour {
+ [System.NonSerialized]
+ public bool
+ valid;
public SkeletonRenderer skeletonRenderer;
public Bone bone;
-
public bool followZPosition = true;
public bool followBoneRotation = true;
@@ -51,46 +51,66 @@ public class BoneComponent : MonoBehaviour {
get { return skeletonRenderer; }
set {
skeletonRenderer = value;
- Reset ();
+ Reset();
}
}
- // TODO: Make the rotation behavior more customizable
- // public bool followTransformRotation = false;
-
- // TODO: Make transform follow bone scale? too specific? This is really useful for shared shadow assets.
- //public bool followBoneScale = false;
/// If a bone isn't set, boneName is used to find the bone.
public String boneName;
-
+ public bool resetOnAwake = true;
protected Transform cachedTransform;
protected Transform skeletonTransform;
-
+
+ public void HandleResetRenderer (SkeletonRenderer skeletonRenderer) {
+ Reset();
+ }
+
public void Reset () {
bone = null;
cachedTransform = transform;
valid = skeletonRenderer != null && skeletonRenderer.valid;
- if (!valid) return;
+ if (!valid)
+ return;
skeletonTransform = skeletonRenderer.transform;
+
+ skeletonRenderer.OnReset -= HandleResetRenderer;
+ skeletonRenderer.OnReset += HandleResetRenderer;
+
+ if (Application.isEditor)
+ DoUpdate();
+ }
+
+ void OnDestroy () {
+ //cleanup
+ if (skeletonRenderer != null)
+ skeletonRenderer.OnReset -= HandleResetRenderer;
}
public void Awake () {
- Reset();
+ if (resetOnAwake)
+ Reset();
}
- public void LateUpdate () {
+ void LateUpdate () {
+ DoUpdate();
+ }
+
+ public void DoUpdate () {
if (!valid) {
Reset();
return;
}
if (bone == null) {
- if (boneName == null || boneName.Length == 0) return;
+ if (boneName == null || boneName.Length == 0)
+ return;
bone = skeletonRenderer.skeleton.FindBone(boneName);
if (bone == null) {
Debug.LogError("Bone not found: " + boneName, this);
return;
+ } else {
+
}
}
@@ -100,22 +120,24 @@ public class BoneComponent : MonoBehaviour {
if (cachedTransform.parent == skeletonTransform) {
cachedTransform.localPosition = new Vector3(bone.worldX, bone.worldY, followZPosition ? 0f : cachedTransform.localPosition.z);
- if(followBoneRotation) {
+ if (followBoneRotation) {
Vector3 rotation = cachedTransform.localRotation.eulerAngles;
cachedTransform.localRotation = Quaternion.Euler(rotation.x, rotation.y, bone.worldRotation * flipRotation);
}
} else {
Vector3 targetWorldPosition = skeletonTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY, 0f));
- if(!followZPosition) targetWorldPosition.z = cachedTransform.position.z;
+ if (!followZPosition)
+ targetWorldPosition.z = cachedTransform.position.z;
cachedTransform.position = targetWorldPosition;
- if(followBoneRotation) {
+ if (followBoneRotation) {
Vector3 rotation = skeletonTransform.rotation.eulerAngles;
- cachedTransform.rotation = Quaternion.Euler(rotation.x, rotation.y,
- skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * flipRotation) );
+
+ cachedTransform.rotation = Quaternion.Euler(rotation.x, rotation.y, skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * flipRotation));
}
}
+
}
}
\ No newline at end of file
diff --git a/spine-tk2d/Assets/spine-tk2d/BoneComponent.cs.meta b/spine-tk2d/Assets/spine-tk2d/BoneFollower.cs.meta
similarity index 78%
rename from spine-tk2d/Assets/spine-tk2d/BoneComponent.cs.meta
rename to spine-tk2d/Assets/spine-tk2d/BoneFollower.cs.meta
index f2c537209..29dabc13e 100644
--- a/spine-tk2d/Assets/spine-tk2d/BoneComponent.cs.meta
+++ b/spine-tk2d/Assets/spine-tk2d/BoneFollower.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: d08aa5caf52eae44ba81cc81ca1dad5d
+guid: a1fd8daaed7b64148a34acb96ba14ce1
MonoImporter:
serializedVersion: 2
defaultReferences: []
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/BoneComponentInspector.cs b/spine-tk2d/Assets/spine-tk2d/Editor/BoneFollowerInspector.cs
similarity index 76%
rename from spine-tk2d/Assets/spine-tk2d/Editor/BoneComponentInspector.cs
rename to spine-tk2d/Assets/spine-tk2d/Editor/BoneFollowerInspector.cs
index b7373393c..943a98715 100644
--- a/spine-tk2d/Assets/spine-tk2d/Editor/BoneComponentInspector.cs
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/BoneFollowerInspector.cs
@@ -27,30 +27,57 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
-
using System;
using UnityEditor;
using UnityEngine;
-[CustomEditor(typeof(BoneComponent))]
-public class BoneComponentInspector : Editor {
+[CustomEditor(typeof(BoneFollower))]
+public class BoneFollowerInspector : Editor {
private SerializedProperty boneName, skeletonRenderer, followZPosition, followBoneRotation;
+ BoneFollower component;
void OnEnable () {
skeletonRenderer = serializedObject.FindProperty("skeletonRenderer");
boneName = serializedObject.FindProperty("boneName");
followBoneRotation = serializedObject.FindProperty("followBoneRotation");
followZPosition = serializedObject.FindProperty("followZPosition");
+ component = (BoneFollower)target;
+ ForceReload();
+ }
+
+ void FindRenderer () {
+ if (skeletonRenderer.objectReferenceValue == null) {
+ SkeletonRenderer parentRenderer = SkeletonUtility.GetInParent(component.transform);
+
+ if (parentRenderer != null) {
+ skeletonRenderer.objectReferenceValue = (UnityEngine.Object)parentRenderer;
+ }
+
+ }
+ }
+
+ void ForceReload () {
+ if (component.skeletonRenderer != null) {
+ if (component.skeletonRenderer.valid == false)
+ component.skeletonRenderer.Reset();
+ }
}
override public void OnInspectorGUI () {
serializedObject.Update();
- BoneComponent component = (BoneComponent)target;
+
+ FindRenderer();
EditorGUILayout.PropertyField(skeletonRenderer);
if (component.valid) {
- String[] bones = new String[component.skeletonRenderer.skeleton.Data.Bones.Count + 1];
+ String[] bones = new String[1];
+ try {
+ bones = new String[component.skeletonRenderer.skeleton.Data.Bones.Count + 1];
+ } catch {
+
+ }
+
bones[0] = "";
for (int i = 0; i < bones.Length - 1; i++)
bones[i + 1] = component.skeletonRenderer.skeleton.Data.Bones[i].Name;
@@ -64,13 +91,14 @@ public class BoneComponentInspector : Editor {
EditorGUILayout.EndHorizontal();
boneName.stringValue = boneIndex == 0 ? null : bones[boneIndex];
-
EditorGUILayout.PropertyField(followBoneRotation);
EditorGUILayout.PropertyField(followZPosition);
+ } else {
+ GUILayout.Label("INVALID");
}
if (serializedObject.ApplyModifiedProperties() ||
- (Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
+ (Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
) {
component.Reset();
}
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/BoneComponentInspector.cs.meta b/spine-tk2d/Assets/spine-tk2d/Editor/BoneFollowerInspector.cs.meta
similarity index 78%
rename from spine-tk2d/Assets/spine-tk2d/Editor/BoneComponentInspector.cs.meta
rename to spine-tk2d/Assets/spine-tk2d/Editor/BoneFollowerInspector.cs.meta
index 7a90e80a3..a5cf9ae89 100644
--- a/spine-tk2d/Assets/spine-tk2d/Editor/BoneComponentInspector.cs.meta
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/BoneFollowerInspector.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 99e3e8311529bbc48a5c3a5b9714e162
+guid: c71ca35fd6241cb49a0b0756a664fcf7
MonoImporter:
serializedVersion: 2
defaultReferences: []
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI.meta
new file mode 100644
index 000000000..d730a5573
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI.meta
@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: bfaea6b7e7f52bc46b8d1c3cb5e9eaa1
+folderAsset: yes
+DefaultImporter:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animation.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animation.png
new file mode 100644
index 000000000..f44d38e90
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animation.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animation.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animation.png.meta
new file mode 100644
index 000000000..6d9bc41dd
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animation.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 52b12ec801461494185a4d3dc66f3d1d
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animationRoot.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animationRoot.png
new file mode 100644
index 000000000..610754689
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animationRoot.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animationRoot.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animationRoot.png.meta
new file mode 100644
index 000000000..4bcf433e8
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-animationRoot.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 3d1be4ea889f3a14b864352fe49a1bde
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-bone.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-bone.png
new file mode 100644
index 000000000..ec66a6a85
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-bone.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-bone.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-bone.png.meta
new file mode 100644
index 000000000..9c59ed87d
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-bone.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 8322793223a533a4ca8be6f430256dfc
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boneNib.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boneNib.png
new file mode 100644
index 000000000..87373b8f0
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boneNib.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boneNib.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boneNib.png.meta
new file mode 100644
index 000000000..955598a84
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boneNib.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 97a43f11e00735147a9dc3dff6d68191
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boundingBox.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boundingBox.png
new file mode 100644
index 000000000..82beedfce
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boundingBox.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boundingBox.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boundingBox.png.meta
new file mode 100644
index 000000000..c90f54d3c
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-boundingBox.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 955aed20030d0504b8a9c6934a5cb47a
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-constraintNib.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-constraintNib.png
new file mode 100644
index 000000000..175bcb047
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-constraintNib.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-constraintNib.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-constraintNib.png.meta
new file mode 100644
index 000000000..e7ab7aca3
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-constraintNib.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: de1a4f5ad4bdf1a4ea072c4d59ba87d8
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-event.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-event.png
new file mode 100644
index 000000000..4547f254c
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-event.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-event.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-event.png.meta
new file mode 100644
index 000000000..2ab786189
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-event.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: d226a80acc775714aa78b85e16a00e9b
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-hingeChain.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-hingeChain.png
new file mode 100644
index 000000000..a27af1c7c
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-hingeChain.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-hingeChain.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-hingeChain.png.meta
new file mode 100644
index 000000000..6f346e072
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-hingeChain.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 2c2c6d283dcf3654baf40001c982891c
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ linearTexture: 0
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: -1
+ mipBias: -1
+ wrapMode: -1
+ nPOTScale: 1
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 0
+ textureType: -1
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-image.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-image.png
new file mode 100644
index 000000000..663d11350
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-image.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-image.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-image.png.meta
new file mode 100644
index 000000000..24d78a242
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-image.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 2b3a6f35bbaa8414eb51a344743ee641
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-mesh.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-mesh.png
new file mode 100644
index 000000000..1035553b7
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-mesh.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-mesh.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-mesh.png.meta
new file mode 100644
index 000000000..a98b0e9c8
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-mesh.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: a309a2e14638a204091b915126910f45
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-null.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-null.png
new file mode 100644
index 000000000..9a6d738eb
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-null.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-null.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-null.png.meta
new file mode 100644
index 000000000..a949f63a6
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-null.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: d1de1604dfe4cb64c9d31246a8e43c78
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-poseBones.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-poseBones.png
new file mode 100644
index 000000000..102700af0
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-poseBones.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-poseBones.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-poseBones.png.meta
new file mode 100644
index 000000000..c3748ea88
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-poseBones.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: da6f6d414e43aac46a57cc5a87208db4
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeleton.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeleton.png
new file mode 100644
index 000000000..b5d5adf28
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeleton.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeleton.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeleton.png.meta
new file mode 100644
index 000000000..f607575fb
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeleton.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: f2216037084d99d4481810cb521ed96f
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeletonUtility.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeletonUtility.png
new file mode 100644
index 000000000..ce4d937b2
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeletonUtility.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeletonUtility.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeletonUtility.png.meta
new file mode 100644
index 000000000..9d3c22794
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skeletonUtility.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 5bb0631368b462047869d8788673cb48
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skin.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skin.png
new file mode 100644
index 000000000..3d9bddeb4
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skin.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skin.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skin.png.meta
new file mode 100644
index 000000000..3be7a6e69
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skin.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: bfd9f3d2607e9e44c97384d7575a17dc
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinPlaceholder.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinPlaceholder.png
new file mode 100644
index 000000000..3b11d379e
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinPlaceholder.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinPlaceholder.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinPlaceholder.png.meta
new file mode 100644
index 000000000..e6ebc95cc
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinPlaceholder.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 04c82a4acf7b5244e947f2709ec3a6cf
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinsRoot.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinsRoot.png
new file mode 100644
index 000000000..289871e41
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinsRoot.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinsRoot.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinsRoot.png.meta
new file mode 100644
index 000000000..e332380e8
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-skinsRoot.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 8bd14c7643597a74ba2edc10a5e4c4ed
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-slot.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-slot.png
new file mode 100644
index 000000000..ca938722d
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-slot.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-slot.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-slot.png.meta
new file mode 100644
index 000000000..89224b580
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-slot.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 0338faf3e7d93e2478fcbc022d13e081
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-spine.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-spine.png
new file mode 100644
index 000000000..7fd5473c1
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-spine.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-spine.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-spine.png.meta
new file mode 100644
index 000000000..c0ec65ca2
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-spine.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 4e7c964fa5e07024c8bf1debecc3b7c8
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-subMeshRenderer.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-subMeshRenderer.png
new file mode 100644
index 000000000..ec7c9e64b
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-subMeshRenderer.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-subMeshRenderer.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-subMeshRenderer.png.meta
new file mode 100644
index 000000000..35500c50d
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-subMeshRenderer.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: f31c0c0d608e8ba4f9a1afb032092287
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ linearTexture: 0
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -1
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: -1
+ mipBias: -1
+ wrapMode: -1
+ nPOTScale: 1
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 0
+ textureType: -1
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-warning.png b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-warning.png
new file mode 100644
index 000000000..05e3f4cdc
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-warning.png differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-warning.png.meta b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-warning.png.meta
new file mode 100644
index 000000000..e32950ca4
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/GUI/icon-warning.png.meta
@@ -0,0 +1,47 @@
+fileFormatVersion: 2
+guid: 754d724c1bd750048852e8cf3d4a05ee
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 2
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ linearTexture: 1
+ correctGamma: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: .25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 0
+ seamlessCubemap: 0
+ textureFormat: -3
+ maxTextureSize: 1024
+ textureSettings:
+ filterMode: -1
+ aniso: 1
+ mipBias: -1
+ wrapMode: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: .5, y: .5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaIsTransparency: 1
+ textureType: 2
+ buildTargetSettings: []
+ spriteSheet:
+ sprites: []
+ spritePackingTag:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonAnimationInspector.cs b/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonAnimationInspector.cs
index bc6d6b19c..f338626b2 100644
--- a/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonAnimationInspector.cs
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonAnimationInspector.cs
@@ -27,28 +27,47 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
-
using System;
using UnityEditor;
using UnityEngine;
+using Spine;
[CustomEditor(typeof(SkeletonAnimation))]
public class SkeletonAnimationInspector : SkeletonRendererInspector {
protected SerializedProperty animationName, loop, timeScale;
+ protected bool isPrefab;
protected override void OnEnable () {
base.OnEnable();
animationName = serializedObject.FindProperty("_animationName");
loop = serializedObject.FindProperty("loop");
timeScale = serializedObject.FindProperty("timeScale");
+
+ if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
+ isPrefab = true;
+
+
}
protected override void gui () {
base.gui();
SkeletonAnimation component = (SkeletonAnimation)target;
- if (!component.valid) return;
+ if (!component.valid)
+ return;
+ //catch case where SetAnimation was used to set track 0 without using AnimationName
+ if (Application.isPlaying) {
+ TrackEntry currentState = component.state.GetCurrent(0);
+ if (currentState != null) {
+ if (component.AnimationName != animationName.stringValue) {
+ animationName.stringValue = currentState.Animation.Name;
+ }
+ }
+ }
+
+
+ //TODO: Refactor this to use GenericMenu and callbacks to avoid interfering with control by other behaviours.
// Animation name.
{
String[] animations = new String[component.skeleton.Data.Animations.Count + 1];
@@ -67,12 +86,26 @@ public class SkeletonAnimationInspector : SkeletonRendererInspector {
EditorGUILayout.EndHorizontal();
String selectedAnimationName = animationIndex == 0 ? null : animations[animationIndex];
- component.AnimationName = selectedAnimationName;
- animationName.stringValue = selectedAnimationName;
+ if (component.AnimationName != selectedAnimationName) {
+ component.AnimationName = selectedAnimationName;
+ animationName.stringValue = selectedAnimationName;
+ }
+
+
}
EditorGUILayout.PropertyField(loop);
EditorGUILayout.PropertyField(timeScale);
component.timeScale = Math.Max(component.timeScale, 0);
+
+ EditorGUILayout.Space();
+
+ if (!isPrefab) {
+ if (component.GetComponent() == null) {
+ if (GUILayout.Button(new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility), GUILayout.Height(30))) {
+ component.gameObject.AddComponent();
+ }
+ }
+ }
}
}
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonDataAssetInspector.cs b/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonDataAssetInspector.cs
index 2642d4d46..f3cf146d1 100644
--- a/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonDataAssetInspector.cs
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonDataAssetInspector.cs
@@ -28,8 +28,17 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
+/*****************************************************************************
+ * Automatic import and advanced preview added by Mitch Thompson
+ * Full irrevocable rights and permissions granted to Esoteric Software
+*****************************************************************************/
using System;
+using System.Collections.Generic;
using UnityEditor;
+
+#if !UNITY_4_3
+using UnityEditor.AnimatedValues;
+#endif
using UnityEngine;
using Spine;
@@ -37,39 +46,75 @@ using Spine;
public class SkeletonDataAssetInspector : Editor {
private SerializedProperty spriteCollection, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix;
private bool showAnimationStateData = true;
-
+
+ #if UNITY_4_3
+ private bool m_showAnimationList = true;
+ #else
+ private AnimBool m_showAnimationList = new AnimBool(true);
+ #endif
+
+ private bool m_initialized = false;
+ private SkeletonDataAsset m_skeletonDataAsset;
+ private string m_skeletonDataAssetGUID;
+
void OnEnable () {
- spriteCollection = serializedObject.FindProperty("spriteCollection");
- skeletonJSON = serializedObject.FindProperty("skeletonJSON");
- scale = serializedObject.FindProperty("scale");
- fromAnimation = serializedObject.FindProperty("fromAnimation");
- toAnimation = serializedObject.FindProperty("toAnimation");
- duration = serializedObject.FindProperty("duration");
- defaultMix = serializedObject.FindProperty("defaultMix");
- }
+ try {
+ spriteCollection = serializedObject.FindProperty("spriteCollection");
+ skeletonJSON = serializedObject.FindProperty("skeletonJSON");
+ scale = serializedObject.FindProperty("scale");
+ fromAnimation = serializedObject.FindProperty("fromAnimation");
+ toAnimation = serializedObject.FindProperty("toAnimation");
+ duration = serializedObject.FindProperty("duration");
+ defaultMix = serializedObject.FindProperty("defaultMix");
+
+ m_skeletonDataAsset = (SkeletonDataAsset)target;
+ m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));
+
+ EditorApplication.update += Update;
+
+ } catch {
+
+
+ }
+ }
+
+ void OnDestroy () {
+ m_initialized = false;
+ EditorApplication.update -= Update;
+ this.DestroyPreviewInstances();
+ if (this.m_previewUtility != null) {
+ this.m_previewUtility.Cleanup();
+ this.m_previewUtility = null;
+ }
+ }
+
override public void OnInspectorGUI () {
serializedObject.Update();
SkeletonDataAsset asset = (SkeletonDataAsset)target;
-
- tk2dSpriteCollection sprites = EditorGUILayout.ObjectField("Sprite Collection", asset.spriteCollection, typeof(tk2dSpriteCollection), false) as tk2dSpriteCollection;
- if (sprites != null)
- spriteCollection.objectReferenceValue = sprites.spriteCollection;
-
+
+ EditorGUI.BeginChangeCheck();
+ EditorGUILayout.PropertyField(spriteCollection);
EditorGUILayout.PropertyField(skeletonJSON);
EditorGUILayout.PropertyField(scale);
+ if (EditorGUI.EndChangeCheck()) {
+ if (m_previewUtility != null) {
+ m_previewUtility.Cleanup();
+ m_previewUtility = null;
+ }
+ }
SkeletonData skeletonData = asset.GetSkeletonData(asset.spriteCollection == null || asset.skeletonJSON == null);
if (skeletonData != null) {
showAnimationStateData = EditorGUILayout.Foldout(showAnimationStateData, "Animation State Data");
if (showAnimationStateData) {
EditorGUILayout.PropertyField(defaultMix);
-
- // Animation names.
+
+ // Animation names
String[] animations = new String[skeletonData.Animations.Count];
for (int i = 0; i < animations.Length; i++)
animations[i] = skeletonData.Animations[i].Name;
-
+
for (int i = 0; i < fromAnimation.arraySize; i++) {
SerializedProperty from = fromAnimation.GetArrayElementAtIndex(i);
SerializedProperty to = toAnimation.GetArrayElementAtIndex(i);
@@ -95,14 +140,471 @@ public class SkeletonDataAssetInspector : Editor {
EditorGUILayout.Space();
EditorGUILayout.EndHorizontal();
}
+
+ if (GUILayout.Button(new GUIContent("Setup Pose", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(105), GUILayout.Height(18))) {
+ StopAnimation();
+ m_skeletonAnimation.skeleton.SetToSetupPose();
+ m_requireRefresh = true;
+ }
+
+ #if UNITY_4_3
+ m_showAnimationList = EditorGUILayout.Foldout(m_showAnimationList, new GUIContent("Animations", SpineEditorUtilities.Icons.animationRoot));
+ if(m_showAnimationList){
+ #else
+ m_showAnimationList.target = EditorGUILayout.Foldout(m_showAnimationList.target, new GUIContent("Animations", SpineEditorUtilities.Icons.animationRoot));
+ if (EditorGUILayout.BeginFadeGroup(m_showAnimationList.faded)) {
+ #endif
+
+
+
+
+ EditorGUILayout.LabelField("Name", "Duration");
+ foreach (Spine.Animation a in skeletonData.Animations) {
+ GUILayout.BeginHorizontal();
+
+ if (m_skeletonAnimation != null && m_skeletonAnimation.state != null) {
+ if (m_skeletonAnimation.state.GetCurrent(0) != null && m_skeletonAnimation.state.GetCurrent(0).Animation == a) {
+ GUI.contentColor = Color.black;
+ if (GUILayout.Button("\u25BA", GUILayout.Width(24))) {
+ StopAnimation();
+ }
+ GUI.contentColor = Color.white;
+ } else {
+ if (GUILayout.Button("\u25BA", GUILayout.Width(24))) {
+ PlayAnimation(a.Name, true);
+ }
+ }
+ } else {
+ GUILayout.Label("?", GUILayout.Width(24));
+ }
+ EditorGUILayout.LabelField(new GUIContent(a.Name, SpineEditorUtilities.Icons.animation), new GUIContent(a.Duration.ToString("f3") + "s" + ("(" + (Mathf.RoundToInt(a.Duration * 30)) + ")").PadLeft(12, ' ')));
+ GUILayout.EndHorizontal();
+ }
+ }
+ #if !UNITY_4_3
+ EditorGUILayout.EndFadeGroup();
+ #endif
}
-
+
if (!Application.isPlaying) {
if (serializedObject.ApplyModifiedProperties() ||
(UnityEngine.Event.current.type == EventType.ValidateCommand && UnityEngine.Event.current.commandName == "UndoRedoPerformed")
- ) {
+ ) {
asset.Reset();
}
}
}
-}
+
+ //preview window stuff
+ private PreviewRenderUtility m_previewUtility;
+ private GameObject m_previewInstance;
+ private Vector2 previewDir;
+ private SkeletonAnimation m_skeletonAnimation;
+ private SkeletonData m_skeletonData;
+ private static int sliderHash = "Slider".GetHashCode();
+ private float m_lastTime;
+ private bool m_playing;
+ private bool m_requireRefresh;
+ private Color m_originColor = new Color(0.3f, 0.3f, 0.3f, 1);
+
+ private void StopAnimation () {
+ m_skeletonAnimation.state.ClearTrack(0);
+ m_playing = false;
+ }
+
+ List m_animEvents = new List();
+ List m_animEventFrames = new List();
+
+ private void PlayAnimation (string animName, bool loop) {
+ m_animEvents.Clear();
+ m_animEventFrames.Clear();
+
+ m_skeletonAnimation.state.SetAnimation(0, animName, loop);
+
+ Spine.Animation a = m_skeletonAnimation.state.GetCurrent(0).Animation;
+ foreach (Timeline t in a.Timelines) {
+ if (t.GetType() == typeof(EventTimeline)) {
+ EventTimeline et = (EventTimeline)t;
+
+ for (int i = 0; i < et.Events.Length; i++) {
+ m_animEvents.Add(et.Events[i]);
+ m_animEventFrames.Add(et.Frames[i]);
+ }
+
+ }
+ }
+
+ m_playing = true;
+ }
+
+ private void InitPreview () {
+ if (this.m_previewUtility == null) {
+ this.m_lastTime = Time.realtimeSinceStartup;
+ this.m_previewUtility = new PreviewRenderUtility(true);
+ this.m_previewUtility.m_Camera.isOrthoGraphic = true;
+ this.m_previewUtility.m_Camera.orthographicSize = (scale.floatValue * (m_skeletonDataAsset.spriteCollection.invOrthoSize * m_skeletonDataAsset.spriteCollection.halfTargetHeight)) / 100;
+ this.m_previewUtility.m_Camera.cullingMask = -2147483648;
+ this.CreatePreviewInstances();
+ }
+ }
+
+ private void CreatePreviewInstances () {
+ this.DestroyPreviewInstances();
+ if (this.m_previewInstance == null) {
+ string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", "");
+
+ m_previewInstance = SpineEditorUtilities.SpawnAnimatedSkeleton((SkeletonDataAsset)target, skinName).gameObject;
+ //m_previewInstance.transform.localScale = Vector3.one * 0.01f;
+ m_previewInstance.hideFlags = HideFlags.HideAndDontSave;
+ m_previewInstance.layer = 0x1f;
+
+
+ m_skeletonAnimation = m_previewInstance.GetComponent();
+ m_skeletonAnimation.initialSkinName = skinName;
+ m_skeletonAnimation.LateUpdate();
+ m_skeletonData = m_skeletonAnimation.skeletonDataAsset.GetSkeletonData(true);
+
+ m_previewInstance.renderer.enabled = false;
+
+ m_initialized = true;
+ AdjustCameraGoals(true);
+ }
+ }
+
+ private void DestroyPreviewInstances () {
+ if (this.m_previewInstance != null) {
+ DestroyImmediate(this.m_previewInstance);
+ m_previewInstance = null;
+ }
+ m_initialized = false;
+ }
+
+ public override bool HasPreviewGUI () {
+ //TODO: validate json data
+ return skeletonJSON.objectReferenceValue != null;
+ }
+
+ Texture m_previewTex = new Texture();
+
+ public override void OnInteractivePreviewGUI (Rect r, GUIStyle background) {
+ this.InitPreview();
+
+ if (UnityEngine.Event.current.type == EventType.Repaint) {
+ if (m_requireRefresh) {
+ this.m_previewUtility.BeginPreview(r, background);
+ this.DoRenderPreview(true);
+ this.m_previewTex = this.m_previewUtility.EndPreview();
+ m_requireRefresh = false;
+ }
+ if (this.m_previewTex != null)
+ GUI.DrawTexture(r, m_previewTex, ScaleMode.StretchToFill, false);
+ }
+
+ DrawSkinToolbar(r);
+ NormalizedTimeBar(r);
+ //TODO: implement panning
+ // this.previewDir = Drag2D(this.previewDir, r);
+ MouseScroll(r);
+ }
+
+ float m_orthoGoal = 1;
+ Vector3 m_posGoal = new Vector3(0, 0, -10);
+ double m_adjustFrameEndTime = 0;
+
+ private void AdjustCameraGoals (bool calculateMixTime) {
+ if (calculateMixTime) {
+ if (m_skeletonAnimation.state.GetCurrent(0) != null) {
+ m_adjustFrameEndTime = EditorApplication.timeSinceStartup + m_skeletonAnimation.state.GetCurrent(0).Mix;
+ }
+ }
+
+ GameObject go = this.m_previewInstance;
+ Bounds bounds = go.renderer.bounds;
+ m_orthoGoal = bounds.size.y;
+ m_posGoal = bounds.center + new Vector3(0, 0, -10);
+ }
+
+ private void AdjustCameraGoals () {
+ AdjustCameraGoals(false);
+ }
+
+ private void AdjustCamera () {
+ if (m_previewUtility == null)
+ return;
+
+
+ if (EditorApplication.timeSinceStartup < m_adjustFrameEndTime) {
+ AdjustCameraGoals();
+ }
+
+ float orthoSet = Mathf.Lerp(this.m_previewUtility.m_Camera.orthographicSize, m_orthoGoal, 0.1f);
+
+ this.m_previewUtility.m_Camera.orthographicSize = orthoSet;
+
+
+ float dist = Vector3.Distance(m_previewUtility.m_Camera.transform.position, m_posGoal);
+ if (dist > m_skeletonDataAsset.scale) {
+ Vector3 pos = Vector3.Lerp(this.m_previewUtility.m_Camera.transform.position, m_posGoal, 0.1f);
+ pos.x = 0;
+ this.m_previewUtility.m_Camera.transform.position = pos;
+ this.m_previewUtility.m_Camera.transform.rotation = Quaternion.identity;
+ m_requireRefresh = true;
+ }
+ }
+
+ private void DoRenderPreview (bool drawHandles) {
+ GameObject go = this.m_previewInstance;
+
+ if (m_requireRefresh) {
+ go.renderer.enabled = true;
+
+ if (EditorApplication.isPlaying) {
+ //do nothing
+ } else {
+ m_skeletonAnimation.Update((Time.realtimeSinceStartup - m_lastTime));
+ }
+
+ m_lastTime = Time.realtimeSinceStartup;
+
+ if (!EditorApplication.isPlaying)
+ m_skeletonAnimation.LateUpdate();
+
+ if (drawHandles) {
+ Handles.SetCamera(m_previewUtility.m_Camera);
+ Handles.color = m_originColor;
+
+ Handles.DrawLine(new Vector3(-1000 * m_skeletonDataAsset.scale, 0, 0), new Vector3(1000 * m_skeletonDataAsset.scale, 0, 0));
+ Handles.DrawLine(new Vector3(0, 1000 * m_skeletonDataAsset.scale, 0), new Vector3(0, -1000 * m_skeletonDataAsset.scale, 0));
+ }
+
+ this.m_previewUtility.m_Camera.Render();
+ go.renderer.enabled = false;
+ }
+
+
+ }
+
+ void Update () {
+ AdjustCamera();
+
+ if (m_playing) {
+ m_requireRefresh = true;
+ Repaint();
+ } else if (m_requireRefresh) {
+ Repaint();
+ } else {
+ #if !UNITY_4_3
+ if (m_showAnimationList.isAnimating)
+ Repaint();
+ #endif
+ }
+ }
+
+ void DrawSkinToolbar (Rect r) {
+ if (m_skeletonAnimation == null)
+ return;
+
+ if (m_skeletonAnimation.skeleton != null) {
+ string label = (m_skeletonAnimation.skeleton != null && m_skeletonAnimation.skeleton.Skin != null) ? m_skeletonAnimation.skeleton.Skin.Name : "default";
+
+ Rect popRect = new Rect(r);
+ popRect.y += 32;
+ popRect.x += 4;
+ popRect.height = 24;
+ popRect.width = 40;
+ EditorGUI.DropShadowLabel(popRect, new GUIContent("Skin", SpineEditorUtilities.Icons.skinsRoot));
+
+ popRect.y += 11;
+ popRect.width = 150;
+ popRect.x += 44;
+
+ if (GUI.Button(popRect, label, EditorStyles.popup)) {
+ SelectSkinContext();
+ }
+ }
+ }
+
+ void SelectSkinContext () {
+ GenericMenu menu = new GenericMenu();
+
+ foreach (Skin s in m_skeletonData.Skins) {
+ menu.AddItem(new GUIContent(s.Name), this.m_skeletonAnimation.skeleton.Skin == s, SetSkin, (object)s);
+ }
+
+ menu.ShowAsContext();
+ }
+
+ void SetSkin (object o) {
+ Skin skin = (Skin)o;
+
+ m_skeletonAnimation.initialSkinName = skin.Name;
+ m_skeletonAnimation.Reset();
+ m_requireRefresh = true;
+
+ EditorPrefs.SetString(m_skeletonDataAssetGUID + "_lastSkin", skin.Name);
+ }
+
+ void NormalizedTimeBar (Rect r) {
+ Rect barRect = new Rect(r);
+ barRect.height = 32;
+ barRect.x += 4;
+ barRect.width -= 4;
+
+ GUI.Box(barRect, "");
+
+ Rect lineRect = new Rect(barRect);
+ float width = lineRect.width;
+ TrackEntry t = m_skeletonAnimation.state.GetCurrent(0);
+
+ if (t != null) {
+ int loopCount = (int)(t.Time / t.EndTime);
+ float currentTime = t.Time - (t.EndTime * loopCount);
+
+ float normalizedTime = currentTime / t.Animation.Duration;
+
+ lineRect.x = barRect.x + (width * normalizedTime) - 0.5f;
+ lineRect.width = 2;
+
+ GUI.color = Color.red;
+ GUI.DrawTexture(lineRect, EditorGUIUtility.whiteTexture);
+ GUI.color = Color.white;
+
+ for (int i = 0; i < m_animEvents.Count; i++) {
+ //TODO: Tooltip
+ //Spine.Event spev = animEvents[i];
+
+ float fr = m_animEventFrames[i];
+
+ Rect evRect = new Rect(barRect);
+ evRect.x = Mathf.Clamp(((fr / t.Animation.Duration) * width) - (SpineEditorUtilities.Icons._event.width / 2), barRect.x, float.MaxValue);
+ evRect.width = SpineEditorUtilities.Icons._event.width;
+ evRect.height = SpineEditorUtilities.Icons._event.height;
+ evRect.y += SpineEditorUtilities.Icons._event.height;
+ GUI.DrawTexture(evRect, SpineEditorUtilities.Icons._event);
+
+
+ //TODO: Tooltip
+ /*
+ UnityEngine.Event ev = UnityEngine.Event.current;
+ if(ev.isMouse){
+ if(evRect.Contains(ev.mousePosition)){
+ Rect tooltipRect = new Rect(evRect);
+ tooltipRect.width = 500;
+ tooltipRect.y -= 4;
+ tooltipRect.x += 4;
+ GUI.Label(tooltipRect, spev.Data.Name);
+ }
+ }
+ */
+ }
+ }
+ }
+
+ void MouseScroll (Rect position) {
+ UnityEngine.Event current = UnityEngine.Event.current;
+ int controlID = GUIUtility.GetControlID(sliderHash, FocusType.Passive);
+
+ switch (current.GetTypeForControl(controlID)) {
+ case EventType.ScrollWheel:
+ if (position.Contains(current.mousePosition)) {
+
+ m_orthoGoal += current.delta.y * ((SkeletonDataAsset)target).scale * 10;
+ GUIUtility.hotControl = controlID;
+ current.Use();
+ }
+ break;
+ }
+
+ }
+
+ //TODO: Implement preview panning
+ /*
+ static Vector2 Drag2D(Vector2 scrollPosition, Rect position)
+ {
+ int controlID = GUIUtility.GetControlID(sliderHash, FocusType.Passive);
+ UnityEngine.Event current = UnityEngine.Event.current;
+ switch (current.GetTypeForControl(controlID))
+ {
+ case EventType.MouseDown:
+ if (position.Contains(current.mousePosition) && (position.width > 50f))
+ {
+ GUIUtility.hotControl = controlID;
+ current.Use();
+ EditorGUIUtility.SetWantsMouseJumping(1);
+ }
+ return scrollPosition;
+
+ case EventType.MouseUp:
+ if (GUIUtility.hotControl == controlID)
+ {
+ GUIUtility.hotControl = 0;
+ }
+ EditorGUIUtility.SetWantsMouseJumping(0);
+ return scrollPosition;
+
+ case EventType.MouseMove:
+ return scrollPosition;
+
+ case EventType.MouseDrag:
+ if (GUIUtility.hotControl == controlID)
+ {
+ scrollPosition -= (Vector2) (((current.delta * (!current.shift ? ((float) 1) : ((float) 3))) / Mathf.Min(position.width, position.height)) * 140f);
+ scrollPosition.y = Mathf.Clamp(scrollPosition.y, -90f, 90f);
+ current.Use();
+ GUI.changed = true;
+ }
+ return scrollPosition;
+ }
+ return scrollPosition;
+ }
+ */
+
+ public override GUIContent GetPreviewTitle () {
+ return new GUIContent("Preview");
+ }
+
+ public override void OnPreviewSettings () {
+ if (!m_initialized) {
+ GUILayout.HorizontalSlider(0, 0, 2, GUILayout.MaxWidth(64));
+ } else {
+ float speed = GUILayout.HorizontalSlider(m_skeletonAnimation.timeScale, 0, 2, GUILayout.MaxWidth(64));
+
+ //snap to nearest 0.25
+ float y = speed / 0.25f;
+ int q = Mathf.RoundToInt(y);
+ speed = q * 0.25f;
+
+ m_skeletonAnimation.timeScale = speed;
+ }
+ }
+
+ //TODO: Fix first-import error
+ //TODO: Update preview without thumbnail
+ public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) {
+ Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false);
+
+ this.InitPreview();
+
+ if (this.m_previewUtility.m_Camera == null)
+ return null;
+
+ m_requireRefresh = true;
+ this.DoRenderPreview(false);
+ AdjustCameraGoals(false);
+
+ this.m_previewUtility.m_Camera.orthographicSize = m_orthoGoal / 2;
+ this.m_previewUtility.m_Camera.transform.position = m_posGoal;
+ this.m_previewUtility.BeginStaticPreview(new Rect(0, 0, width, height));
+ this.DoRenderPreview(false);
+
+ //TODO: Figure out why this is throwing errors on first attempt
+ // if(m_previewUtility != null){
+ // Handles.SetCamera(this.m_previewUtility.m_Camera);
+ // Handles.BeginGUI();
+ // GUI.DrawTexture(new Rect(40,60,width,height), SpineEditorUtilities.Icons.spine, ScaleMode.StretchToFill);
+ // Handles.EndGUI();
+ // }
+ tex = this.m_previewUtility.EndStaticPreview();
+ return tex;
+ }
+}
\ No newline at end of file
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonDataAssetInspector.cs.meta b/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonDataAssetInspector.cs.meta
index e7eaac24c..fba64b6e3 100644
--- a/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonDataAssetInspector.cs.meta
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/SkeletonDataAssetInspector.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: cffb121e3cd80644d84c585b9c7448e8
+guid: 01cbef8f24d105f4bafa9668d669e040
MonoImporter:
serializedVersion: 2
defaultReferences: []
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/SpineEditorUtilities.cs b/spine-tk2d/Assets/spine-tk2d/Editor/SpineEditorUtilities.cs
new file mode 100644
index 000000000..7bb412ce6
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/SpineEditorUtilities.cs
@@ -0,0 +1,268 @@
+#pragma warning disable 0219
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.1
+ *
+ * Copyright (c) 2013, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable and
+ * non-transferable license to install, execute and perform the Spine Runtimes
+ * Software (the "Software") solely for internal use. Without the written
+ * permission of Esoteric Software (typically granted by licensing Spine), you
+ * may not (a) modify, translate, adapt or otherwise create derivative works,
+ * improvements of the Software or develop new applications using the Software
+ * or (b) remove, delete, alter or obscure any trademarks or any copyright,
+ * trademark, patent or other intellectual property or proprietary rights
+ * notices on or in the Software, including any copy thereof. Redistributions
+ * in binary or source form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Spine Editor Utilities created by Mitch Thompson
+ * Full irrevocable rights and permissions granted to Esoteric Software
+*****************************************************************************/
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Spine;
+
+[InitializeOnLoad]
+public class SpineEditorUtilities : AssetPostprocessor {
+
+ public static class Icons {
+ public static Texture2D skeleton;
+ public static Texture2D nullBone;
+ public static Texture2D bone;
+ public static Texture2D poseBones;
+ public static Texture2D boneNib;
+ public static Texture2D slot;
+ public static Texture2D skinPlaceholder;
+ public static Texture2D image;
+ public static Texture2D boundingBox;
+ public static Texture2D mesh;
+ public static Texture2D skin;
+ public static Texture2D skinsRoot;
+ public static Texture2D animation;
+ public static Texture2D animationRoot;
+ public static Texture2D spine;
+ public static Texture2D _event;
+ public static Texture2D constraintNib;
+ public static Texture2D warning;
+ public static Texture2D skeletonUtility;
+ public static Texture2D hingeChain;
+ public static Texture2D subMeshRenderer;
+
+ public static Mesh boneMesh {
+ get {
+ if (_boneMesh == null) {
+ _boneMesh = new Mesh();
+ _boneMesh.vertices = new Vector3[4] {
+ Vector3.zero,
+ new Vector3(-0.1f, 0.1f, 0),
+ Vector3.up,
+ new Vector3(0.1f, 0.1f, 0)
+ };
+ _boneMesh.uv = new Vector2[4];
+ _boneMesh.triangles = new int[6]{0,1,2,2,3,0};
+ _boneMesh.RecalculateBounds();
+ _boneMesh.RecalculateNormals();
+ }
+
+ return _boneMesh;
+ }
+ }
+
+ internal static Mesh _boneMesh;
+
+ public static Material boneMaterial {
+ get {
+ if (_boneMaterial == null) {
+#if UNITY_4_3
+ _boneMaterial = new Material(Shader.Find("Particles/Alpha Blended"));
+ _boneMaterial.SetColor("_TintColor", new Color(0.4f, 0.4f, 0.4f, 0.25f));
+#else
+ _boneMaterial = new Material(Shader.Find("Spine/Bones"));
+ _boneMaterial.SetColor("_Color", new Color(0.4f, 0.4f, 0.4f, 0.25f));
+#endif
+
+ }
+
+ return _boneMaterial;
+ }
+ }
+
+ internal static Material _boneMaterial;
+
+ public static void Initialize () {
+ skeleton = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skeleton.png");
+ nullBone = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-null.png");
+ bone = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-bone.png");
+ poseBones = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-poseBones.png");
+ boneNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-boneNib.png");
+ slot = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-slot.png");
+ skinPlaceholder = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skinPlaceholder.png");
+ image = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-image.png");
+ boundingBox = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-boundingBox.png");
+ mesh = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-mesh.png");
+ skin = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skinPlaceholder.png");
+ skinsRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skinsRoot.png");
+ animation = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-animation.png");
+ animationRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-animationRoot.png");
+ spine = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-spine.png");
+ _event = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-event.png");
+ constraintNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-constraintNib.png");
+ warning = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-warning.png");
+ skeletonUtility = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skeletonUtility.png");
+ hingeChain = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-hingeChain.png");
+ subMeshRenderer = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-subMeshRenderer.png");
+ }
+ }
+
+ public static string editorPath = "";
+ public static string editorGUIPath = "";
+ static Dictionary skeletonRendererTable;
+ static Dictionary skeletonUtilityBoneTable;
+ public static float defaultScale = 0.01f;
+ public static float defaultMix = 0.2f;
+ public static string defaultShader = "Spine/Skeleton";
+
+ static SpineEditorUtilities () {
+ DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath);
+ FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories);
+ editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets"));
+ editorGUIPath = editorPath + "/GUI";
+
+ Icons.Initialize();
+
+ skeletonRendererTable = new Dictionary();
+ skeletonUtilityBoneTable = new Dictionary();
+
+ EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged;
+ EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
+
+ HierarchyWindowChanged();
+ }
+
+ static void HierarchyWindowChanged () {
+ skeletonRendererTable.Clear();
+ skeletonUtilityBoneTable.Clear();
+
+ SkeletonRenderer[] arr = Object.FindObjectsOfType();
+
+ foreach (SkeletonRenderer r in arr)
+ skeletonRendererTable.Add(r.gameObject.GetInstanceID(), r.gameObject);
+
+ SkeletonUtilityBone[] boneArr = Object.FindObjectsOfType();
+ foreach (SkeletonUtilityBone b in boneArr)
+ skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b);
+ }
+
+ static void HierarchyWindowItemOnGUI (int instanceId, Rect selectionRect) {
+ if (skeletonRendererTable.ContainsKey(instanceId)) {
+ Rect r = new Rect(selectionRect);
+ r.x = r.width - 15;
+ r.width = 15;
+
+ GUI.Label(r, Icons.spine);
+ } else if (skeletonUtilityBoneTable.ContainsKey(instanceId)) {
+ Rect r = new Rect(selectionRect);
+ r.x -= 26;
+
+ if (skeletonUtilityBoneTable[instanceId] != null) {
+ if (skeletonUtilityBoneTable[instanceId].transform.childCount == 0)
+ r.x += 13;
+
+ r.y += 2;
+
+ r.width = 13;
+ r.height = 13;
+
+ if (skeletonUtilityBoneTable[instanceId].mode == SkeletonUtilityBone.Mode.Follow) {
+ GUI.DrawTexture(r, Icons.bone);
+ } else {
+ GUI.DrawTexture(r, Icons.poseBones);
+ }
+ }
+
+ }
+
+ }
+
+ [MenuItem("Assets/Spine/Spawn")]
+ static void SpawnAnimatedSkeleton () {
+ Object[] arr = Selection.objects;
+ foreach (Object o in arr) {
+ string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o));
+ string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
+
+ SpawnAnimatedSkeleton((SkeletonDataAsset)o, skinName);
+ SceneView.RepaintAll();
+ }
+ }
+
+ [MenuItem("Assets/Spine/Spawn", true)]
+ static bool ValidateSpawnAnimatedSkeleton () {
+ Object[] arr = Selection.objects;
+
+ if (arr.Length == 0)
+ return false;
+
+ foreach (Object o in arr) {
+ if (o.GetType() != typeof(SkeletonDataAsset))
+ return false;
+ }
+
+ return true;
+ }
+
+ public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, string skinName) {
+ return SpawnAnimatedSkeleton(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
+ }
+
+ public static SkeletonAnimation SpawnAnimatedSkeleton (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
+ GameObject go = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
+ SkeletonAnimation anim = go.GetComponent();
+ anim.skeletonDataAsset = skeletonDataAsset;
+
+
+
+ SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
+
+ if (data == null) {
+ return null;
+ }
+
+ if (skin == null)
+ skin = data.DefaultSkin;
+
+ if (skin == null)
+ skin = data.Skins[0];
+
+ anim.Reset();
+
+ anim.skeleton.SetSkin(skin);
+ anim.initialSkinName = skin.Name;
+
+ anim.skeleton.Update(1);
+ anim.state.Update(1);
+ anim.state.Apply(anim.skeleton);
+ anim.skeleton.UpdateWorldTransform();
+
+ return anim;
+ }
+}
diff --git a/spine-tk2d/Assets/spine-tk2d/Editor/SpineEditorUtilities.cs.meta b/spine-tk2d/Assets/spine-tk2d/Editor/SpineEditorUtilities.cs.meta
new file mode 100644
index 000000000..544e47769
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Editor/SpineEditorUtilities.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f834d5cd806ec4645915ac315edbdc60
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Shaders/Bones.shader b/spine-tk2d/Assets/spine-tk2d/Shaders/Bones.shader
new file mode 100644
index 000000000..61fc977e5
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Shaders/Bones.shader
@@ -0,0 +1,69 @@
+Shader "Spine/Bones" {
+Properties {
+ _Color ("Color", Color) = (0.5,0.5,0.5,0.5)
+ _MainTex ("Particle Texture", 2D) = "white" {}
+}
+
+Category {
+ Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
+ Blend SrcAlpha OneMinusSrcAlpha
+ AlphaTest Greater .01
+ ColorMask RGB
+
+ Lighting Off Cull Off ZTest Always ZWrite Off Fog { Mode Off }
+
+ SubShader {
+ Pass {
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #pragma multi_compile_particles
+
+ #include "UnityCG.cginc"
+
+ sampler2D _MainTex;
+ fixed4 _Color;
+
+ struct appdata_t {
+ float4 vertex : POSITION;
+ fixed4 color : COLOR;
+ float2 texcoord : TEXCOORD0;
+ };
+
+ struct v2f {
+ float4 vertex : SV_POSITION;
+ fixed4 color : COLOR;
+ float2 texcoord : TEXCOORD0;
+ #ifdef SOFTPARTICLES_ON
+ float4 projPos : TEXCOORD1;
+ #endif
+ };
+
+ float4 _MainTex_ST;
+
+ v2f vert (appdata_t v)
+ {
+ v2f o;
+ o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
+ #ifdef SOFTPARTICLES_ON
+ o.projPos = ComputeScreenPos (o.vertex);
+ COMPUTE_EYEDEPTH(o.projPos.z);
+ #endif
+ o.color = v.color;
+ o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
+ return o;
+ }
+
+ sampler2D_float _CameraDepthTexture;
+
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ return 2.0f * i.color * _Color * tex2D(_MainTex, i.texcoord);
+ }
+ ENDCG
+ }
+ }
+}
+}
diff --git a/spine-tk2d/Assets/spine-tk2d/Shaders/Bones.shader.meta b/spine-tk2d/Assets/spine-tk2d/Shaders/Bones.shader.meta
new file mode 100644
index 000000000..d01814ef9
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Shaders/Bones.shader.meta
@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: 66988de88a15abd4e8846c6805485f57
+ShaderImporter:
+ defaultTextures: []
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.mat b/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.mat
new file mode 100644
index 000000000..31cf39d99
Binary files /dev/null and b/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.mat differ
diff --git a/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.mat.meta b/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.mat.meta
new file mode 100644
index 000000000..ef267ef07
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.mat.meta
@@ -0,0 +1,4 @@
+fileFormatVersion: 2
+guid: 43227e5adadc6f24bb4bf74b92a56fb4
+NativeFormatImporter:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.shader b/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.shader
new file mode 100644
index 000000000..3a0de6756
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.shader
@@ -0,0 +1,21 @@
+Shader "Spine/HiddenPass" {
+ SubShader
+
+ {
+
+ Tags {"Queue" = "Geometry-1" }
+
+ Lighting Off
+
+ Pass
+
+ {
+
+ ZWrite Off
+
+ ColorMask 0
+
+ }
+
+ }
+}
diff --git a/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.shader.meta b/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.shader.meta
new file mode 100644
index 000000000..bcc031d30
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/Shaders/HiddenPass.shader.meta
@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: 913475501bf19374c84390868a9d6d3d
+ShaderImporter:
+ defaultTextures: []
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonAnimation.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonAnimation.cs
index 8810a5383..0c4c9a44f 100644
--- a/spine-tk2d/Assets/spine-tk2d/SkeletonAnimation.cs
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonAnimation.cs
@@ -41,18 +41,23 @@ public class SkeletonAnimation : SkeletonRenderer {
public bool loop;
public Spine.AnimationState state;
- public delegate void UpdateBonesDelegate(SkeletonAnimation skeleton);
- public UpdateBonesDelegate UpdateBones;
+ public delegate void UpdateBonesDelegate (SkeletonAnimation skeleton);
+ public UpdateBonesDelegate UpdateLocal;
+ public UpdateBonesDelegate UpdateWorld;
+ public UpdateBonesDelegate UpdateComplete;
[SerializeField]
- private String _animationName;
+ private String
+ _animationName;
+
public String AnimationName {
get {
TrackEntry entry = state.GetCurrent(0);
return entry == null ? null : entry.Animation.Name;
}
set {
- if (_animationName == value) return;
+ if (_animationName == value)
+ return;
_animationName = value;
if (value == null || value.Length == 0)
state.ClearTrack(0);
@@ -63,7 +68,8 @@ public class SkeletonAnimation : SkeletonRenderer {
public override void Reset () {
base.Reset();
- if (!valid) return;
+ if (!valid)
+ return;
state = new Spine.AnimationState(skeletonDataAsset.GetAnimationStateData());
if (_animationName != null && _animationName.Length > 0) {
@@ -77,13 +83,26 @@ public class SkeletonAnimation : SkeletonRenderer {
}
public virtual void Update (float deltaTime) {
- if (!valid) return;
+ if (!valid)
+ return;
deltaTime *= timeScale;
skeleton.Update(deltaTime);
state.Update(deltaTime);
state.Apply(skeleton);
- if (UpdateBones != null) UpdateBones(this);
+
+ if (UpdateLocal != null)
+ UpdateLocal(this);
+
skeleton.UpdateWorldTransform();
+
+ if (UpdateWorld != null) {
+ UpdateWorld(this);
+ skeleton.UpdateWorldTransform();
+ }
+
+ if (UpdateComplete != null) {
+ UpdateComplete(this);
+ }
}
}
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonDataAsset.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonDataAsset.cs
index 9323a2d31..3e760787e 100644
--- a/spine-tk2d/Assets/spine-tk2d/SkeletonDataAsset.cs
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonDataAsset.cs
@@ -53,14 +53,14 @@ public class SkeletonDataAsset : ScriptableObject {
public SkeletonData GetSkeletonData (bool quiet) {
if (spriteCollection == null) {
if (!quiet)
- Debug.LogError("Sprite collection not set for skeleton data asset: " + name, this);
+ Debug.LogError("SpriteCollection not set for SkeletonData asset: " + name, this);
Reset();
return null;
}
-
+
if (skeletonJSON == null) {
if (!quiet)
- Debug.LogError("Skeleton JSON file not set for skeleton data asset: " + name, this);
+ Debug.LogError("Skeleton JSON file not set for SkeletonData asset: " + name, this);
Reset();
return null;
}
@@ -81,7 +81,8 @@ public class SkeletonDataAsset : ScriptableObject {
stateData = new AnimationStateData(skeletonData);
stateData.DefaultMix = defaultMix;
for (int i = 0, n = fromAnimation.Length; i < n; i++) {
- if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0) continue;
+ if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0)
+ continue;
stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]);
}
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonExtensions.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonExtensions.cs
new file mode 100644
index 000000000..a483e47e6
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonExtensions.cs
@@ -0,0 +1,108 @@
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.1
+ *
+ * Copyright (c) 2013, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable and
+ * non-transferable license to install, execute and perform the Spine Runtimes
+ * Software (the "Software") solely for internal use. Without the written
+ * permission of Esoteric Software (typically granted by licensing Spine), you
+ * may not (a) modify, translate, adapt or otherwise create derivative works,
+ * improvements of the Software or develop new applications using the Software
+ * or (b) remove, delete, alter or obscure any trademarks or any copyright,
+ * trademark, patent or other intellectual property or proprietary rights
+ * notices on or in the Software, including any copy thereof. Redistributions
+ * in binary or source form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Spine Extensions created by Mitch Thompson
+ * Full irrevocable rights and permissions granted to Esoteric Software
+*****************************************************************************/
+
+using UnityEngine;
+using System.Collections;
+using Spine;
+
+public static class SkeletonExtensions {
+
+ public static void SetColor (this Slot slot, Color color) {
+ slot.A = color.a;
+ slot.R = color.r;
+ slot.G = color.g;
+ slot.B = color.b;
+ }
+
+ public static void SetColor (this Slot slot, Color32 color) {
+ slot.A = color.a / 255f;
+ slot.R = color.r / 255f;
+ slot.G = color.g / 255f;
+ slot.B = color.b / 255f;
+ }
+
+ public static void SetColor (this RegionAttachment attachment, Color color) {
+ attachment.A = color.a;
+ attachment.R = color.r;
+ attachment.G = color.g;
+ attachment.B = color.b;
+ }
+
+ public static void SetColor (this RegionAttachment attachment, Color32 color) {
+ attachment.A = color.a / 255f;
+ attachment.R = color.r / 255f;
+ attachment.G = color.g / 255f;
+ attachment.B = color.b / 255f;
+ }
+
+ public static void SetColor (this MeshAttachment attachment, Color color) {
+ attachment.A = color.a;
+ attachment.R = color.r;
+ attachment.G = color.g;
+ attachment.B = color.b;
+ }
+
+ public static void SetColor (this MeshAttachment attachment, Color32 color) {
+ attachment.A = color.a / 255f;
+ attachment.R = color.r / 255f;
+ attachment.G = color.g / 255f;
+ attachment.B = color.b / 255f;
+ }
+
+ public static void SetColor (this SkinnedMeshAttachment attachment, Color color) {
+ attachment.A = color.a;
+ attachment.R = color.r;
+ attachment.G = color.g;
+ attachment.B = color.b;
+ }
+
+ public static void SetColor (this SkinnedMeshAttachment attachment, Color32 color) {
+ attachment.A = color.a / 255f;
+ attachment.R = color.r / 255f;
+ attachment.G = color.g / 255f;
+ attachment.B = color.b / 255f;
+ }
+
+ public static void SetPosition (this Bone bone, Vector2 position) {
+ bone.X = position.x;
+ bone.Y = position.y;
+ }
+
+ public static void SetPosition (this Bone bone, Vector3 position) {
+ bone.X = position.x;
+ bone.Y = position.y;
+ }
+
+}
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonExtensions.cs.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonExtensions.cs.meta
new file mode 100644
index 000000000..427cdd10a
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonExtensions.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ea85c8f6a91a6ab45881b0dbdaabb7d0
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonRenderer.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonRenderer.cs
index 355ac0e46..5f4da3adb 100644
--- a/spine-tk2d/Assets/spine-tk2d/SkeletonRenderer.cs
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonRenderer.cs
@@ -37,17 +37,20 @@ using Spine;
/// Renders a skeleton.
[ExecuteInEditMode, RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SkeletonRenderer : MonoBehaviour {
+
+ public delegate void SkeletonRendererDelegate (SkeletonRenderer skeletonRenderer);
+
+ public SkeletonRendererDelegate OnReset;
[System.NonSerialized]
public bool valid;
[System.NonSerialized]
public Skeleton skeleton;
-
public SkeletonDataAsset skeletonDataAsset;
public String initialSkinName;
public bool calculateNormals, calculateTangents;
public float zSpacing;
public bool renderMeshes = true, immutableTriangles;
-
+ public bool logErrors = false;
private MeshFilter meshFilter;
private Mesh mesh, mesh1, mesh2;
private bool useMesh1;
@@ -61,9 +64,12 @@ public class SkeletonRenderer : MonoBehaviour {
private readonly List submeshes = new List();
public virtual void Reset () {
- if (meshFilter != null) meshFilter.sharedMesh = null;
- if (mesh != null) DestroyImmediate(mesh);
- if (renderer != null) renderer.sharedMaterial = null;
+ if (meshFilter != null)
+ meshFilter.sharedMesh = null;
+ if (mesh != null)
+ DestroyImmediate(mesh);
+ if (renderer != null)
+ renderer.sharedMaterial = null;
mesh = null;
mesh1 = null;
mesh2 = null;
@@ -78,11 +84,14 @@ public class SkeletonRenderer : MonoBehaviour {
valid = false;
if (!skeletonDataAsset) {
- Debug.LogError("Missing SkeletonData asset.", this);
+ if (logErrors)
+ Debug.LogError("Missing SkeletonData asset.", this);
+
return;
}
SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false);
- if (skeletonData == null) return;
+ if (skeletonData == null)
+ return;
valid = true;
meshFilter = GetComponent();
@@ -93,6 +102,8 @@ public class SkeletonRenderer : MonoBehaviour {
skeleton = new Skeleton(skeletonData);
if (initialSkinName != null && initialSkinName.Length > 0 && initialSkinName != "default")
skeleton.SetSkin(initialSkinName);
+ if (OnReset != null)
+ OnReset(this);
}
public void Awake () {
@@ -108,8 +119,8 @@ public class SkeletonRenderer : MonoBehaviour {
}
public virtual void LateUpdate () {
- if (!valid) return;
-
+ if (!valid)
+ return;
// Count vertices and submesh triangles.
int vertexCount = 0;
int submeshTriangleCount = 0, submeshFirstVertex = 0, submeshStartSlotIndex = 0;
@@ -119,7 +130,8 @@ public class SkeletonRenderer : MonoBehaviour {
int drawOrderCount = drawOrder.Count;
bool renderMeshes = this.renderMeshes;
for (int i = 0; i < drawOrderCount; i++) {
- Attachment attachment = drawOrder[i].attachment;
+ Slot slot = drawOrder[i];
+ Attachment attachment = slot.attachment;
object rendererObject;
int attachmentVertexCount, attachmentTriangleCount;
@@ -129,24 +141,25 @@ public class SkeletonRenderer : MonoBehaviour {
attachmentVertexCount = 4;
attachmentTriangleCount = 6;
} else {
- if (!renderMeshes) continue;
+ if (!renderMeshes)
+ continue;
if (attachment is MeshAttachment) {
MeshAttachment meshAttachment = (MeshAttachment)attachment;
rendererObject = meshAttachment.RendererObject;
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
attachmentTriangleCount = meshAttachment.triangles.Length;
} else if (attachment is SkinnedMeshAttachment) {
- SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
- rendererObject = meshAttachment.RendererObject;
- attachmentVertexCount = meshAttachment.uvs.Length >> 1;
- attachmentTriangleCount = meshAttachment.triangles.Length;
- } else
- continue;
+ SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
+ rendererObject = meshAttachment.RendererObject;
+ attachmentVertexCount = meshAttachment.uvs.Length >> 1;
+ attachmentTriangleCount = meshAttachment.triangles.Length;
+ } else
+ continue;
}
// Populate submesh when material changes.
Material material = (Material)rendererObject;
- if (lastMaterial != material && lastMaterial != null) {
+ if ((lastMaterial != material && lastMaterial != null) || slot.Data.name[0] == '*') {
AddSubmesh(lastMaterial, submeshStartSlotIndex, i, submeshTriangleCount, submeshFirstVertex, false);
submeshTriangleCount = 0;
submeshFirstVertex = vertexCount;
@@ -209,7 +222,8 @@ public class SkeletonRenderer : MonoBehaviour {
color.r = (byte)(r * slot.r * regionAttachment.r * color.a);
color.g = (byte)(g * slot.g * regionAttachment.g * color.a);
color.b = (byte)(b * slot.b * regionAttachment.b * color.a);
- if (slot.data.additiveBlending) color.a = 0;
+ if (slot.data.additiveBlending)
+ color.a = 0;
colors[vertexIndex] = color;
colors[vertexIndex + 1] = color;
colors[vertexIndex + 2] = color;
@@ -223,18 +237,21 @@ public class SkeletonRenderer : MonoBehaviour {
vertexIndex += 4;
} else {
- if (!renderMeshes) continue;
+ if (!renderMeshes)
+ continue;
if (attachment is MeshAttachment) {
MeshAttachment meshAttachment = (MeshAttachment)attachment;
int meshVertexCount = meshAttachment.vertices.Length;
- if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
+ if (tempVertices.Length < meshVertexCount)
+ tempVertices = new float[meshVertexCount];
meshAttachment.ComputeWorldVertices(slot, tempVertices);
color.a = (byte)(a * slot.a * meshAttachment.a);
color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
- if (slot.data.additiveBlending) color.a = 0;
+ if (slot.data.additiveBlending)
+ color.a = 0;
float[] meshUVs = meshAttachment.uvs;
float z = i * zSpacing;
@@ -244,25 +261,27 @@ public class SkeletonRenderer : MonoBehaviour {
uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
}
} else if (attachment is SkinnedMeshAttachment) {
- SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
- int meshVertexCount = meshAttachment.uvs.Length;
- if (tempVertices.Length < meshVertexCount) tempVertices = new float[meshVertexCount];
- meshAttachment.ComputeWorldVertices(slot, tempVertices);
+ SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
+ int meshVertexCount = meshAttachment.uvs.Length;
+ if (tempVertices.Length < meshVertexCount)
+ tempVertices = new float[meshVertexCount];
+ meshAttachment.ComputeWorldVertices(slot, tempVertices);
- color.a = (byte)(a * slot.a * meshAttachment.a);
- color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
- color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
- color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
- if (slot.data.additiveBlending) color.a = 0;
+ color.a = (byte)(a * slot.a * meshAttachment.a);
+ color.r = (byte)(r * slot.r * meshAttachment.r * color.a);
+ color.g = (byte)(g * slot.g * meshAttachment.g * color.a);
+ color.b = (byte)(b * slot.b * meshAttachment.b * color.a);
+ if (slot.data.additiveBlending)
+ color.a = 0;
- float[] meshUVs = meshAttachment.uvs;
- float z = i * zSpacing;
- for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
- vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
- colors[vertexIndex] = color;
- uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
+ float[] meshUVs = meshAttachment.uvs;
+ float z = i * zSpacing;
+ for (int ii = 0; ii < meshVertexCount; ii += 2, vertexIndex++) {
+ vertices[vertexIndex] = new Vector3(tempVertices[ii], tempVertices[ii + 1], z);
+ colors[vertexIndex] = color;
+ uvs[vertexIndex] = new Vector2(meshUVs[ii], meshUVs[ii + 1]);
+ }
}
- }
}
}
@@ -310,7 +329,7 @@ public class SkeletonRenderer : MonoBehaviour {
if (submeshes.Count <= submeshIndex)
submeshes.Add(new Submesh());
else if (immutableTriangles)
- return;
+ return;
Submesh submesh = submeshes[submeshIndex];
@@ -322,10 +341,10 @@ public class SkeletonRenderer : MonoBehaviour {
triangles[i] = 0;
submesh.triangleCount = triangleCount;
} else if (trianglesCapacity != triangleCount) {
- // Reallocate triangles when not the exact size needed.
- submesh.triangles = triangles = new int[triangleCount];
- submesh.triangleCount = 0;
- }
+ // Reallocate triangles when not the exact size needed.
+ submesh.triangles = triangles = new int[triangleCount];
+ submesh.triangleCount = 0;
+ }
if (!renderMeshes) {
// Use stored triangles if possible.
@@ -366,18 +385,18 @@ public class SkeletonRenderer : MonoBehaviour {
attachmentVertexCount = meshAttachment.vertices.Length >> 1;
attachmentTriangles = meshAttachment.triangles;
} else if (attachment is SkinnedMeshAttachment) {
- SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
- attachmentVertexCount = meshAttachment.uvs.Length >> 1;
- attachmentTriangles = meshAttachment.triangles;
- } else
- continue;
+ SkinnedMeshAttachment meshAttachment = (SkinnedMeshAttachment)attachment;
+ attachmentVertexCount = meshAttachment.uvs.Length >> 1;
+ attachmentTriangles = meshAttachment.triangles;
+ } else
+ continue;
for (int ii = 0, nn = attachmentTriangles.Length; ii < nn; ii++, triangleIndex++)
triangles[triangleIndex] = firstVertex + attachmentTriangles[ii];
firstVertex += attachmentVertexCount;
}
}
- #if UNITY_EDITOR
+#if UNITY_EDITOR
void OnDrawGizmos() {
// Make selection easier by drawing a clear gizmo over the skeleton.
if (vertices == null) return;
@@ -397,7 +416,7 @@ public class SkeletonRenderer : MonoBehaviour {
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.DrawCube(gizmosCenter, gizmosSize);
}
- #endif
+#endif
}
class Submesh {
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility.meta
new file mode 100644
index 000000000..d690c94de
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility.meta
@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: f6e0caaafe294de48af468a6a9321473
+folderAsset: yes
+DefaultImporter:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor.meta
new file mode 100644
index 000000000..386e1e90b
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor.meta
@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: a751a9d1e3e26d64d997b66a781df8e9
+folderAsset: yes
+DefaultImporter:
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs
new file mode 100644
index 000000000..a6950aa84
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs
@@ -0,0 +1,304 @@
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.1
+ *
+ * Copyright (c) 2013, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable and
+ * non-transferable license to install, execute and perform the Spine Runtimes
+ * Software (the "Software") solely for internal use. Without the written
+ * permission of Esoteric Software (typically granted by licensing Spine), you
+ * may not (a) modify, translate, adapt or otherwise create derivative works,
+ * improvements of the Software or develop new applications using the Software
+ * or (b) remove, delete, alter or obscure any trademarks or any copyright,
+ * trademark, patent or other intellectual property or proprietary rights
+ * notices on or in the Software, including any copy thereof. Redistributions
+ * in binary or source form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Skeleton Utility created by Mitch Thompson
+ * Full irrevocable rights and permissions granted to Esoteric Software
+*****************************************************************************/
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+using System.Collections.Generic;
+using Spine;
+
+[CustomEditor(typeof(SkeletonUtilityBone)), CanEditMultipleObjects]
+public class SkeletonUtilityBoneInspector : Editor {
+ SerializedProperty mode, boneName, zPosition, position, rotation, scale, overrideAlpha, parentReference, flip, flipX;
+
+ //multi selected flags
+ bool containsFollows, containsOverrides, multiObject;
+
+ //single selected helpers
+ SkeletonUtilityBone utilityBone;
+ SkeletonUtility skeletonUtility;
+ bool canCreateHingeChain = false;
+
+ void OnEnable () {
+ mode = this.serializedObject.FindProperty("mode");
+ boneName = this.serializedObject.FindProperty("boneName");
+ zPosition = this.serializedObject.FindProperty("zPosition");
+ position = this.serializedObject.FindProperty("position");
+ rotation = this.serializedObject.FindProperty("rotation");
+ scale = this.serializedObject.FindProperty("scale");
+ overrideAlpha = this.serializedObject.FindProperty("overrideAlpha");
+ parentReference = this.serializedObject.FindProperty("parentReference");
+ flip = this.serializedObject.FindProperty("flip");
+ flipX = this.serializedObject.FindProperty("flipX");
+
+ EvaluateFlags();
+
+ if (utilityBone.valid == false && skeletonUtility != null && skeletonUtility.skeletonRenderer != null) {
+ skeletonUtility.skeletonRenderer.Reset();
+ }
+
+ canCreateHingeChain = CanCreateHingeChain();
+ }
+
+ void EvaluateFlags () {
+ utilityBone = (SkeletonUtilityBone)target;
+ skeletonUtility = utilityBone.skeletonUtility;
+
+ if (Selection.objects.Length == 1) {
+ containsFollows = utilityBone.mode == SkeletonUtilityBone.Mode.Follow;
+ containsOverrides = utilityBone.mode == SkeletonUtilityBone.Mode.Override;
+ } else {
+ int boneCount = 0;
+ foreach (Object o in Selection.objects) {
+ if (o is GameObject) {
+ GameObject go = (GameObject)o;
+ SkeletonUtilityBone sub = go.GetComponent();
+ if (sub != null) {
+ boneCount++;
+ if (sub.mode == SkeletonUtilityBone.Mode.Follow)
+ containsFollows = true;
+ if (sub.mode == SkeletonUtilityBone.Mode.Override)
+ containsOverrides = true;
+ }
+ }
+ }
+
+ if (boneCount > 1)
+ multiObject = true;
+ }
+ }
+
+ public override void OnInspectorGUI () {
+ serializedObject.Update();
+
+ EditorGUI.BeginChangeCheck();
+ EditorGUILayout.PropertyField(mode);
+ if (EditorGUI.EndChangeCheck()) {
+ containsOverrides = mode.enumValueIndex == 1;
+ containsFollows = mode.enumValueIndex == 0;
+ }
+
+ EditorGUI.BeginDisabledGroup(multiObject);
+ {
+ string str = boneName.stringValue;
+ if (str == "")
+ str = "";
+ if (multiObject)
+ str = "";
+
+ GUILayout.BeginHorizontal();
+ EditorGUILayout.PrefixLabel("Bone");
+
+ if (GUILayout.Button(str, EditorStyles.popup)) {
+ BoneSelectorContextMenu(str, ((SkeletonUtilityBone)target).skeletonUtility.skeletonRenderer.skeleton.Bones, "", TargetBoneSelected);
+ }
+
+ GUILayout.EndHorizontal();
+ }
+ EditorGUI.EndDisabledGroup();
+
+ EditorGUILayout.PropertyField(zPosition);
+ EditorGUILayout.PropertyField(position);
+ EditorGUILayout.PropertyField(rotation);
+ EditorGUILayout.PropertyField(scale);
+ EditorGUILayout.PropertyField(flip);
+
+ EditorGUI.BeginDisabledGroup(containsFollows);
+ {
+ EditorGUILayout.PropertyField(overrideAlpha);
+ EditorGUILayout.PropertyField(parentReference);
+
+ EditorGUI.BeginDisabledGroup(multiObject || !flip.boolValue);
+ {
+ EditorGUI.BeginChangeCheck();
+ EditorGUILayout.PropertyField(flipX);
+ if (EditorGUI.EndChangeCheck()) {
+ FlipX(flipX.boolValue);
+ }
+ }
+ EditorGUI.EndDisabledGroup();
+
+ }
+ EditorGUI.EndDisabledGroup();
+
+ EditorGUILayout.Space();
+
+ GUILayout.BeginHorizontal();
+ {
+ EditorGUI.BeginDisabledGroup(multiObject || !utilityBone.valid || utilityBone.bone == null || utilityBone.bone.Children.Count == 0);
+ {
+ if (GUILayout.Button(new GUIContent("Add Child", SpineEditorUtilities.Icons.bone), GUILayout.Width(150), GUILayout.Height(24)))
+ BoneSelectorContextMenu("", utilityBone.bone.Children, "", SpawnChildBoneSelected);
+ }
+ EditorGUI.EndDisabledGroup();
+
+ EditorGUI.BeginDisabledGroup(multiObject || !utilityBone.valid || utilityBone.bone == null || containsOverrides);
+ {
+ if (GUILayout.Button(new GUIContent("Add Override", SpineEditorUtilities.Icons.poseBones), GUILayout.Width(150), GUILayout.Height(24)))
+ SpawnOverride();
+ }
+ EditorGUI.EndDisabledGroup();
+
+ EditorGUI.BeginDisabledGroup(multiObject || !utilityBone.valid || !canCreateHingeChain);
+ {
+ if (GUILayout.Button(new GUIContent("Create Hinge Chain", SpineEditorUtilities.Icons.hingeChain), GUILayout.Width(150), GUILayout.Height(24)))
+ CreateHingeChain();
+ }
+ EditorGUI.EndDisabledGroup();
+
+ }
+ GUILayout.EndHorizontal();
+
+ serializedObject.ApplyModifiedProperties();
+ }
+
+ void FlipX (bool state) {
+ utilityBone.FlipX(state);
+ if (Application.isPlaying == false) {
+ skeletonUtility.skeletonAnimation.LateUpdate();
+ }
+ }
+
+ void BoneSelectorContextMenu (string current, List bones, string topValue, GenericMenu.MenuFunction2 callback) {
+ GenericMenu menu = new GenericMenu();
+
+ if (topValue != "")
+ menu.AddItem(new GUIContent(topValue), current == topValue, callback, null);
+
+ for (int i = 0; i < bones.Count; i++) {
+ menu.AddItem(new GUIContent(bones[i].Data.Name), bones[i].Data.Name == current, callback, bones[i]);
+ }
+
+ menu.ShowAsContext();
+
+ }
+
+ void TargetBoneSelected (object obj) {
+ if (obj == null) {
+ boneName.stringValue = "";
+ serializedObject.ApplyModifiedProperties();
+ } else {
+ Bone bone = (Bone)obj;
+ boneName.stringValue = bone.Data.Name;
+ serializedObject.ApplyModifiedProperties();
+
+ utilityBone.Reset();
+ }
+ }
+
+ void SpawnChildBoneSelected (object obj) {
+ if (obj == null) {
+ //add recursively
+ foreach (var bone in utilityBone.bone.Children) {
+ GameObject go = skeletonUtility.SpawnBoneRecursively(bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale);
+ SkeletonUtilityBone[] newUtilityBones = go.GetComponentsInChildren();
+ foreach (SkeletonUtilityBone utilBone in newUtilityBones)
+ SkeletonUtilityInspector.AttachIcon(utilBone);
+ }
+ } else {
+ Bone bone = (Bone)obj;
+ GameObject go = skeletonUtility.SpawnBone(bone, utilityBone.transform, utilityBone.mode, utilityBone.position, utilityBone.rotation, utilityBone.scale);
+ SkeletonUtilityInspector.AttachIcon(go.GetComponent());
+ Selection.activeGameObject = go;
+ EditorGUIUtility.PingObject(go);
+ }
+ }
+
+ void SpawnOverride () {
+ GameObject go = skeletonUtility.SpawnBone(utilityBone.bone, utilityBone.transform.parent, SkeletonUtilityBone.Mode.Override, utilityBone.position, utilityBone.rotation, utilityBone.scale);
+ go.name = go.name + " [Override]";
+ SkeletonUtilityInspector.AttachIcon(go.GetComponent());
+ Selection.activeGameObject = go;
+ EditorGUIUtility.PingObject(go);
+ }
+
+ bool CanCreateHingeChain () {
+ if (utilityBone == null)
+ return false;
+ if (utilityBone.rigidbody != null)
+ return false;
+ if (utilityBone.bone != null && utilityBone.bone.Children.Count == 0)
+ return false;
+
+ Rigidbody[] rigidbodies = utilityBone.GetComponentsInChildren();
+
+ if (rigidbodies.Length > 0)
+ return false;
+
+ return true;
+ }
+
+ void CreateHingeChain () {
+ var utilBoneArr = utilityBone.GetComponentsInChildren();
+
+ foreach (var utilBone in utilBoneArr) {
+ AttachRigidbody(utilBone);
+ }
+
+ utilityBone.rigidbody.isKinematic = true;
+
+ foreach (var utilBone in utilBoneArr) {
+ if (utilBone == utilityBone)
+ continue;
+
+ utilBone.mode = SkeletonUtilityBone.Mode.Override;
+
+ HingeJoint joint = utilBone.gameObject.AddComponent();
+ joint.axis = Vector3.forward;
+ joint.connectedBody = utilBone.transform.parent.rigidbody;
+ joint.useLimits = true;
+ JointLimits limits = new JointLimits();
+ limits.min = -20;
+ limits.max = 20;
+ joint.limits = limits;
+ utilBone.rigidbody.mass = utilBone.transform.parent.rigidbody.mass * 0.75f;
+ }
+ }
+
+ void AttachRigidbody (SkeletonUtilityBone utilBone) {
+ if (utilBone.GetComponent() == null) {
+ if (utilBone.bone.Data.Length == 0) {
+ SphereCollider sphere = utilBone.gameObject.AddComponent();
+ sphere.radius = 0.1f;
+ } else {
+ float length = utilBone.bone.Data.Length;
+ BoxCollider box = utilBone.gameObject.AddComponent();
+ box.size = new Vector3(length, length / 3, 0.2f);
+ box.center = new Vector3(length / 2, 0, 0);
+ }
+ }
+
+ utilBone.gameObject.AddComponent();
+ }
+}
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs.meta
new file mode 100644
index 000000000..340d6e2eb
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityBoneInspector.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b3ae20b4bcc31f645afd6f5b64f82473
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityInspector.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityInspector.cs
new file mode 100644
index 000000000..4c6d02d09
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityInspector.cs
@@ -0,0 +1,311 @@
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.1
+ *
+ * Copyright (c) 2013, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable and
+ * non-transferable license to install, execute and perform the Spine Runtimes
+ * Software (the "Software") solely for internal use. Without the written
+ * permission of Esoteric Software (typically granted by licensing Spine), you
+ * may not (a) modify, translate, adapt or otherwise create derivative works,
+ * improvements of the Software or develop new applications using the Software
+ * or (b) remove, delete, alter or obscure any trademarks or any copyright,
+ * trademark, patent or other intellectual property or proprietary rights
+ * notices on or in the Software, including any copy thereof. Redistributions
+ * in binary or source form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Skeleton Utility created by Mitch Thompson
+ * Full irrevocable rights and permissions granted to Esoteric Software
+*****************************************************************************/
+using UnityEngine;
+using UnityEditor;
+
+#if UNITY_4_3
+//nothing
+#else
+using UnityEditor.AnimatedValues;
+#endif
+using System.Collections;
+using System.Collections.Generic;
+using Spine;
+
+using System.Reflection;
+
+[CustomEditor(typeof(SkeletonUtility))]
+public class SkeletonUtilityInspector : Editor {
+
+ public static void AttachIcon (SkeletonUtilityBone utilityBone) {
+ Skeleton skeleton = utilityBone.skeletonUtility.skeletonRenderer.skeleton;
+ Texture2D icon;
+ if (utilityBone.bone.Data.Length == 0)
+ icon = SpineEditorUtilities.Icons.nullBone;
+ else
+ icon = SpineEditorUtilities.Icons.boneNib;
+
+ foreach (IkConstraint c in skeleton.IkConstraints) {
+ if (c.Target == utilityBone.bone) {
+ icon = SpineEditorUtilities.Icons.constraintNib;
+ break;
+ }
+ }
+
+
+
+ typeof(EditorGUIUtility).InvokeMember("SetIconForObject", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic, null, null, new object[2] {
+ utilityBone.gameObject,
+ icon
+ });
+ }
+
+ static void AttachIconsToChildren (Transform root) {
+ if (root != null) {
+ var utilityBones = root.GetComponentsInChildren();
+ foreach (var utilBone in utilityBones) {
+ AttachIcon(utilBone);
+ }
+ }
+ }
+
+ static SkeletonUtilityInspector () {
+ #if UNITY_4_3
+ showSlots = false;
+ #else
+ showSlots = new AnimBool(false);
+ #endif
+ }
+
+ SkeletonUtility skeletonUtility;
+ Skeleton skeleton;
+ SkeletonRenderer skeletonRenderer;
+ Transform transform;
+ bool isPrefab;
+ Dictionary> attachmentTable = new Dictionary>();
+
+
+ //GUI stuff
+#if UNITY_4_3
+ static bool showSlots;
+#else
+ static AnimBool showSlots;
+#endif
+
+ void OnEnable () {
+ skeletonUtility = (SkeletonUtility)target;
+ skeletonRenderer = skeletonUtility.GetComponent();
+ skeleton = skeletonRenderer.skeleton;
+ transform = skeletonRenderer.transform;
+
+ if (skeleton == null) {
+ skeletonRenderer.Reset();
+ skeletonRenderer.LateUpdate();
+
+ skeleton = skeletonRenderer.skeleton;
+ }
+
+ UpdateAttachments();
+
+ if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
+ isPrefab = true;
+
+ }
+
+ void OnDestroy () {
+
+ }
+
+ void OnSceneGUI () {
+ if (skeleton == null) {
+ OnEnable();
+ return;
+ }
+
+ float flipRotation = skeleton.FlipX ? -1 : 1;
+
+ foreach (Bone b in skeleton.Bones) {
+ Vector3 vec = transform.TransformPoint(new Vector3(b.WorldX, b.WorldY, 0));
+
+ Quaternion rot = Quaternion.Euler(0, 0, b.WorldRotation * flipRotation);
+ Vector3 forward = transform.TransformDirection(rot * Vector3.right);
+ forward *= flipRotation;
+
+ SpineEditorUtilities.Icons.boneMaterial.SetPass(0);
+ Graphics.DrawMeshNow(SpineEditorUtilities.Icons.boneMesh, Matrix4x4.TRS(vec, Quaternion.LookRotation(transform.forward, forward), Vector3.one * b.Data.Length * b.WorldScaleX));
+ }
+ }
+
+ void UpdateAttachments () {
+ attachmentTable = new Dictionary>();
+ Skin skin = skeleton.Skin;
+
+ if (skin == null) {
+ skin = skeletonRenderer.skeletonDataAsset.GetSkeletonData(true).DefaultSkin;
+ }
+
+ for (int i = skeleton.Slots.Count-1; i >= 0; i--) {
+ List attachments = new List();
+ skin.FindAttachmentsForSlot(i, attachments);
+
+ attachmentTable.Add(skeleton.Slots[i], attachments);
+ }
+ }
+
+ void SpawnHierarchyButton (string label, string tooltip, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca, params GUILayoutOption[] options) {
+ GUIContent content = new GUIContent(label, tooltip);
+ if (GUILayout.Button(content, options)) {
+ if (skeletonUtility.skeletonRenderer == null)
+ skeletonUtility.skeletonRenderer = skeletonUtility.GetComponent();
+
+ if (skeletonUtility.boneRoot != null) {
+ return;
+ }
+
+ skeletonUtility.SpawnHierarchy(mode, pos, rot, sca);
+
+ SkeletonUtilityBone[] boneComps = skeletonUtility.GetComponentsInChildren();
+ foreach (SkeletonUtilityBone b in boneComps)
+ AttachIcon(b);
+ }
+ }
+
+ public override void OnInspectorGUI () {
+ if (isPrefab) {
+ GUILayout.Label(new GUIContent("Cannot edit Prefabs", SpineEditorUtilities.Icons.warning));
+ return;
+ }
+
+ skeletonUtility.boneRoot = (Transform)EditorGUILayout.ObjectField("Bone Root", skeletonUtility.boneRoot, typeof(Transform), true);
+
+ GUILayout.BeginHorizontal();
+ EditorGUI.BeginDisabledGroup(skeletonUtility.boneRoot != null);
+ {
+ if (GUILayout.Button(new GUIContent("Spawn Hierarchy", SpineEditorUtilities.Icons.skeleton), GUILayout.Width(150), GUILayout.Height(24)))
+ SpawnHierarchyContextMenu();
+ }
+ EditorGUI.EndDisabledGroup();
+
+ if (GUILayout.Button(new GUIContent("Spawn Submeshes", SpineEditorUtilities.Icons.subMeshRenderer), GUILayout.Width(150), GUILayout.Height(24)))
+ skeletonUtility.SpawnSubRenderers(true);
+ GUILayout.EndHorizontal();
+
+ EditorGUI.BeginChangeCheck();
+ skeleton.FlipX = EditorGUILayout.ToggleLeft("Flip X", skeleton.FlipX);
+ skeleton.FlipY = EditorGUILayout.ToggleLeft("Flip Y", skeleton.FlipY);
+ if (EditorGUI.EndChangeCheck()) {
+ skeletonRenderer.LateUpdate();
+ SceneView.RepaintAll();
+ }
+
+#if UNITY_4_3
+ showSlots = EditorGUILayout.Foldout(showSlots, "Slots");
+#else
+ showSlots.target = EditorGUILayout.Foldout(showSlots.target, "Slots");
+ if (EditorGUILayout.BeginFadeGroup(showSlots.faded)) {
+#endif
+ foreach (KeyValuePair> pair in attachmentTable) {
+
+ Slot slot = pair.Key;
+
+ EditorGUILayout.BeginHorizontal();
+ EditorGUI.indentLevel = 1;
+ EditorGUILayout.LabelField(new GUIContent(slot.Data.Name, SpineEditorUtilities.Icons.slot), GUILayout.ExpandWidth(false));
+
+ EditorGUI.BeginChangeCheck();
+ Color c = EditorGUILayout.ColorField(new Color(slot.R, slot.G, slot.B, slot.A), GUILayout.Width(60));
+
+ if (EditorGUI.EndChangeCheck()) {
+ slot.SetColor(c);
+ skeletonRenderer.LateUpdate();
+ }
+
+ EditorGUILayout.EndHorizontal();
+
+
+
+ foreach (Attachment attachment in pair.Value) {
+
+ if (slot.Attachment == attachment) {
+ GUI.contentColor = Color.white;
+ } else {
+ GUI.contentColor = Color.grey;
+ }
+
+ EditorGUI.indentLevel = 2;
+ bool isAttached = attachment == slot.Attachment;
+
+ Texture2D icon = null;
+
+ if (attachment is MeshAttachment || attachment is SkinnedMeshAttachment)
+ icon = SpineEditorUtilities.Icons.mesh;
+ else
+ icon = SpineEditorUtilities.Icons.image;
+
+ bool swap = EditorGUILayout.ToggleLeft(new GUIContent(attachment.Name, icon), attachment == slot.Attachment);
+
+ if (!isAttached && swap) {
+ slot.Attachment = attachment;
+ skeletonRenderer.LateUpdate();
+ } else if (isAttached && !swap) {
+ slot.Attachment = null;
+ skeletonRenderer.LateUpdate();
+ }
+
+ GUI.contentColor = Color.white;
+ }
+ }
+ #if UNITY_4_3
+
+#else
+ }
+ EditorGUILayout.EndFadeGroup();
+ if (showSlots.isAnimating)
+ Repaint();
+#endif
+ }
+
+ void SpawnHierarchyContextMenu () {
+ GenericMenu menu = new GenericMenu();
+
+ menu.AddItem(new GUIContent("Follow"), false, SpawnFollowHierarchy);
+ menu.AddItem(new GUIContent("Follow (Root Only)"), false, SpawnFollowHierarchyRootOnly);
+ menu.AddSeparator("");
+ menu.AddItem(new GUIContent("Override"), false, SpawnOverrideHierarchy);
+ menu.AddItem(new GUIContent("Override (Root Only)"), false, SpawnOverrideHierarchyRootOnly);
+
+ menu.ShowAsContext();
+ }
+
+ void SpawnFollowHierarchy () {
+ Selection.activeGameObject = skeletonUtility.SpawnHierarchy(SkeletonUtilityBone.Mode.Follow, true, true, true);
+ AttachIconsToChildren(skeletonUtility.boneRoot);
+ }
+
+ void SpawnFollowHierarchyRootOnly () {
+ Selection.activeGameObject = skeletonUtility.SpawnRoot(SkeletonUtilityBone.Mode.Follow, true, true, true);
+ AttachIconsToChildren(skeletonUtility.boneRoot);
+ }
+
+ void SpawnOverrideHierarchy () {
+ Selection.activeGameObject = skeletonUtility.SpawnHierarchy(SkeletonUtilityBone.Mode.Override, true, true, true);
+ AttachIconsToChildren(skeletonUtility.boneRoot);
+ }
+
+ void SpawnOverrideHierarchyRootOnly () {
+ Selection.activeGameObject = skeletonUtility.SpawnRoot(SkeletonUtilityBone.Mode.Override, true, true, true);
+ AttachIconsToChildren(skeletonUtility.boneRoot);
+ }
+}
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityInspector.cs.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityInspector.cs.meta
new file mode 100644
index 000000000..7820cbd6d
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/Editor/SkeletonUtilityInspector.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: a5b90df955eb8c2429ac67c8b2de6c5c
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtility.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtility.cs
new file mode 100644
index 000000000..c274c3db6
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtility.cs
@@ -0,0 +1,346 @@
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.1
+ *
+ * Copyright (c) 2013, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable and
+ * non-transferable license to install, execute and perform the Spine Runtimes
+ * Software (the "Software") solely for internal use. Without the written
+ * permission of Esoteric Software (typically granted by licensing Spine), you
+ * may not (a) modify, translate, adapt or otherwise create derivative works,
+ * improvements of the Software or develop new applications using the Software
+ * or (b) remove, delete, alter or obscure any trademarks or any copyright,
+ * trademark, patent or other intellectual property or proprietary rights
+ * notices on or in the Software, including any copy thereof. Redistributions
+ * in binary or source form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Skeleton Utility created by Mitch Thompson
+ * Full irrevocable rights and permissions granted to Esoteric Software
+*****************************************************************************/
+
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using Spine;
+
+[RequireComponent(typeof(SkeletonAnimation))]
+[ExecuteInEditMode]
+public class SkeletonUtility : MonoBehaviour {
+
+ public static T GetInParent (Transform origin) where T : Component {
+#if UNITY_4_3
+ Transform parent = origin.parent;
+ while(parent.GetComponent() == null){
+ parent = parent.parent;
+ if(parent == null)
+ return default(T);
+ }
+
+ return parent.GetComponent();
+#else
+ return origin.GetComponentInParent();
+#endif
+ }
+
+
+ public delegate void SkeletonUtilityDelegate ();
+
+ public event SkeletonUtilityDelegate OnReset;
+
+ public Transform boneRoot;
+
+ void Update () {
+ if (boneRoot != null && skeletonRenderer.skeleton != null) {
+ Vector3 flipScale = Vector3.one;
+ if (skeletonRenderer.skeleton.FlipX)
+ flipScale.x = -1;
+
+ if (skeletonRenderer.skeleton.FlipY)
+ flipScale.y = -1;
+
+ boneRoot.localScale = flipScale;
+ }
+ }
+
+ [HideInInspector]
+ public SkeletonRenderer skeletonRenderer;
+ [HideInInspector]
+ public SkeletonAnimation skeletonAnimation;
+ [System.NonSerialized]
+ public List utilityBones = new List();
+ [System.NonSerialized]
+ public List utilityConstraints = new List();
+// Dictionary utilityBoneTable;
+
+ protected bool hasTransformBones;
+ protected bool hasUtilityConstraints;
+ protected bool needToReprocessBones;
+
+ void OnEnable () {
+ if (skeletonRenderer == null) {
+ skeletonRenderer = GetComponent();
+ }
+
+ if (skeletonAnimation == null) {
+ skeletonAnimation = GetComponent();
+ }
+
+ skeletonRenderer.OnReset -= HandleRendererReset;
+ skeletonRenderer.OnReset += HandleRendererReset;
+
+ if (skeletonAnimation != null) {
+ skeletonAnimation.UpdateLocal -= UpdateLocal;
+ skeletonAnimation.UpdateLocal += UpdateLocal;
+ }
+
+
+ CollectBones();
+ }
+
+ void Start () {
+ //recollect because order of operations failure when switching between game mode and edit mode...
+// CollectBones();
+ }
+
+ void OnDisable () {
+ skeletonRenderer.OnReset -= HandleRendererReset;
+
+ if (skeletonAnimation != null) {
+ skeletonAnimation.UpdateLocal -= UpdateLocal;
+ skeletonAnimation.UpdateWorld -= UpdateWorld;
+ skeletonAnimation.UpdateComplete -= UpdateComplete;
+ }
+ }
+
+ void HandleRendererReset (SkeletonRenderer r) {
+ if (OnReset != null)
+ OnReset();
+
+ CollectBones();
+ }
+
+ public void RegisterBone (SkeletonUtilityBone bone) {
+ if (utilityBones.Contains(bone))
+ return;
+ else {
+ utilityBones.Add(bone);
+ needToReprocessBones = true;
+ }
+ }
+
+ public void UnregisterBone (SkeletonUtilityBone bone) {
+ utilityBones.Remove(bone);
+ }
+
+ public void RegisterConstraint (SkeletonUtilityConstraint constraint) {
+
+ if (utilityConstraints.Contains(constraint))
+ return;
+ else {
+ utilityConstraints.Add(constraint);
+ needToReprocessBones = true;
+ }
+ }
+
+ public void UnregisterConstraint (SkeletonUtilityConstraint constraint) {
+ utilityConstraints.Remove(constraint);
+ }
+
+ public void CollectBones () {
+ if (skeletonRenderer.skeleton == null)
+ return;
+
+ if (boneRoot != null) {
+ List constraintTargetNames = new List();
+
+ foreach (IkConstraint c in skeletonRenderer.skeleton.IkConstraints) {
+ constraintTargetNames.Add(c.Target.Data.Name);
+ }
+
+ foreach (var b in utilityBones) {
+ if (b.bone == null) {
+ return;
+ }
+ if (b.mode == SkeletonUtilityBone.Mode.Override) {
+ hasTransformBones = true;
+ }
+
+ if (constraintTargetNames.Contains(b.bone.Data.Name)) {
+ hasUtilityConstraints = true;
+ }
+ }
+
+ if (utilityConstraints.Count > 0)
+ hasUtilityConstraints = true;
+
+ if (skeletonAnimation != null) {
+ skeletonAnimation.UpdateWorld -= UpdateWorld;
+ skeletonAnimation.UpdateComplete -= UpdateComplete;
+
+ if (hasTransformBones || hasUtilityConstraints) {
+ skeletonAnimation.UpdateWorld += UpdateWorld;
+ }
+
+ if (hasUtilityConstraints) {
+ skeletonAnimation.UpdateComplete += UpdateComplete;
+ }
+ }
+
+ needToReprocessBones = false;
+ } else {
+ utilityBones.Clear();
+ utilityConstraints.Clear();
+ }
+
+ }
+
+ void UpdateLocal (SkeletonAnimation anim) {
+
+ if (needToReprocessBones)
+ CollectBones();
+
+ if (utilityBones == null)
+ return;
+
+ foreach (SkeletonUtilityBone b in utilityBones) {
+ b.transformLerpComplete = false;
+ }
+
+ UpdateAllBones();
+ }
+
+ void UpdateWorld (SkeletonAnimation anim) {
+ UpdateAllBones();
+
+ foreach (SkeletonUtilityConstraint c in utilityConstraints)
+ c.DoUpdate();
+ }
+
+ void UpdateComplete (SkeletonAnimation anim) {
+ UpdateAllBones();
+ }
+
+ void UpdateAllBones () {
+ if (boneRoot == null) {
+ CollectBones();
+ }
+
+ if (utilityBones == null)
+ return;
+
+ foreach (SkeletonUtilityBone b in utilityBones) {
+ b.DoUpdate();
+ }
+ }
+
+ public Transform GetBoneRoot () {
+ if (boneRoot != null)
+ return boneRoot;
+
+ boneRoot = new GameObject("SkeletonUtility-Root").transform;
+ boneRoot.parent = transform;
+ boneRoot.localPosition = Vector3.zero;
+ boneRoot.localRotation = Quaternion.identity;
+ boneRoot.localScale = Vector3.one;
+
+ return boneRoot;
+ }
+
+ public GameObject SpawnRoot (SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) {
+ GetBoneRoot();
+ Skeleton skeleton = this.skeletonRenderer.skeleton;
+
+ GameObject go = SpawnBone(skeleton.RootBone, boneRoot, mode, pos, rot, sca);
+
+ CollectBones();
+
+ return go;
+ }
+
+ public GameObject SpawnHierarchy (SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) {
+ GetBoneRoot();
+
+ Skeleton skeleton = this.skeletonRenderer.skeleton;
+
+ GameObject go = SpawnBoneRecursively(skeleton.RootBone, boneRoot, mode, pos, rot, sca);
+
+ CollectBones();
+
+ return go;
+ }
+
+ public GameObject SpawnBoneRecursively (Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) {
+ GameObject go = SpawnBone(bone, parent, mode, pos, rot, sca);
+
+ foreach (Bone child in bone.Children) {
+ SpawnBoneRecursively(child, go.transform, mode, pos, rot, sca);
+ }
+
+ return go;
+ }
+
+ public GameObject SpawnBone (Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca) {
+ GameObject go = new GameObject(bone.Data.Name);
+ go.transform.parent = parent;
+
+ SkeletonUtilityBone b = go.AddComponent();
+ b.skeletonUtility = this;
+ b.position = pos;
+ b.rotation = rot;
+ b.scale = sca;
+ b.mode = mode;
+ b.zPosition = true;
+ b.Reset();
+ b.bone = bone;
+ b.boneName = bone.Data.Name;
+ b.valid = true;
+
+ if (mode == SkeletonUtilityBone.Mode.Override) {
+ if (rot)
+ go.transform.localRotation = Quaternion.Euler(0, 0, b.bone.RotationIK);
+
+ if (pos)
+ go.transform.localPosition = new Vector3(b.bone.X, b.bone.Y, 0);
+
+ go.transform.localScale = new Vector3(b.bone.scaleX, b.bone.scaleY, 0);
+ }
+
+ return go;
+ }
+
+ public void SpawnSubRenderers (bool disablePrimaryRenderer) {
+ int submeshCount = GetComponent().sharedMesh.subMeshCount;
+
+ for (int i = 0; i < submeshCount; i++) {
+ GameObject go = new GameObject("Submesh " + i, typeof(MeshFilter), typeof(MeshRenderer));
+ go.transform.parent = transform;
+ go.transform.localPosition = Vector3.zero;
+ go.transform.localRotation = Quaternion.identity;
+ go.transform.localScale = Vector3.one;
+
+ SkeletonUtilitySubmeshRenderer s = go.AddComponent();
+ s.sortingOrder = i * 10;
+ s.submeshIndex = i;
+ s.Initialize(renderer);
+ s.Update();
+ }
+
+ if (disablePrimaryRenderer)
+ renderer.enabled = false;
+ }
+}
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtility.cs.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtility.cs.meta
new file mode 100644
index 000000000..7d3d7a44f
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtility.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7f726fb798ad621458c431cb9966d91d
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityBone.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityBone.cs
new file mode 100644
index 000000000..99c561499
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityBone.cs
@@ -0,0 +1,293 @@
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.1
+ *
+ * Copyright (c) 2013, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable and
+ * non-transferable license to install, execute and perform the Spine Runtimes
+ * Software (the "Software") solely for internal use. Without the written
+ * permission of Esoteric Software (typically granted by licensing Spine), you
+ * may not (a) modify, translate, adapt or otherwise create derivative works,
+ * improvements of the Software or develop new applications using the Software
+ * or (b) remove, delete, alter or obscure any trademarks or any copyright,
+ * trademark, patent or other intellectual property or proprietary rights
+ * notices on or in the Software, including any copy thereof. Redistributions
+ * in binary or source form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Skeleton Utility created by Mitch Thompson
+ * Full irrevocable rights and permissions granted to Esoteric Software
+*****************************************************************************/
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using UnityEngine;
+using Spine;
+
+/// Sets a GameObject's transform to match a bone on a Spine skeleton.
+[ExecuteInEditMode]
+[AddComponentMenu("Spine/SkeletonUtilityBone")]
+public class SkeletonUtilityBone : MonoBehaviour {
+
+ public enum Mode {
+ Follow,
+ Override
+ }
+
+ [System.NonSerialized]
+ public bool valid;
+ [System.NonSerialized]
+ public SkeletonUtility skeletonUtility;
+ [System.NonSerialized]
+ public Bone bone;
+ public Mode mode;
+ public bool zPosition = true;
+ public bool position;
+ public bool rotation;
+ public bool scale;
+ public bool flip;
+ public bool flipX;
+ [Range(0f,1f)]
+ public float overrideAlpha = 1;
+
+ /// If a bone isn't set, boneName is used to find the bone.
+ public String boneName;
+ public Transform parentReference;
+ [HideInInspector]
+ public bool transformLerpComplete;
+ protected Transform cachedTransform;
+ protected Transform skeletonTransform;
+
+ public bool NonUniformScaleWarning {
+ get {
+ return nonUniformScaleWarning;
+ }
+ }
+
+ private bool nonUniformScaleWarning;
+
+ public void Reset () {
+ bone = null;
+ cachedTransform = transform;
+ valid = skeletonUtility != null && skeletonUtility.skeletonRenderer != null && skeletonUtility.skeletonRenderer.valid;
+ if (!valid)
+ return;
+ skeletonTransform = skeletonUtility.transform;
+
+ skeletonUtility.OnReset -= HandleOnReset;
+ skeletonUtility.OnReset += HandleOnReset;
+
+ DoUpdate();
+ }
+
+ void OnEnable () {
+ skeletonUtility = SkeletonUtility.GetInParent(transform);
+
+ if (skeletonUtility == null)
+ return;
+
+ skeletonUtility.RegisterBone(this);
+
+ skeletonUtility.OnReset += HandleOnReset;
+ }
+
+ void HandleOnReset () {
+ Reset();
+ }
+
+ void OnDisable () {
+ if (skeletonUtility != null) {
+ skeletonUtility.OnReset -= HandleOnReset;
+
+ skeletonUtility.UnregisterBone(this);
+ }
+ }
+
+ public void DoUpdate () {
+
+ if (!valid) {
+ Reset();
+ return;
+ }
+
+ Spine.Skeleton skeleton = skeletonUtility.skeletonRenderer.skeleton;
+
+ if (bone == null) {
+ if (boneName == null || boneName.Length == 0)
+ return;
+ bone = skeleton.FindBone(boneName);
+ if (bone == null) {
+ Debug.LogError("Bone not found: " + boneName, this);
+ return;
+ }
+ }
+
+
+
+ float skeletonFlipRotation = (skeleton.flipX ^ skeleton.flipY) ? -1f : 1f;
+
+ float flipCompensation = 0;
+ if (flip && (flipX || (flipX != bone.flipX)) && bone.parent != null) {
+ flipCompensation = bone.parent.WorldRotation * -2;
+ }
+
+ if (mode == Mode.Follow) {
+ if (flip) {
+ flipX = bone.flipX;
+ }
+
+
+ if (position) {
+ cachedTransform.localPosition = new Vector3(bone.x, bone.y, 0);
+ }
+
+ if (rotation) {
+
+ if (bone.Data.InheritRotation) {
+ if (bone.FlipX) {
+ cachedTransform.localRotation = Quaternion.Euler(0, 180, bone.rotationIK - flipCompensation);
+ } else {
+ cachedTransform.localRotation = Quaternion.Euler(0, 0, bone.rotationIK);
+ }
+ } else {
+ Vector3 euler = skeletonTransform.rotation.eulerAngles;
+ cachedTransform.rotation = Quaternion.Euler(euler.x, euler.y, skeletonTransform.rotation.eulerAngles.z + (bone.worldRotation * skeletonFlipRotation));
+ }
+
+ }
+
+ if (scale) {
+ cachedTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1);
+
+ nonUniformScaleWarning = (bone.scaleX != bone.scaleY);
+ }
+
+ } else if (mode == Mode.Override) {
+
+
+
+ if (transformLerpComplete)
+ return;
+
+ if (parentReference == null) {
+ if (position) {
+ bone.x = Mathf.Lerp(bone.x, cachedTransform.localPosition.x, overrideAlpha);
+ bone.y = Mathf.Lerp(bone.y, cachedTransform.localPosition.y, overrideAlpha);
+ }
+
+ if (rotation) {
+ float angle = Mathf.LerpAngle(bone.Rotation, cachedTransform.localRotation.eulerAngles.z, overrideAlpha) + flipCompensation;
+
+ if (flip) {
+ if ((!flipX && bone.flipX)) {
+ angle -= flipCompensation;
+ }
+
+ //TODO fix this...
+ if (angle >= 360)
+ angle -= 360;
+ else if (angle <= -360)
+ angle += 360;
+ }
+
+ bone.Rotation = angle;
+ }
+
+ if (scale) {
+ bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha);
+ bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha);
+
+ nonUniformScaleWarning = (bone.scaleX != bone.scaleY);
+ }
+
+ if (flip) {
+ bone.flipX = flipX;
+ }
+ } else {
+
+ if (transformLerpComplete)
+ return;
+
+ if (position) {
+ Vector3 pos = parentReference.InverseTransformPoint(cachedTransform.position);
+ bone.x = Mathf.Lerp(bone.x, pos.x, overrideAlpha);
+ bone.y = Mathf.Lerp(bone.y, pos.y, overrideAlpha);
+ }
+
+ if (rotation) {
+ float angle = Mathf.LerpAngle(bone.Rotation, Quaternion.LookRotation(flipX ? Vector3.forward * -1 : Vector3.forward, parentReference.InverseTransformDirection(cachedTransform.up)).eulerAngles.z, overrideAlpha) + flipCompensation;
+
+ if (flip) {
+ if ((!flipX && bone.flipX)) {
+ angle -= flipCompensation;
+ }
+
+ //TODO fix this...
+ if (angle >= 360)
+ angle -= 360;
+ else if (angle <= -360)
+ angle += 360;
+ }
+
+ bone.Rotation = angle;
+ }
+
+ //TODO: Something about this
+ if (scale) {
+ bone.scaleX = Mathf.Lerp(bone.scaleX, cachedTransform.localScale.x, overrideAlpha);
+ bone.scaleY = Mathf.Lerp(bone.scaleY, cachedTransform.localScale.y, overrideAlpha);
+
+ nonUniformScaleWarning = (bone.scaleX != bone.scaleY);
+ }
+
+ if (flip) {
+ bone.flipX = flipX;
+ }
+
+ }
+
+ transformLerpComplete = true;
+ }
+ }
+
+ public void FlipX (bool state) {
+ if (state != flipX) {
+ flipX = state;
+ if (flipX && Mathf.Abs(transform.localRotation.eulerAngles.y) > 90) {
+ skeletonUtility.skeletonAnimation.LateUpdate();
+ return;
+ } else if (!flipX && Mathf.Abs(transform.localRotation.eulerAngles.y) < 90) {
+ skeletonUtility.skeletonAnimation.LateUpdate();
+ return;
+ }
+ }
+
+ bone.FlipX = state;
+ transform.RotateAround(transform.position, skeletonUtility.transform.up, 180);
+ Vector3 euler = transform.localRotation.eulerAngles;
+ euler.x = 0;
+ euler.y = bone.FlipX ? 180 : 0;
+ transform.localRotation = Quaternion.Euler(euler);
+ }
+
+ void OnDrawGizmos () {
+ if (NonUniformScaleWarning) {
+ Gizmos.DrawIcon(transform.position + new Vector3(0, 0.128f, 0), "icon-warning");
+ }
+ }
+}
\ No newline at end of file
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityBone.cs.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityBone.cs.meta
new file mode 100644
index 000000000..f66d45053
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityBone.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b238dfcde8209044b97d23f62bcaadf6
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityConstraint.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityConstraint.cs
new file mode 100644
index 000000000..3be62228c
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityConstraint.cs
@@ -0,0 +1,22 @@
+using UnityEngine;
+using System.Collections;
+
+[RequireComponent(typeof(SkeletonUtilityBone)), ExecuteInEditMode]
+
+public abstract class SkeletonUtilityConstraint : MonoBehaviour {
+
+ protected SkeletonUtilityBone utilBone;
+ protected SkeletonUtility skeletonUtility;
+
+ protected virtual void OnEnable () {
+ utilBone = GetComponent();
+ skeletonUtility = SkeletonUtility.GetInParent(transform);
+ skeletonUtility.RegisterConstraint(this);
+ }
+
+ protected virtual void OnDisable () {
+ skeletonUtility.UnregisterConstraint(this);
+ }
+
+ public abstract void DoUpdate ();
+}
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityConstraint.cs.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityConstraint.cs.meta
new file mode 100644
index 000000000..dad11e0a2
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityConstraint.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 522dbfcc6c916df4396f14f35048d185
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityEyeConstraint.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityEyeConstraint.cs
new file mode 100644
index 000000000..6aefded5a
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityEyeConstraint.cs
@@ -0,0 +1,56 @@
+using UnityEngine;
+using System.Collections;
+
+public class SkeletonUtilityEyeConstraint : SkeletonUtilityConstraint {
+
+ public Transform[] eyes;
+ public float radius = 0.5f;
+ public Transform target;
+ public Vector3 targetPosition;
+ public float speed = 10;
+ Vector3[] origins;
+ Vector3 centerPoint;
+
+ protected override void OnEnable () {
+ if (!Application.isPlaying)
+ return;
+
+ base.OnEnable();
+
+ Bounds centerBounds = new Bounds(eyes[0].localPosition, Vector3.zero);
+ origins = new Vector3[eyes.Length];
+ for (int i = 0; i < eyes.Length; i++) {
+ origins[i] = eyes[i].localPosition;
+ centerBounds.Encapsulate(origins[i]);
+ }
+
+ centerPoint = centerBounds.center;
+ }
+
+ protected override void OnDisable () {
+ if (!Application.isPlaying)
+ return;
+
+ base.OnDisable();
+ }
+
+ public override void DoUpdate () {
+
+ if (target != null)
+ targetPosition = target.position;
+
+ Vector3 goal = targetPosition;
+
+ Vector3 center = transform.TransformPoint(centerPoint);
+ Vector3 dir = goal - center;
+
+ if (dir.magnitude > 1)
+ dir.Normalize();
+
+ for (int i = 0; i < eyes.Length; i++) {
+ center = transform.TransformPoint(origins[i]);
+ eyes[i].position = Vector3.MoveTowards(eyes[i].position, center + (dir * radius), speed * Time.deltaTime);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityEyeConstraint.cs.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityEyeConstraint.cs.meta
new file mode 100644
index 000000000..3e82746da
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityEyeConstraint.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0d994c65b6daec64f80ae2ae04e9d999
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityGroundConstraint.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityGroundConstraint.cs
new file mode 100644
index 000000000..b9608e9bc
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityGroundConstraint.cs
@@ -0,0 +1,120 @@
+using UnityEngine;
+using System.Collections;
+
+[RequireComponent(typeof(SkeletonUtilityBone)), ExecuteInEditMode]
+public class SkeletonUtilityGroundConstraint : SkeletonUtilityConstraint {
+
+#if UNITY_4_3
+ public LayerMask groundMask;
+ public bool use2D = false;
+ public bool useRadius = false;
+ public float castRadius = 0.1f;
+ public float castDistance = 5f;
+ public float castOffset = 0;
+ public float groundOffset = 0;
+ public float adjustSpeed = 5;
+#else
+ [Tooltip("LayerMask for what objects to raycast against")]
+ public LayerMask groundMask;
+ [Tooltip("The 2D")]
+ public bool use2D = false;
+ [Tooltip("Uses SphereCast for 3D mode and CircleCast for 2D mode")]
+ public bool useRadius = false;
+ [Tooltip("The Radius")]
+ public float castRadius = 0.1f;
+ [Tooltip("How high above the target bone to begin casting from")]
+ public float castDistance = 5f;
+ [Tooltip("X-Axis adjustment")]
+ public float castOffset = 0;
+ [Tooltip("Y-Axis adjustment")]
+ public float groundOffset = 0;
+ [Tooltip("How fast the target IK position adjusts to the ground. Use smaller values to prevent snapping")]
+ public float adjustSpeed = 5;
+#endif
+
+
+ Vector3 rayOrigin;
+ Vector3 rayDir = new Vector3(0, -1, 0);
+ float hitY;
+ float lastHitY;
+
+ protected override void OnEnable () {
+ base.OnEnable();
+ }
+
+ protected override void OnDisable () {
+ base.OnDisable();
+ }
+
+ public override void DoUpdate () {
+ rayOrigin = transform.position + new Vector3(castOffset, castDistance, 0);
+
+ hitY = float.MinValue;
+ if (use2D) {
+ RaycastHit2D hit;
+
+ if (useRadius) {
+#if UNITY_4_3
+ //NOTE: Unity 4.3.x does not have CircleCast
+ hit = Physics2D.Raycast(rayOrigin , rayDir, castDistance + groundOffset, groundMask);
+#else
+ hit = Physics2D.CircleCast(rayOrigin, castRadius, rayDir, castDistance + groundOffset, groundMask);
+#endif
+ } else {
+ hit = Physics2D.Raycast(rayOrigin, rayDir, castDistance + groundOffset, groundMask);
+ }
+
+ if (hit.collider != null) {
+ hitY = hit.point.y + groundOffset;
+ if (Application.isPlaying) {
+ hitY = Mathf.MoveTowards(lastHitY, hitY, adjustSpeed * Time.deltaTime);
+ }
+ } else {
+ if (Application.isPlaying)
+ hitY = Mathf.MoveTowards(lastHitY, transform.position.y, adjustSpeed * Time.deltaTime);
+ }
+ } else {
+ RaycastHit hit;
+ bool validHit = false;
+
+ if (useRadius) {
+ validHit = Physics.SphereCast(rayOrigin, castRadius, rayDir, out hit, castDistance + groundOffset, groundMask);
+ } else {
+ validHit = Physics.Raycast(rayOrigin, rayDir, out hit, castDistance + groundOffset, groundMask);
+ }
+
+ if (validHit) {
+ hitY = hit.point.y + groundOffset;
+ if (Application.isPlaying) {
+ hitY = Mathf.MoveTowards(lastHitY, hitY, adjustSpeed * Time.deltaTime);
+ }
+ } else {
+ if (Application.isPlaying)
+ hitY = Mathf.MoveTowards(lastHitY, transform.position.y, adjustSpeed * Time.deltaTime);
+ }
+ }
+
+ Vector3 v = transform.position;
+ v.y = Mathf.Clamp(v.y, Mathf.Min(lastHitY, hitY), float.MaxValue);
+ transform.position = v;
+
+ utilBone.bone.X = transform.localPosition.x;
+ utilBone.bone.Y = transform.localPosition.y;
+
+ lastHitY = hitY;
+ }
+
+ void OnDrawGizmos () {
+ Vector3 hitEnd = rayOrigin + (rayDir * Mathf.Min(castDistance, rayOrigin.y - hitY));
+ Vector3 clearEnd = rayOrigin + (rayDir * castDistance);
+ Gizmos.DrawLine(rayOrigin, hitEnd);
+
+ if (useRadius) {
+ Gizmos.DrawLine(new Vector3(hitEnd.x - castRadius, hitEnd.y - groundOffset, hitEnd.z), new Vector3(hitEnd.x + castRadius, hitEnd.y - groundOffset, hitEnd.z));
+ Gizmos.DrawLine(new Vector3(clearEnd.x - castRadius, clearEnd.y, clearEnd.z), new Vector3(clearEnd.x + castRadius, clearEnd.y, clearEnd.z));
+ }
+
+ Gizmos.color = Color.red;
+ Gizmos.DrawLine(hitEnd, clearEnd);
+ }
+}
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityGroundConstraint.cs.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityGroundConstraint.cs.meta
new file mode 100644
index 000000000..5d9e6920c
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityGroundConstraint.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3662334b99de5fe4396ab24e30c4fd12
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityKinematicShadow.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityKinematicShadow.cs
new file mode 100644
index 000000000..c088353f2
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityKinematicShadow.cs
@@ -0,0 +1,79 @@
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+
+public class SkeletonUtilityKinematicShadow : MonoBehaviour {
+ public bool hideShadow = true;
+ Dictionary shadowTable;
+ GameObject shadowRoot;
+
+ void Start () {
+ shadowRoot = (GameObject)Instantiate(gameObject);
+ if (hideShadow)
+ shadowRoot.hideFlags = HideFlags.HideInHierarchy;
+
+ shadowRoot.transform.parent = transform.root;
+
+ shadowTable = new Dictionary();
+
+ Destroy(shadowRoot.GetComponent());
+
+ shadowRoot.transform.position = transform.position;
+ shadowRoot.transform.rotation = transform.rotation;
+
+ Vector3 scaleRef = transform.TransformPoint(Vector3.right);
+ float scale = Vector3.Distance(transform.position, scaleRef);
+ shadowRoot.transform.localScale = Vector3.one;
+
+ var shadowJoints = shadowRoot.GetComponentsInChildren();
+ foreach (Joint j in shadowJoints) {
+ j.connectedAnchor *= scale;
+ }
+
+ var joints = GetComponentsInChildren();
+ foreach (var j in joints)
+ Destroy(j);
+
+ var rbs = GetComponentsInChildren();
+ foreach (var rb in rbs)
+ Destroy(rb);
+
+ var colliders = GetComponentsInChildren();
+ foreach (var c in colliders)
+ Destroy(c);
+
+
+ //match by bone name
+ var shadowBones = shadowRoot.GetComponentsInChildren();
+ var bones = GetComponentsInChildren();
+
+ //build bone lookup
+ foreach (var b in bones) {
+ if (b.gameObject == gameObject)
+ continue;
+
+ foreach (var sb in shadowBones) {
+ if (sb.rigidbody == null)
+ continue;
+
+ if (sb.boneName == b.boneName) {
+ shadowTable.Add(sb.transform, b.transform);
+ break;
+ }
+ }
+ }
+
+ foreach (var b in shadowBones)
+ Destroy(b);
+ }
+
+ void FixedUpdate () {
+ shadowRoot.rigidbody.MovePosition(transform.position);
+ shadowRoot.rigidbody.MoveRotation(transform.rotation);
+
+ foreach (var pair in shadowTable) {
+ pair.Value.localPosition = pair.Key.localPosition;
+ pair.Value.localRotation = pair.Key.localRotation;
+ }
+ }
+}
\ No newline at end of file
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityKinematicShadow.cs.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityKinematicShadow.cs.meta
new file mode 100644
index 000000000..06bcb6f4a
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilityKinematicShadow.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: cfeac06b8a6aa1645813700e3e4c0863
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs
new file mode 100644
index 000000000..fc8867e6b
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs
@@ -0,0 +1,96 @@
+using UnityEngine;
+using System.Collections;
+
+[ExecuteInEditMode]
+public class SkeletonUtilitySubmeshRenderer : MonoBehaviour {
+ public Renderer parentRenderer;
+ [System.NonSerialized]
+ public Mesh mesh;
+ public int submeshIndex = 0;
+ public int sortingOrder = 0;
+ public int sortingLayerID = 0;
+ public Material hiddenPassMaterial;
+ Renderer cachedRenderer;
+ MeshFilter filter;
+ Material[] sharedMaterials;
+ MeshFilter parentFilter;
+
+ void Awake () {
+ cachedRenderer = renderer;
+ sharedMaterials = cachedRenderer.sharedMaterials;
+ filter = GetComponent();
+
+ if (parentRenderer != null)
+ Initialize(parentRenderer);
+ }
+
+ void OnEnable () {
+ parentRenderer = transform.parent.GetComponent();
+ parentRenderer.GetComponent().OnReset += HandleSkeletonReset;
+ }
+
+ void OnDisable () {
+ parentRenderer.GetComponent().OnReset -= HandleSkeletonReset;
+ }
+
+ void HandleSkeletonReset (SkeletonRenderer r) {
+ if (parentRenderer != null)
+ Initialize(parentRenderer);
+ }
+
+ public void Initialize (Renderer parentRenderer) {
+ this.parentRenderer = parentRenderer;
+ parentFilter = parentRenderer.GetComponent();
+ mesh = parentFilter.sharedMesh;
+ filter.sharedMesh = mesh;
+ Debug.Log("Mesh: " + mesh);
+ }
+
+ public void Update () {
+ if (mesh == null || mesh != parentFilter.sharedMesh) {
+ mesh = parentFilter.sharedMesh;
+ filter.sharedMesh = mesh;
+ }
+
+ if (cachedRenderer == null)
+ cachedRenderer = renderer;
+
+ if (mesh == null || submeshIndex > mesh.subMeshCount - 1) {
+ cachedRenderer.enabled = false;
+ return;
+ } else {
+ renderer.enabled = true;
+ }
+
+ bool changed = false;
+
+ if (sharedMaterials.Length != parentRenderer.sharedMaterials.Length) {
+ sharedMaterials = parentRenderer.sharedMaterials;
+ changed = true;
+ }
+
+
+
+ for (int i = 0; i < renderer.sharedMaterials.Length; i++) {
+ if (i == submeshIndex)
+ continue;
+
+ if (sharedMaterials[i] != hiddenPassMaterial) {
+ sharedMaterials[i] = hiddenPassMaterial;
+ changed = true;
+ }
+ }
+
+ if (sharedMaterials[submeshIndex] != parentRenderer.sharedMaterials[submeshIndex]) {
+ sharedMaterials[submeshIndex] = parentRenderer.sharedMaterials[submeshIndex];
+ changed = true;
+ }
+
+ if (changed) {
+ cachedRenderer.sharedMaterials = sharedMaterials;
+ }
+
+ cachedRenderer.sortingLayerID = sortingLayerID;
+ cachedRenderer.sortingOrder = sortingOrder;
+ }
+}
diff --git a/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs.meta b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs.meta
new file mode 100644
index 000000000..168ca8811
--- /dev/null
+++ b/spine-tk2d/Assets/spine-tk2d/SkeletonUtility/SkeletonUtilitySubmeshRenderer.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 7820c1c2b0e52c6408de899d6939996e
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences:
+ - parentRenderer: {instanceID: 0}
+ - mesh: {instanceID: 0}
+ - hiddenPassMaterial: {fileID: 2100000, guid: 43227e5adadc6f24bb4bf74b92a56fb4,
+ type: 2}
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData: