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/examples/goblins/Goblins.cs b/spine-tk2d/Assets/examples/goblins/Goblins.cs index c30e677b0..bf3a78079 100644 --- a/spine-tk2d/Assets/examples/goblins/Goblins.cs +++ b/spine-tk2d/Assets/examples/goblins/Goblins.cs @@ -40,11 +40,11 @@ public class Goblins : MonoBehaviour { public void Start () { skeletonAnimation = GetComponent(); headBone = skeletonAnimation.skeleton.FindBone("head"); - skeletonAnimation.UpdateBones += UpdateBones; + skeletonAnimation.UpdateLocal += UpdateLocal; } // This is called after the animation is applied to the skeleton and can be used to adjust the bones dynamically. - public void UpdateBones (SkeletonAnimation skeletonAnimation) { + public void UpdateLocal (SkeletonAnimation skeletonAnimation) { headBone.Rotation += 15; } 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: