├── Assets ├── UnitySpineImporter.meta ├── UnitySpineImporter │ ├── 3DParty.meta │ ├── 3DParty │ │ ├── CurveExtension.meta │ │ ├── CurveExtension │ │ │ ├── CurveExtension.cs │ │ │ ├── CurveExtension.cs.meta │ │ │ ├── KeyframeUtil.cs │ │ │ └── KeyframeUtil.cs.meta │ │ ├── LitJson.meta │ │ └── LitJson │ │ │ ├── COPYING │ │ │ ├── COPYING.meta │ │ │ ├── LitJson.dll │ │ │ └── LitJson.dll.meta │ ├── Scripts.meta │ ├── Scripts │ │ ├── Editor.meta │ │ └── Editor │ │ │ ├── Model.meta │ │ │ ├── Model │ │ │ ├── Spine.meta │ │ │ ├── Spine │ │ │ │ ├── Atlas.meta │ │ │ │ ├── Atlas │ │ │ │ │ ├── SpineAtlas.cs │ │ │ │ │ ├── SpineAtlas.cs.meta │ │ │ │ │ ├── SpineMultialtas.cs │ │ │ │ │ ├── SpineMultialtas.cs.meta │ │ │ │ │ ├── SpineSprite.cs │ │ │ │ │ └── SpineSprite.cs.meta │ │ │ │ ├── Data.meta │ │ │ │ └── Data │ │ │ │ │ ├── Animation.meta │ │ │ │ │ ├── Animation │ │ │ │ │ ├── BoneAnimation.meta │ │ │ │ │ ├── BoneAnimation │ │ │ │ │ │ ├── SpineBoneAnimation.cs │ │ │ │ │ │ ├── SpineBoneAnimation.cs.meta │ │ │ │ │ │ ├── SpineBoneAnimationBaseValues.cs │ │ │ │ │ │ ├── SpineBoneAnimationBaseValues.cs.meta │ │ │ │ │ │ ├── SpineBoneRotateAnimation.cs │ │ │ │ │ │ ├── SpineBoneRotateAnimation.cs.meta │ │ │ │ │ │ ├── SpineBoneScaleAnimation.cs │ │ │ │ │ │ ├── SpineBoneScaleAnimation.cs.meta │ │ │ │ │ │ ├── SpineBoneTranslateAnimation.cs │ │ │ │ │ │ └── SpineBoneTranslateAnimation.cs.meta │ │ │ │ │ ├── DrawOrder.meta │ │ │ │ │ ├── DrawOrder │ │ │ │ │ │ ├── SpineDrawOrderAnimation.cs │ │ │ │ │ │ ├── SpineDrawOrderAnimation.cs.meta │ │ │ │ │ │ ├── SpineDrawOrderAnimationSlot.cs │ │ │ │ │ │ └── SpineDrawOrderAnimationSlot.cs.meta │ │ │ │ │ ├── SlotAnimation.meta │ │ │ │ │ ├── SlotAnimation │ │ │ │ │ │ ├── SpineSlotAnimation.cs │ │ │ │ │ │ ├── SpineSlotAnimation.cs.meta │ │ │ │ │ │ ├── SpineSlotAttachmentAnimation.cs │ │ │ │ │ │ ├── SpineSlotAttachmentAnimation.cs.meta │ │ │ │ │ │ ├── SpineSlotColorAnimation.cs │ │ │ │ │ │ └── SpineSlotColorAnimation.cs.meta │ │ │ │ │ ├── SpineAnimation.cs │ │ │ │ │ ├── SpineAnimation.cs.meta │ │ │ │ │ ├── SpineAnimationEvent.cs │ │ │ │ │ └── SpineAnimationEvent.cs.meta │ │ │ │ │ ├── Skin.meta │ │ │ │ │ ├── Skin │ │ │ │ │ ├── SpineSkinAttachment.cs │ │ │ │ │ ├── SpineSkinAttachment.cs.meta │ │ │ │ │ ├── SpineSkinSlotAttachments.cs │ │ │ │ │ ├── SpineSkinSlotAttachments.cs.meta │ │ │ │ │ ├── SpineSkinSlots.cs │ │ │ │ │ ├── SpineSkinSlots.cs.meta │ │ │ │ │ ├── SpineSkins.cs │ │ │ │ │ └── SpineSkins.cs.meta │ │ │ │ │ ├── SpineBone.cs │ │ │ │ │ ├── SpineBone.cs.meta │ │ │ │ │ ├── SpineData.cs │ │ │ │ │ ├── SpineData.cs.meta │ │ │ │ │ ├── SpineSlot.cs │ │ │ │ │ └── SpineSlot.cs.meta │ │ │ ├── Unity.meta │ │ │ └── Unity │ │ │ │ ├── SpritesByName.cs │ │ │ │ └── SpritesByName.cs.meta │ │ │ ├── SpineImporterWizard.cs │ │ │ ├── SpineImporterWizard.cs.meta │ │ │ ├── UnityInternalMethods.cs │ │ │ ├── UnityInternalMethods.cs.meta │ │ │ ├── Util.meta │ │ │ └── Util │ │ │ ├── SpineUtil.cs │ │ │ └── SpineUtil.cs.meta │ ├── SharedScripts.meta │ └── SharedScripts │ │ ├── AttachmentGOByName.cs │ │ ├── AttachmentGOByName.cs.meta │ │ ├── AttachmentGOByNameBySlot.cs │ │ ├── AttachmentGOByNameBySlot.cs.meta │ │ ├── Editor.meta │ │ ├── Editor │ │ ├── SkinControllerEditor.cs │ │ ├── SkinControllerEditor.cs.meta │ │ ├── SlotPropDrawer.cs │ │ └── SlotPropDrawer.cs.meta │ │ ├── Skin.meta │ │ ├── Skin │ │ ├── Skin.cs │ │ ├── Skin.cs.meta │ │ ├── SkinSlot.cs │ │ ├── SkinSlot.cs.meta │ │ ├── SkinSlotAttachment.cs │ │ └── SkinSlotAttachment.cs.meta │ │ ├── SkinController.cs │ │ ├── SkinController.cs.meta │ │ ├── SkinSlotGO.cs │ │ ├── SkinSlotGO.cs.meta │ │ ├── Slot.meta │ │ ├── Slot │ │ ├── Attachment.cs │ │ ├── Attachment.cs.meta │ │ ├── AttachmentType.cs │ │ ├── AttachmentType.cs.meta │ │ ├── Slot.cs │ │ └── Slot.cs.meta │ │ ├── SlotGOByName.cs │ │ ├── SlotGOByName.cs.meta │ │ ├── SlotGOByNameBySkinName.cs │ │ └── SlotGOByNameBySkinName.cs.meta └── test │ └── DrawOrder │ ├── 1.png │ ├── 1.png.meta │ ├── 2.png │ ├── 2.png.meta │ ├── 3.png │ ├── 3.png.meta │ ├── 4.png │ ├── 4.png.meta │ ├── animation.meta │ ├── animation │ ├── test_slot_order.anim.asset │ ├── test_slot_order.anim.asset.meta │ ├── test_slot_order.mask.asset │ └── test_slot_order.mask.asset.meta │ ├── spine.spine │ ├── spine.spine.meta │ ├── test_slot_order.atlas │ ├── test_slot_order.atlas.meta │ ├── test_slot_order.json │ ├── test_slot_order.json.meta │ ├── test_slot_order.png │ └── test_slot_order.png.meta ├── LICENSE ├── ProjectSettings ├── AudioManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NavMeshLayers.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset └── TimeManager.asset └── README.md /Assets/UnitySpineImporter.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aab12dc5231ef48b090bf4700fec66a4 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/3DParty.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9577a34d7e6da4ede9a2a8a7fbcbd493 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/3DParty/CurveExtension.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: efead4398b85c41dea12210782c3a6a4 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/3DParty/CurveExtension/CurveExtension.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | namespace CurveExtended{ 5 | 6 | public static class CurveExtension { 7 | 8 | public static void UpdateAllLinearTangents(this AnimationCurve curve){ 9 | for (int i = 0; i < curve.keys.Length; i++) { 10 | UpdateTangentsFromMode(curve, i); 11 | } 12 | } 13 | 14 | // UnityEditor.CurveUtility.cs (c) Unity Technologies 15 | public static void UpdateTangentsFromMode(AnimationCurve curve, int index) 16 | { 17 | if (index < 0 || index >= curve.length) 18 | return; 19 | Keyframe key = curve[index]; 20 | if (KeyframeUtil.GetKeyTangentMode(key, 0) == TangentMode.Linear && index >= 1) 21 | { 22 | key.inTangent = CalculateLinearTangent(curve, index, index - 1); 23 | curve.MoveKey(index, key); 24 | } 25 | if (KeyframeUtil.GetKeyTangentMode(key, 1) == TangentMode.Linear && index + 1 < curve.length) 26 | { 27 | key.outTangent = CalculateLinearTangent(curve, index, index + 1); 28 | curve.MoveKey(index, key); 29 | } 30 | if (KeyframeUtil.GetKeyTangentMode(key, 0) != TangentMode.Smooth && KeyframeUtil.GetKeyTangentMode(key, 1) != TangentMode.Smooth) 31 | return; 32 | curve.SmoothTangents(index, 0.0f); 33 | } 34 | 35 | // UnityEditor.CurveUtility.cs (c) Unity Technologies 36 | public static float CalculateLinearTangent(AnimationCurve curve, int index, int toIndex) 37 | { 38 | return (float) (((double) curve[index].value - (double) curve[toIndex].value) / ((double) curve[index].time - (double) curve[toIndex].time)); 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/3DParty/CurveExtension/CurveExtension.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d5ba2492951b2420da779a4bc9e093eb 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/3DParty/CurveExtension/KeyframeUtil.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Reflection; 4 | using System; 5 | 6 | namespace CurveExtended{ 7 | [Flags] 8 | public enum TangentMode 9 | { 10 | Editable = 0, 11 | Smooth = 1, 12 | Linear = 2, 13 | Stepped = Linear | Smooth, 14 | } 15 | 16 | public enum TangentDirection 17 | { 18 | Left, 19 | Right 20 | } 21 | 22 | 23 | public class KeyframeUtil { 24 | 25 | public static Keyframe GetNew( float time, float value, TangentMode leftAndRight){ 26 | return GetNew(time, value, leftAndRight,leftAndRight); 27 | } 28 | 29 | public static Keyframe GetNew(float time, float value, TangentMode left, TangentMode right){ 30 | object boxed = new Keyframe(time,value); // cant use struct in reflection 31 | 32 | SetKeyBroken(boxed, true); 33 | SetKeyTangentMode(boxed, 0, left); 34 | SetKeyTangentMode(boxed, 1, right); 35 | 36 | Keyframe keyframe = (Keyframe)boxed; 37 | if (left == TangentMode.Stepped ) 38 | keyframe.inTangent = float.PositiveInfinity; 39 | if (right == TangentMode.Stepped ) 40 | keyframe.outTangent = float.PositiveInfinity; 41 | 42 | return keyframe; 43 | } 44 | 45 | 46 | // UnityEditor.CurveUtility.cs (c) Unity Technologies 47 | public static void SetKeyTangentMode(object keyframe, int leftRight, TangentMode mode) 48 | { 49 | 50 | Type t = typeof( UnityEngine.Keyframe ); 51 | FieldInfo field = t.GetField( "m_TangentMode", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance ); 52 | int tangentMode = (int)field.GetValue(keyframe); 53 | 54 | if (leftRight == 0) 55 | { 56 | tangentMode &= -7; 57 | tangentMode |= (int) mode << 1; 58 | } 59 | else 60 | { 61 | tangentMode &= -25; 62 | tangentMode |= (int) mode << 3; 63 | } 64 | 65 | field.SetValue(keyframe, tangentMode); 66 | if (GetKeyTangentMode(tangentMode, leftRight) == mode) 67 | return; 68 | Debug.Log("bug"); 69 | } 70 | 71 | // UnityEditor.CurveUtility.cs (c) Unity Technologies 72 | public static TangentMode GetKeyTangentMode(int tangentMode, int leftRight) 73 | { 74 | if (leftRight == 0) 75 | return (TangentMode) ((tangentMode & 6) >> 1); 76 | else 77 | return (TangentMode) ((tangentMode & 24) >> 3); 78 | } 79 | 80 | // UnityEditor.CurveUtility.cs (c) Unity Technologies 81 | public static TangentMode GetKeyTangentMode(Keyframe keyframe, int leftRight) 82 | { 83 | Type t = typeof( UnityEngine.Keyframe ); 84 | FieldInfo field = t.GetField( "m_TangentMode", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance ); 85 | int tangentMode = (int)field.GetValue(keyframe); 86 | if (leftRight == 0) 87 | return (TangentMode) ((tangentMode & 6) >> 1); 88 | else 89 | return (TangentMode) ((tangentMode & 24) >> 3); 90 | } 91 | 92 | 93 | // UnityEditor.CurveUtility.cs (c) Unity Technologies 94 | public static void SetKeyBroken(object keyframe, bool broken) 95 | { 96 | Type t = typeof( UnityEngine.Keyframe ); 97 | FieldInfo field = t.GetField( "m_TangentMode", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance ); 98 | int tangentMode = (int)field.GetValue(keyframe); 99 | 100 | if (broken) 101 | tangentMode |= 1; 102 | else 103 | tangentMode &= -2; 104 | field.SetValue(keyframe, tangentMode); 105 | } 106 | 107 | // UnityEditor.CurveUtility.cs (c) Unity Technologies 108 | public static bool isKeyBroken(object keyframe){ 109 | Type t = typeof( UnityEngine.Keyframe ); 110 | FieldInfo field = t.GetField( "m_TangentMode", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance ); 111 | int tangentMode = (int)field.GetValue(keyframe); 112 | return (tangentMode & 1) != 0; 113 | } 114 | 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/3DParty/CurveExtension/KeyframeUtil.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2cf707975f5fb4475bb58509ea5b7e9a 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/3DParty/LitJson.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a23f3323700db450497c73ab8acb92ce 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/3DParty/LitJson/COPYING: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | Thank you for reading this notice. Following the tradition of other public 27 | domain projects, here's a blessing: 28 | 29 | May you find forgiveness for yourself and forgive others. 30 | May you experience and share the gift of unconditional love. 31 | May you see light, wherever the illusion of darkness appears. 32 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/3DParty/LitJson/COPYING.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4529868f627d14b22b11b46db17cdc4e 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/3DParty/LitJson/LitJson.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/Assets/UnitySpineImporter/3DParty/LitJson/LitJson.dll -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/3DParty/LitJson/LitJson.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83dbda8cdbcd847979520d7f99b87c2a 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ce72e6ed28c07432e8ac44dbebf3d89b 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ff1f6715789444e3a9cc5a65929ee676 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f46c48ed9b281480d9ace8f758d99218 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8054e6bc346f0497bb65bd033ddc746c 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Atlas.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d5bce7205c56e4d43bbbb10802cfc538 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Atlas/SpineAtlas.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace UnitySpineImporter{ 6 | public class SpineAtlas { 7 | public string imageName; 8 | public string format; 9 | public string filter; 10 | public string repeat; 11 | public List sprites; 12 | } 13 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Atlas/SpineAtlas.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a77cf6a954ba04e80a58e11d50875622 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Atlas/SpineMultialtas.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | 6 | namespace UnitySpineImporter{ 7 | public class SpineMultiatlasCreationException: System.Exception{ 8 | public SpineMultiatlasCreationException(string message):base(message) 9 | { 10 | } 11 | } 12 | 13 | 14 | public class SpineMultiatlas : List { 15 | 16 | public static SpineMultiatlas deserializeFromFile(string multiatlasFilePath){ 17 | SpineMultiatlas multiAtlas = new SpineMultiatlas(); 18 | if (!File.Exists(multiatlasFilePath)) 19 | throw new SpineMultiatlasCreationException("provided file does not exists"); 20 | using(StreamReader streamReader = new StreamReader(multiatlasFilePath)){ 21 | string line; 22 | string spriteNameAfterProps = ""; 23 | bool setMainProps = false; 24 | SpineAtlas spineAtlas = null; 25 | SpineSprite sprite = null; 26 | while((line = streamReader.ReadLine())!=null){ 27 | if (line==""){ 28 | setMainProps = true; 29 | } else { 30 | if (setMainProps){ 31 | spineAtlas = new SpineAtlas(); 32 | multiAtlas.Add(spineAtlas); 33 | spineAtlas.imageName = line; 34 | Dictionary keyValue = new Dictionary(); 35 | string[] kvp; 36 | while( (kvp= streamReader.ReadLine().Split(':')).Length == 2) 37 | keyValue.Add(kvp[0].Trim(), kvp[1].Trim()); 38 | 39 | spineAtlas.format = keyValue["format"]; 40 | spineAtlas.filter = keyValue["filter"]; 41 | spineAtlas.repeat = keyValue["repeat"]; 42 | 43 | spriteNameAfterProps = kvp[0]; 44 | spineAtlas.sprites = new List(); 45 | setMainProps = false; 46 | 47 | } 48 | 49 | if (!setMainProps){ 50 | sprite = new SpineSprite(); 51 | 52 | if (string.IsNullOrEmpty( spriteNameAfterProps)){ 53 | sprite.name = line; 54 | } else { 55 | sprite.name = spriteNameAfterProps; 56 | spriteNameAfterProps = ""; 57 | } 58 | try{ 59 | sprite.rotate = bool.Parse(streamReader.ReadLine().Split(':')[1]); 60 | sprite.xy = SpineUtil.lineToVector2(streamReader.ReadLine()); 61 | sprite.size = SpineUtil.lineToVector2(streamReader.ReadLine()); 62 | sprite.orig = SpineUtil.lineToVector2(streamReader.ReadLine()); 63 | sprite.offset = SpineUtil.lineToVector2(streamReader.ReadLine()); 64 | sprite.index = int.Parse(streamReader.ReadLine().Split(':')[1]); 65 | } catch (System.FormatException e) { 66 | throw new SpineMultiatlasCreationException("can't parse source file \n" + multiatlasFilePath +"\n"+e); 67 | } 68 | spineAtlas.sprites.Add(sprite); 69 | } 70 | } 71 | } 72 | } 73 | 74 | if (multiAtlas.Count == 0) 75 | throw new SpineMultiatlasCreationException("don't have any atlases in provided file"); 76 | return multiAtlas; 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Atlas/SpineMultialtas.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa20af245c9fb420f8318e890a91ddfc 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Atlas/SpineSprite.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | namespace UnitySpineImporter{ 4 | public class SpineSprite { 5 | public string name; 6 | 7 | public bool rotate; 8 | public Vector2 xy; 9 | public Vector2 size; 10 | public Vector2 orig; 11 | public Vector2 offset; 12 | public int index; // not used (http://esotericsoftware.com/forum/viewtopic.php?f=7&t=1933) 13 | } 14 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Atlas/SpineSprite.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f6320ba1da5db4090bda6b99fe2b0852 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 720f4c5586aef402bb5f765ba2cd6fba 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 34920a2e4271e49eb8fe5598f174944f 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/BoneAnimation.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b9d9e602a201f4623b207c9e5124edaf 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/BoneAnimation/SpineBoneAnimation.cs: -------------------------------------------------------------------------------- 1 |  2 | using System.Collections.Generic; 3 | 4 | namespace UnitySpineImporter{ 5 | public class SpineBoneAnimation { 6 | public List translate; 7 | public List rotate; 8 | public List scale; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/BoneAnimation/SpineBoneAnimation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8b1d4624921984687a8917a59d884251 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/BoneAnimation/SpineBoneAnimationBaseValues.cs: -------------------------------------------------------------------------------- 1 | using LitJson; 2 | 3 | namespace UnitySpineImporter{ 4 | public class SpineBoneAnimationBaseValues { 5 | public double time; 6 | public JsonData curve;/* linear|stepped|double[] <<-- because of array this type is Json data because it can be string or array. 7 | The interpolation to use between this and the next keyframe. One of: linear, stepped, or an array defining a Bézier curve. Assume “linear” if omitted. 8 | The Bézier curve array has 4 elements which define the control points: cx1, cy1, cx2, cy2. The X axis is from 0 to 1 and represents the percent of time between the two keyframes. The Y axis is from 0 to 1 and represents the percent of the difference between the keyframe’s values. 9 | */ 10 | } 11 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/BoneAnimation/SpineBoneAnimationBaseValues.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 92c2b8fbc17674cd9be803512580c6b0 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/BoneAnimation/SpineBoneRotateAnimation.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace UnitySpineImporter{ 3 | public class SpineBoneRotateAnimation : SpineBoneAnimationBaseValues{ 4 | public double angle; 5 | } 6 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/BoneAnimation/SpineBoneRotateAnimation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f0753b8302b9c4d42a4b5e30718074fd 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/BoneAnimation/SpineBoneScaleAnimation.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace UnitySpineImporter{ 3 | public class SpineBoneScaleAnimation : SpineBoneAnimationBaseValues { 4 | public double x; 5 | public double y; 6 | } 7 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/BoneAnimation/SpineBoneScaleAnimation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba36a5e8214f1445d9f3bf931391291b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/BoneAnimation/SpineBoneTranslateAnimation.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace UnitySpineImporter{ 3 | public class SpineBoneTranslateAnimation : SpineBoneAnimationBaseValues { 4 | public double x; 5 | public double y; 6 | } 7 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/BoneAnimation/SpineBoneTranslateAnimation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: baafb7e260e7c402eba8cec72059b586 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/DrawOrder.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 991cc60832cf24bd68216f7ea9b307e4 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/DrawOrder/SpineDrawOrderAnimation.cs: -------------------------------------------------------------------------------- 1 | namespace UnitySpineImporter{ 2 | public class SpineDrawOrderAnimation { 3 | public double time; 4 | public SpineDrawOrderAnimationSlot[] offsets; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/DrawOrder/SpineDrawOrderAnimation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 096d31952566f45e6a469137a0474f2b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/DrawOrder/SpineDrawOrderAnimationSlot.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace UnitySpineImporter{ 3 | public class SpineDrawOrderAnimationSlot { 4 | public string slot; 5 | public int offset; 6 | } 7 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/DrawOrder/SpineDrawOrderAnimationSlot.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 360be07ee884b49948c635f3e17e18c8 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/SlotAnimation.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f83a93731d07d420bbeefdf40cd290de 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/SlotAnimation/SpineSlotAnimation.cs: -------------------------------------------------------------------------------- 1 |  2 | using System.Collections.Generic; 3 | 4 | namespace UnitySpineImporter{ 5 | public class SpineSlotAnimation { 6 | public List attachment; 7 | public List color; 8 | } 9 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/SlotAnimation/SpineSlotAnimation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ed4a5ffdaeca440e2b253bf4ee3a2485 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/SlotAnimation/SpineSlotAttachmentAnimation.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace UnitySpineImporter{ 3 | public class SpineSlotAttachmentAnimation { 4 | public double time; 5 | public string name; //name of attachment 6 | } 7 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/SlotAnimation/SpineSlotAttachmentAnimation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 47764fbe32dd24504b98ae4b2c922acd 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/SlotAnimation/SpineSlotColorAnimation.cs: -------------------------------------------------------------------------------- 1 | using LitJson; 2 | 3 | namespace UnitySpineImporter{ 4 | public class SpineSlotColorAnimation { 5 | public double time; 6 | public string color; // FFFFFFFF hex 7 | public JsonData curve; /* 8 | The interpolation to use between this and the next keyframe. One of: linear, stepped, or an array defining a Bézier curve. Assume “linear” if omitted. 9 | The Bézier curve array has 4 elements which define the control points: cx1, cy1, cx2, cy2. The X axis is from 0 to 1 and represents the percent of time between the two keyframes. The Y axis is from 0 to 1 and represents the percent of the difference between the keyframe’s values. 10 | */ 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/SlotAnimation/SpineSlotColorAnimation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: be18b0168d88a4802bf2b1a038edc19b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/SpineAnimation.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using LitJson; 3 | 4 | namespace UnitySpineImporter{ 5 | public class SpineAnimation { 6 | public Dictionary< string, SpineBoneAnimation > bones; 7 | public Dictionary< string, SpineSlotAnimation > slots; 8 | public List< SpineDrawOrderAnimation > draworder; 9 | public List< JsonData > events; 10 | } 11 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/SpineAnimation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 055cc312297c644b2a01c2f44287ab1a 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/SpineAnimationEvent.cs: -------------------------------------------------------------------------------- 1 | using LitJson; 2 | namespace UnitySpineImporter { 3 | public class SpineAnimationEvent { 4 | public double time; 5 | public string name; 6 | 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Animation/SpineAnimationEvent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c8790a731d2e140268f8de897df73215 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Skin.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ac689827e31234827ac39f0a7d52fd64 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Skin/SpineSkinAttachment.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace UnitySpineImporter{ 3 | public class SpineSkinAttachment { 4 | public string name; 5 | public string type = "region"; //region|regionsequence|boundingbox . TODO - regionsequence not implemented 6 | public double x = 0; 7 | public double y = 0; 8 | public double scaleX = 1; 9 | public double scaleY = 1; 10 | public double rotation = 0; 11 | public double width; //TODO - not implemented 12 | public double height; //TODO - not implemented 13 | 14 | //- regionsequence block TODO - not implementd 15 | public double fps; //TODO - not implemented 16 | public string mode; //TODO - not implemented (forward, backward, forwardLoop, backwardLoop, pingPong, or random) 17 | // 18 | 19 | //- boundingbox block 20 | public double[] vertices; 21 | } 22 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Skin/SpineSkinAttachment.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02c13f56ff3c34902bd1396dcec2b056 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Skin/SpineSkinSlotAttachments.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace UnitySpineImporter{ 4 | public class SpineSkinSlotAttachments : Dictionary { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Skin/SpineSkinSlotAttachments.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d576a0e3561764ec2ad6da482a8ff497 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Skin/SpineSkinSlots.cs: -------------------------------------------------------------------------------- 1 |  2 | using System.Collections.Generic; 3 | 4 | namespace UnitySpineImporter{ 5 | public class SpineSkinSlots : Dictionary { 6 | } 7 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Skin/SpineSkinSlots.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 54859c5bf40264816bf09504e4fed54b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Skin/SpineSkins.cs: -------------------------------------------------------------------------------- 1 | 2 | using System.Collections.Generic; 3 | using System.Collections; 4 | 5 | namespace UnitySpineImporter{ 6 | public class SpineSkins: Dictionary{ 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/Skin/SpineSkins.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b03ad2be34e97471d8501fd0adab80bc 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/SpineBone.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace UnitySpineImporter{ 3 | public class SpineBone { 4 | public string name; 5 | public string parent; 6 | public double length = 0; 7 | public double x = 0; 8 | public double y = 0; 9 | public double scaleX = 1; 10 | public double scaleY = 1; 11 | public double rotation = 0; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/SpineBone.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8bb2d4ce4e12d4bdebeb3bdfa1df02d6 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/SpineData.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Collections.Generic; 3 | using LitJson; 4 | using UnityEngine; 5 | 6 | namespace UnitySpineImporter{ 7 | public class SpineDatatCreationException:System.Exception{ 8 | public SpineDatatCreationException(string message):base(message) 9 | { 10 | } 11 | } 12 | 13 | public class SpineData{ 14 | 15 | public List bones; 16 | public List slots; 17 | 18 | public SpineSkins skins; 19 | 20 | public Dictionary animations; 21 | 22 | 23 | public Dictionary boneByName; 24 | public Dictionary slotByName; 25 | public Dictionary slotOrder; 26 | public Dictionary bonePathByName; 27 | public Dictionary slotPathByName; 28 | 29 | public string defaultSkinName; 30 | public string[] skinNames; 31 | public string[] defaultPoseSlots; 32 | public Dictionary slotDefaultAttachments; 33 | 34 | 35 | 36 | public static SpineData deserializeFromFile(string spineDataFilePath){ 37 | SpineData data = null; 38 | if (!File.Exists(spineDataFilePath)) 39 | throw new SpineDatatCreationException("provided file does not exists"); 40 | try{ 41 | data = LitJson.JsonMapper.ToObject(File.ReadAllText(spineDataFilePath)); 42 | } catch (LitJson.JsonException e){ 43 | throw new SpineDatatCreationException("problem with parse json data \n"+e.Message); 44 | } 45 | setCachedData(data); 46 | fixeAttachmentNamesIfOmited(data); 47 | return data; 48 | } 49 | 50 | static void fixeAttachmentNamesIfOmited (SpineData data) 51 | { 52 | foreach(KeyValuePairkvp in data.skins){ 53 | string skinName = kvp.Key; 54 | foreach(KeyValuePairkvp2 in data.skins[skinName]){ 55 | string slotName = kvp2.Key; 56 | foreach(KeyValuePair kvp3 in data.skins[skinName][slotName]){ 57 | string attachmentName = kvp3.Key; 58 | SpineSkinAttachment attachment = kvp3.Value; 59 | if (string.IsNullOrEmpty(attachment.name)) 60 | attachment.name = attachmentName; // we set actualAttachment(sprite name) here in case if it empty it equal to attachment name 61 | } 62 | } 63 | } 64 | } 65 | 66 | static void setCachedData (SpineData data) 67 | { 68 | data.slotByName = new Dictionary(); 69 | 70 | 71 | data.boneByName = new Dictionary(); 72 | for (int i = 0; i < data.bones.Count; i++) { 73 | data.boneByName.Add(data.bones[i].name, data.bones[i]); 74 | } 75 | 76 | data.bonePathByName = new Dictionary(); 77 | 78 | foreach (SpineBone bone in data.bones){ 79 | string path = ""; 80 | SpineBone b = bone; 81 | do { 82 | path=b.name+"/"+path; 83 | if (!string.IsNullOrEmpty( b.parent)) 84 | b = data.boneByName[b.parent]; 85 | else 86 | b = null; 87 | } while (b!=null); 88 | 89 | if (path.Length >0) 90 | path = path.Remove(path.Length - 1); 91 | 92 | data.bonePathByName.Add(bone.name, path); 93 | } 94 | 95 | 96 | data.slotOrder = new Dictionary(); 97 | 98 | data.slotPathByName = new Dictionary(); 99 | data.slotDefaultAttachments = new Dictionary(); 100 | for (int i = 0; i < data.slots.Count; i++) { 101 | string slotName = data.slots[i].name; 102 | string defaultAttachment = data.slots[i].attachment; 103 | data.slotOrder.Add(slotName, i); 104 | string boneName = data.slots[i].bone; 105 | string bonePath = data.bonePathByName[boneName]; 106 | string slotPath = bonePath+"/" + SpineUtil.getSlotGOName(slotName); 107 | data.slotPathByName.Add(slotName, slotPath); 108 | data.slotDefaultAttachments.Add(slotName, defaultAttachment); 109 | } 110 | } 111 | 112 | } 113 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/SpineData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f4a5dbde1587a41ada66e5b1273591cd 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/SpineSlot.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace UnitySpineImporter{ 3 | public class SpineSlot{ 4 | public string name; 5 | public string bone; 6 | public string color = "FFFFFFFF"; // This is an 8 character string containing 4 two digit hex numbers in RGBA order. Assume “FFFFFFFF” if omitted. 7 | public string attachment; 8 | } 9 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Spine/Data/SpineSlot.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3f023dcfa95454622b0dc40b55efaafc 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 972ac560b7d1e4292a9eb3661803d95f 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Unity/SpritesByName.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | 5 | public class SpritesByName : Dictionary { 6 | public HashSet rotatedSprites; 7 | 8 | public SpritesByName():base(){ 9 | rotatedSprites = new HashSet(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Model/Unity/SpritesByName.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fdf70a72297d3463290b3288c141cc13 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/SpineImporterWizard.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using UnityEditor; 4 | using System.IO; 5 | using System.Collections.Generic; 6 | 7 | 8 | namespace UnitySpineImporter{ 9 | 10 | public class SpineImporterWizard :ScriptableWizard { 11 | public int pixelsPerUnit = 100; 12 | public bool buildAvatarMask = true; 13 | public bool useLegacyAnimation = false; //false - means mecanim 14 | public bool updateResources = true; 15 | public float zStep = 0.01f; 16 | [HideInInspector] 17 | public string path; 18 | 19 | [MenuItem("Assets/Spine build prefab", false)] 20 | public static void spineBuildPrefab(){ 21 | string path = AssetDatabase.GetAssetPath(Selection.activeObject); 22 | SpineImporterWizard wizard = ScriptableWizard.DisplayWizard("Generate Prefab from Spine data", "Generate"); 23 | wizard.path = path; 24 | } 25 | 26 | [MenuItem("Assets/Spine build prefab", true)] 27 | public static bool validateContext(){ 28 | string path = AssetDatabase.GetAssetPath(Selection.activeObject); 29 | return path.EndsWith(".json"); 30 | } 31 | 32 | void OnWizardUpdate() { 33 | helpString = "Be carefull, don't use small amout of pixels per unit (e.g. 1 or 10) \n" + 34 | "if you are going to use result model with unity 2d physics and gravity\n" + 35 | "update resources means - instead of create new animator and new animations update them"; 36 | if (pixelsPerUnit <=0) 37 | errorString = "PixelsPerUnit must be greater than zero"; 38 | else 39 | errorString =""; 40 | isValid = errorString.Equals(""); 41 | if (useLegacyAnimation && buildAvatarMask) 42 | helpString += "\n buildAvatarMask will be ignored"; 43 | } 44 | 45 | 46 | void OnWizardCreate(){ 47 | string atlasPath = getAtlasFilePath(path); 48 | string directory = Path.GetDirectoryName(atlasPath); 49 | string name = Path.GetFileNameWithoutExtension(path); 50 | SpritesByName spriteByName; 51 | Dictionary boneGOByName; 52 | Dictionary slotByName; 53 | List skins; 54 | AttachmentGOByNameBySlot attachmentGOByNameBySlot; 55 | 56 | if (File.Exists(path)){ 57 | try{ 58 | SpineMultiatlas spineMultiAtlas = SpineMultiatlas.deserializeFromFile(atlasPath ); 59 | SpineData spineData = SpineData .deserializeFromFile(path); 60 | 61 | SpineUtil.updateImporters(spineMultiAtlas, directory, pixelsPerUnit, out spriteByName); 62 | GameObject rootGO = SpineUtil.buildSceleton(name, spineData, pixelsPerUnit, zStep, out boneGOByName, out slotByName); 63 | rootGO.name = name; 64 | SpineUtil.addAllAttahcmentsSlots(spineData, spriteByName, slotByName, pixelsPerUnit, out skins, out attachmentGOByNameBySlot); 65 | SkinController sk = SpineUtil.addSkinController(rootGO, spineData, skins, slotByName); 66 | if (!useLegacyAnimation){ 67 | Animator animator = SpineUtil.addAnimator(rootGO); 68 | if (buildAvatarMask) 69 | SpineUtil.builAvatarMask(rootGO,spineData, animator, directory, name); 70 | } 71 | 72 | if (spineData.animations !=null && spineData.animations.Count > 0) 73 | SpineUtil.addAnimation(rootGO, directory, spineData, boneGOByName, slotByName, attachmentGOByNameBySlot, skins, 74 | pixelsPerUnit, zStep, useLegacyAnimation, updateResources ); 75 | sk.showDefaulSlots(); 76 | SpineUtil.buildPrefab(rootGO, directory, name); 77 | GameObject.DestroyImmediate(rootGO); 78 | 79 | } catch (SpineMultiatlasCreationException e){ 80 | Debug.LogException(e); 81 | } catch (SpineDatatCreationException e){ 82 | Debug.LogException(e); 83 | } catch (AtlasImageDuplicateSpriteName e){ 84 | Debug.LogException(e); 85 | } 86 | } 87 | } 88 | 89 | static string getAtlasFilePath(string path){ 90 | string dir = Path.GetDirectoryName(path); 91 | string fileName = Path.GetFileNameWithoutExtension(path+"ffff"); 92 | return dir + "/" + fileName + ".atlas"; 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/SpineImporterWizard.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: de97a4305103046df9d2e1125d107dec 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/UnityInternalMethods.cs: -------------------------------------------------------------------------------- 1 |  2 | using UnityEditor.Animations; 3 | using UnityEngine; 4 | using System.Reflection; 5 | using UnityEditor; 6 | 7 | public class UnityInternalMethods { 8 | public static AnimatorController GetEffectiveAnimatorController(Animator animator){ 9 | return (AnimatorController) (typeof(AnimatorController).GetMethod("GetEffectiveAnimatorController" 10 | , BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[]{ animator})); 11 | } 12 | 13 | public static void GetTextureSize(TextureImporter textureImporter, out int width, out int height){ 14 | object[] args = new object[2] { 0, 0 }; 15 | MethodInfo mi = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance); 16 | mi.Invoke(textureImporter, args); 17 | width = (int)args[0]; 18 | height = (int)args[1]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/UnityInternalMethods.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0431ec8deb4b24d35b064852bd344afc 3 | timeCreated: 1436945266 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Util.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 515c9b2aeb1e941719760a5ba310e103 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Util/SpineUtil.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.IO; 4 | using UnityEditor; 5 | using System.Collections.Generic; 6 | using System; 7 | using UnityEditorInternal; 8 | using CurveExtended; 9 | using LitJson; 10 | using UnityEditor.Animations; 11 | 12 | namespace UnitySpineImporter{ 13 | public class AtlasImageNotFoundException: System.Exception{ 14 | public AtlasImageNotFoundException(string message):base(message){ 15 | } 16 | } 17 | 18 | public class AtlasImageDuplicateSpriteName:System.Exception{ 19 | public AtlasImageDuplicateSpriteName(string message):base(message){ 20 | } 21 | } 22 | 23 | public class SpineUtil { 24 | public static string SLOT_PREFIX = "slot"; 25 | public static string SKIN_PREFIX = "skin"; 26 | public static string ANIMATION_FOLDER = "animation"; 27 | public static string SLASH_REPLACEMENT = "|"; 28 | 29 | public static Vector2 lineToVector2(string line){ 30 | string[] xy = null; 31 | try{ 32 | line = line.Split(':')[1]; 33 | xy = line.Split(','); 34 | } finally{ 35 | } 36 | return new Vector2(int.Parse(xy[0]), int.Parse( xy[1])); 37 | 38 | } 39 | 40 | public static void buildPrefab(GameObject gameObject, string directory, string name){ 41 | string prefabPath = directory + "/" + name + ".prefab"; 42 | UnityEngine.Object oldPrefab = AssetDatabase.LoadAssetAtPath( prefabPath, typeof(GameObject)); 43 | if (oldPrefab == null) 44 | PrefabUtility.CreatePrefab(prefabPath, gameObject, ReplacePrefabOptions.ConnectToPrefab); 45 | else 46 | PrefabUtility.ReplacePrefab(gameObject, oldPrefab, ReplacePrefabOptions.ReplaceNameBased); 47 | } 48 | 49 | public static void builAvatarMask(GameObject gameObject, SpineData spineData, Animator animator, string directory, string name){ 50 | Avatar avatar = AvatarBuilder.BuildGenericAvatar(gameObject,""); 51 | animator.avatar = avatar; 52 | AvatarMask avatarMask = new AvatarMask(); 53 | string[] transofrmPaths = getTransformPaths(gameObject, spineData); 54 | avatarMask.transformCount = transofrmPaths.Length; 55 | for (int i=0; i< transofrmPaths.Length; i++){ 56 | avatarMask.SetTransformPath(i, transofrmPaths[i]); 57 | avatarMask.SetTransformActive(i, true); 58 | } 59 | createFolderIfNoExists(directory, ANIMATION_FOLDER); 60 | AssetDatabase.CreateAsset(avatar , directory + "/" + ANIMATION_FOLDER + "/" + name + ".anim.asset"); 61 | AssetDatabase.CreateAsset(avatarMask, directory + "/" + ANIMATION_FOLDER + "/" + name + ".mask.asset"); 62 | } 63 | 64 | public static string[] getTransformPaths(GameObject go, SpineData spineData){ 65 | List result = new List(); 66 | result.Add(""); 67 | foreach(Transform t in go.GetComponentsInChildren(true)){ 68 | string path = AnimationUtility.CalculateTransformPath(t,go.transform); 69 | if (t.name.StartsWith(SLOT_PREFIX+" [") && t.name.EndsWith("]")){ 70 | string slotName = t.name.Remove(t.name.Length -1); 71 | slotName = slotName.Remove(0,(SLOT_PREFIX+" [").Length ); 72 | if (spineData.slotPathByName.ContainsKey(slotName) && spineData.slotPathByName[slotName]==path) 73 | result.Add(path); 74 | }else { 75 | if (spineData.bonePathByName.ContainsKey(t.name) && spineData.bonePathByName[t.name]==path) 76 | result.Add(path); 77 | } 78 | 79 | } 80 | return result.ToArray(); 81 | } 82 | 83 | static int[] sizes = new int[]{0, 32, 64, 128, 256, 512, 1024, 2048, 4096}; 84 | static string[] platforms = new string[]{"Web", "Standalone", "iPhone", "Android", "FlashPlayer"}; 85 | static void fixTextureSize(string imagePath){ 86 | TextureImporter importer = TextureImporter.GetAtPath(imagePath) as TextureImporter; 87 | if (importer != null) { 88 | int width, height; 89 | UnityInternalMethods.GetTextureSize(importer, out width, out height); 90 | 91 | int max = Mathf.Max(width,height); 92 | if (max > 4096){ 93 | Debug.LogError("original texture size is to big " + imagePath + " size=" + width + "x" + height); 94 | return; 95 | } 96 | 97 | int fitSize = 0; 98 | for (int i = 0,nextI =1; i < max && fitSize==0; i=nextI++ ) { 99 | if (max > sizes[i] && max <= sizes[nextI] ) 100 | fitSize = sizes[nextI]; 101 | } 102 | 103 | if (importer.maxTextureSize!=fitSize){ 104 | Debug.LogWarning("change default size to " + fitSize+ " for "+imagePath); 105 | importer.maxTextureSize = fitSize; 106 | } 107 | 108 | foreach(string platform in platforms){ 109 | int maxTextureSize; 110 | TextureImporterFormat textureFormat; 111 | importer.GetPlatformTextureSettings(platform, out maxTextureSize, out textureFormat); 112 | if (maxTextureSize != fitSize){ 113 | Debug.LogWarning("change specific size to " + fitSize + "on " + platform + " for " + imagePath); 114 | importer.SetPlatformTextureSettings(platform, fitSize, textureFormat); 115 | } 116 | } 117 | AssetDatabase.ImportAsset(imagePath, ImportAssetOptions.ForceSynchronousImport); 118 | } 119 | } 120 | 121 | public static void updateImporters(SpineMultiatlas multiatlas, string directory, int pixelsPerUnit, out SpritesByName spriteByName){ 122 | spriteByName = new SpritesByName(); 123 | foreach (SpineAtlas spineAtlas in multiatlas){ 124 | string imagePath = directory + "/" + spineAtlas.imageName; 125 | if (!File.Exists(imagePath)) 126 | throw new AtlasImageNotFoundException("can't find " + spineAtlas.imageName + " image in " + directory + " folder"); 127 | fixTextureSize(imagePath); 128 | Texture2D tex = AssetDatabase.LoadAssetAtPath(imagePath, typeof(Texture2D )) as Texture2D; 129 | Vector2 atlasSize = new Vector2(tex.width, tex.height); 130 | TextureImporter importer = TextureImporter.GetAtPath(imagePath) as TextureImporter; 131 | importer.spritesheet = getSpriteMetadata(spineAtlas, atlasSize); 132 | importer.textureType = TextureImporterType.Sprite; 133 | importer.spriteImportMode = SpriteImportMode.Multiple; 134 | importer.spritePixelsToUnits = pixelsPerUnit; 135 | AssetDatabase.ImportAsset(imagePath, ImportAssetOptions.ForceUpdate); 136 | AssetDatabase.SaveAssets(); 137 | 138 | 139 | foreach(UnityEngine.Object obj in AssetDatabase.LoadAllAssetsAtPath(imagePath)){ 140 | Sprite s = obj as Sprite; 141 | if (s!=null){ 142 | try{ 143 | spriteByName.Add(s.name,s); 144 | } catch (ArgumentException e) { 145 | throw new AtlasImageDuplicateSpriteName("source images has duplicate name "+s.name +"\n"+e); 146 | } 147 | } 148 | } 149 | 150 | foreach(SpineSprite spineSprite in spineAtlas.sprites){ 151 | if (spineSprite.rotate){ 152 | spriteByName.rotatedSprites.Add(spriteByName[spineSprite.name]); 153 | } 154 | } 155 | } 156 | } 157 | 158 | public static SpriteMetaData[] getSpriteMetadata(SpineAtlas spineAtlas, Vector2 atlasImageSize){ 159 | 160 | SpriteMetaData[] result = new SpriteMetaData[spineAtlas.sprites.Count]; 161 | SpineSprite spineSprite; 162 | for (int i = 0; i < result.Length; i++) { 163 | spineSprite = spineAtlas.sprites[i]; 164 | result[i] = new SpriteMetaData(); 165 | result[i].name = spineSprite.name; 166 | result[i].rect = getRectFromSpineSprite(spineSprite, atlasImageSize); 167 | 168 | if (spineSprite.orig != spineSprite.size){ 169 | result[i].alignment = (int) SpriteAlignment.Custom; 170 | result[i].pivot = getPivotFromSpineSprite(spineSprite); 171 | } 172 | 173 | } 174 | return result; 175 | } 176 | 177 | public static Rect getRectFromSpineSprite(SpineSprite sprite, Vector2 atlasImageSize){ 178 | float x,y,width,height; 179 | 180 | x = sprite.xy.x; 181 | width = sprite.size.x; 182 | height = sprite.size.y; 183 | if (sprite.rotate){ 184 | y = atlasImageSize.y - sprite.size.x - sprite.xy.y; 185 | swap2Float(ref width, ref height); 186 | }else { 187 | y = atlasImageSize.y - sprite.size.y - sprite.xy.y; 188 | } 189 | return new Rect(x, y, width, height); 190 | } 191 | 192 | public static Vector2 getPivotFromSpineSprite(SpineSprite sprite){ 193 | float offsetX = sprite.offset.x; 194 | float offsetY = sprite.offset.y; 195 | if (sprite.rotate) 196 | swap2Float(ref offsetX, ref offsetY); 197 | float x = 0.5f + (float)((offsetX + sprite.size.x/2 - sprite.orig.x/2)/ sprite.size.x); 198 | float y = 0.5f + (float)(((sprite.orig.y - offsetY - sprite.size.y/2) - sprite.orig.y / 2)/ sprite.size.y); 199 | if (sprite.rotate) 200 | swap2Float(ref x, ref y); 201 | return new Vector2(x,y); 202 | } 203 | 204 | public static void swap2Float(ref float float1, ref float float2){ 205 | float tmp = float1; 206 | float1 = float2; 207 | float2 = tmp; 208 | } 209 | 210 | public static GameObject buildSceleton( string name, SpineData data, int pixelsPerUnit, float zStep, out Dictionary boneGOByName, out Dictionary slotByName ) { 211 | float ratio = 1.0f / (float)pixelsPerUnit; 212 | boneGOByName = new Dictionary(); 213 | slotByName = new Dictionary(); 214 | GameObject rootGO = new GameObject(name); 215 | foreach(SpineBone bone in data.bones){ 216 | GameObject go = new GameObject(bone.name); 217 | boneGOByName.Add(bone.name, go); 218 | } 219 | 220 | foreach(SpineBone bone in data.bones){ 221 | GameObject go = boneGOByName[bone.name]; 222 | if (bone.parent == null) 223 | go.transform.parent = rootGO.transform; 224 | else 225 | go.transform.parent = boneGOByName[bone.parent].transform; 226 | 227 | Vector3 position = new Vector3((float)bone.x * ratio, (float)bone.y * ratio, 0.0f); 228 | Vector3 scale = new Vector3((float)bone.scaleX, (float)bone.scaleY, 1.0f); 229 | Quaternion rotation = Quaternion.Euler(0, 0, (float)bone.rotation); 230 | go.transform.localPosition = position; 231 | go.transform.localScale = scale; 232 | go.transform.localRotation = rotation; 233 | } 234 | 235 | foreach(SpineSlot spineSlot in data.slots){ 236 | GameObject go = new GameObject(getSlotGOName(spineSlot.name)); 237 | go.transform.parent = boneGOByName[spineSlot.bone].transform; 238 | resetLocalTRS(go); 239 | int drawOrder = data.slotOrder[ spineSlot.name ]; 240 | go.transform.localPosition = new Vector3( 0, 0, (- drawOrder ) * zStep ); 241 | Slot slot = new Slot(); 242 | slot.bone = spineSlot.bone; 243 | slot.name = spineSlot.name; 244 | slot.color = hexStringToColor32(spineSlot.color); 245 | slot.gameObject = go; 246 | slot.defaultAttachmentName = spineSlot.attachment; 247 | slotByName.Add(slot.name, slot); 248 | } 249 | return rootGO; 250 | } 251 | 252 | public static string getSlotGOName(string slotName){ 253 | return SLOT_PREFIX+" ["+slotName+"]"; 254 | } 255 | 256 | public static void resetLocalTRS(GameObject go){ 257 | go.transform.localPosition = Vector3.zero; 258 | go.transform.localRotation = Quaternion.identity; 259 | go.transform.localScale = Vector3.one; 260 | } 261 | 262 | public static void addAllAttahcmentsSlots(SpineData spineData, SpritesByName spriteByName, Dictionary slotByName, int pixelsPerUnit, out List skins, out AttachmentGOByNameBySlot attachmentGOByNameBySlot){ 263 | float ratio = 1.0f / (float) pixelsPerUnit; 264 | skins = new List(); 265 | attachmentGOByNameBySlot= new AttachmentGOByNameBySlot(); 266 | foreach(KeyValuePairkvp in spineData.skins){ 267 | string skinName = kvp.Key; 268 | Skin skin = new Skin(); 269 | skin.name = skinName; 270 | List slotList = new List(); 271 | 272 | bool isDefault = skinName.Equals("default"); 273 | foreach(KeyValuePairkvp2 in spineData.skins[skinName]){ 274 | string slotName = kvp2.Key; 275 | GameObject slotGO = slotByName[slotName].gameObject; 276 | 277 | Slot slot = slotByName[slotName]; 278 | string spritePath = spineData.slotPathByName[ slotName ] + "/"; 279 | 280 | 281 | SkinSlot skinSlot = new SkinSlot(); 282 | skinSlot.name = slotName; 283 | skinSlot.gameObject = slotGO; 284 | List attachmentList = new List(); 285 | foreach(KeyValuePair kvp3 in spineData.skins[skinName][slotName]){ 286 | string attachmenName = kvp3.Key; 287 | SkinSlotAttachment attachment = new SkinSlotAttachment(); 288 | attachment.name = attachmenName; 289 | 290 | SpineSkinAttachment spineAttachment = kvp3.Value; 291 | 292 | // - create skined object or direct GO for default skin 293 | Sprite sprite; 294 | spriteByName.TryGetValue(spineAttachment.name, out sprite); 295 | 296 | GameObject parentGO; 297 | GameObject spriteGO; 298 | string fixedName = attachmenName.Replace("/",SLASH_REPLACEMENT); 299 | if (isDefault){ 300 | parentGO = slotGO; 301 | spriteGO = new GameObject(fixedName); 302 | spritePath += fixedName; 303 | Attachment a = new Attachment(attachmenName, AttachmentType.SINGLE_SPRITE, spriteGO); 304 | slot.addAttachment(a); 305 | } else { 306 | spriteGO = new GameObject(skinName); 307 | Attachment a; 308 | slot.attachmentByName.TryGetValue(attachmenName, out a); 309 | if (a == null){ 310 | GameObject attachmentGO = new GameObject(fixedName); 311 | attachmentGO.transform.parent = slotGO.transform; 312 | resetLocalTRS(attachmentGO); 313 | a = new Attachment(attachmenName, AttachmentType.SKINED_SPRITE, attachmentGO); 314 | slot.addAttachment(a); 315 | } 316 | spritePath += fixedName + "/" + skinName; 317 | parentGO = a.gameObject; 318 | } 319 | 320 | attachment.gameObject = spriteGO; 321 | attachment.ObPath = spritePath; 322 | spriteGO.transform.parent = parentGO.gameObject.transform; 323 | // - 324 | if (spineAttachment.type.Equals("region")){ 325 | SpriteRenderer sr = spriteGO.AddComponent(); 326 | sr.sprite = sprite; 327 | spriteGO.transform.localPosition = getAttachmentPosition(spineAttachment, ratio, 0); 328 | spriteGO.transform.localRotation = getAttachmentRotation(spineAttachment, spriteByName.rotatedSprites.Contains(sprite)); 329 | spriteGO.transform.localScale = getAttachmentScale(spineAttachment); 330 | attachment.sprite = sr; 331 | } else if (spineAttachment.type.Equals("boundingbox")) { 332 | PolygonCollider2D collider = spriteGO.AddComponent(); 333 | resetLocalTRS(spriteGO); 334 | Vector2[] vertices = new Vector2[spineAttachment.vertices.Length/2]; 335 | for (int i = 0; i < spineAttachment.vertices.Length; i+=2) { 336 | float x = (float) spineAttachment.vertices[i ] * ratio; 337 | float y = (float) spineAttachment.vertices[i+1] * ratio; 338 | vertices[i/2] = new Vector2(x,y); 339 | } 340 | collider.points = vertices; 341 | collider.SetPath(0,vertices); 342 | }else { 343 | Debug.LogWarning("Attachment type " + spineAttachment.type + " is not supported yiet FIX MEEE"); 344 | } 345 | attachmentList.Add(attachment); 346 | } 347 | skinSlot.attachments = attachmentList.ToArray(); 348 | slotList.Add(skinSlot); 349 | } 350 | skin.slots = slotList.ToArray(); 351 | skins.Add(skin); 352 | } 353 | } 354 | 355 | 356 | public static SkinController addSkinController(GameObject gameObject, SpineData spineData, List allSkins, Dictionary slotByName){ 357 | SkinController sk = gameObject.AddComponent(); 358 | List skins = new List(); 359 | Skin defaultSkin = null; 360 | foreach(Skin skin in allSkins){ 361 | if (skin.name.Equals("default")){ 362 | defaultSkin = skin; 363 | } else { 364 | skins.Add(skin); 365 | } 366 | } 367 | sk.defaultSkin = defaultSkin; 368 | sk.skins = skins.ToArray(); 369 | 370 | Slot[] slots = new Slot[slotByName.Count]; 371 | slotByName.Values.CopyTo(slots,0); 372 | sk.slots = slots; 373 | return sk; 374 | } 375 | 376 | public static Animator addAnimator(GameObject go){ 377 | Animator result = go.GetComponent(); 378 | if (result == null) 379 | result = go.AddComponent(); 380 | return result; 381 | } 382 | 383 | public static void addAnimation(GameObject rootGO, 384 | string rootDirectory, 385 | SpineData spineData, 386 | Dictionary boneGOByName, 387 | Dictionary slotByName, 388 | AttachmentGOByNameBySlot attachmentGOByNameBySlot, 389 | List skinList, 390 | int pixelsPerUnit, 391 | float zStep, 392 | bool useLegacyAnimation, 393 | bool updateResources) 394 | { 395 | float ratio = 1.0f / (float)pixelsPerUnit; 396 | foreach(KeyValuePair kvp in spineData.animations){ 397 | string animationName = kvp.Key; 398 | string animationFolder = rootDirectory+"/"+ANIMATION_FOLDER; 399 | string assetPath = animationFolder + "/" + animationName+".anim"; 400 | 401 | SpineAnimation spineAnimation = kvp.Value; 402 | AnimationClip animationClip = new AnimationClip(); 403 | bool updateCurve = false; 404 | if (File.Exists(assetPath)){ 405 | AnimationClip oldClip = AssetDatabase.LoadAssetAtPath(assetPath, typeof(AnimationClip)) as AnimationClip; 406 | if (oldClip != null){ 407 | animationClip = oldClip; 408 | animationClip.ClearCurves(); 409 | updateCurve = true; 410 | } 411 | } 412 | animationClip.legacy = useLegacyAnimation; 413 | if (spineAnimation.bones!=null) 414 | addBoneAnimationToClip(animationClip,spineAnimation.bones, spineData, boneGOByName, ratio); 415 | if (spineAnimation.slots!=null) 416 | addSlotAnimationToClip(animationClip, spineAnimation.slots, spineData, skinList, attachmentGOByNameBySlot); 417 | 418 | if ( spineAnimation.events != null ) 419 | AddEvents( animationClip, spineAnimation.events, animationName ); 420 | if (spineAnimation.draworder!=null) 421 | addDrawOrderAnimation( animationClip, spineAnimation.draworder, spineData, zStep, animationName, slotByName ); 422 | 423 | if (updateCurve){ 424 | EditorUtility.SetDirty(animationClip); 425 | AssetDatabase.SaveAssets(); 426 | } else { 427 | animationClip.frameRate = 30; 428 | createFolderIfNoExists(rootDirectory, ANIMATION_FOLDER); 429 | AssetDatabase.CreateAsset(animationClip, assetPath); 430 | AssetDatabase.SaveAssets(); 431 | 432 | if (useLegacyAnimation){ 433 | AddClipToLegacyAnimationComponent(rootGO, animationClip); 434 | } else { 435 | AddClipToAnimatorComponent(rootGO,animationClip); 436 | } 437 | } 438 | 439 | } 440 | } 441 | 442 | static void AddEvents( AnimationClip clip, 443 | List< JsonData > events, 444 | string animName ) 445 | { 446 | List< UnityEngine.AnimationEvent > unityEvents = new List( ); 447 | foreach ( JsonData entry in events ) { 448 | if ( !entry.IsObject ) 449 | Debug.LogError( "JSON data is wrong. Event is not an Object??!!" ); 450 | IDictionary entry_dict = entry as IDictionary; 451 | 452 | UnityEngine.AnimationEvent ev = new UnityEngine.AnimationEvent( ); 453 | 454 | if ( entry_dict.Contains( "name" ) ) 455 | ev.functionName = ( ( string ) entry[ "name" ] ); 456 | else 457 | Debug.LogError( "JSON data is wrong. Missing Name in event data: " + animName ); 458 | 459 | if ( entry_dict.Contains( "time" ) ) 460 | ev.time = getNumberData( entry[ "time" ], animName ); 461 | else 462 | Debug.LogError( "JSON data is wrong. Missing Time in event data: " + animName + " EVENT_NAME: " + ev.functionName ); 463 | 464 | bool ParamAdded = false; 465 | if ( entry_dict.Contains( "int" ) ) { 466 | ev.intParameter = ( int ) entry[ "int" ]; 467 | ParamAdded = true; 468 | } 469 | 470 | if ( entry_dict.Contains( "float" ) ) { 471 | if ( ParamAdded ) 472 | Debug.LogError( "JSON data is wrong. Unity Supports only one event parameter!!!! CLIP NAME: " + animName + " EVENT_NAME: " + entry.ToJson( ) ); 473 | ev.floatParameter = getNumberData( entry[ "float" ], animName ); 474 | ParamAdded = true; 475 | } 476 | 477 | if ( entry_dict.Contains( "string" ) ) { 478 | if ( ParamAdded ) 479 | Debug.LogError( "JSON data is wrong. Unity Supports only one event parameter!!!! CLIP NAME: " + animName + " EVENT_NAME: " + entry.ToJson( ) ); 480 | ev.stringParameter = ( string ) entry[ "string" ]; 481 | } 482 | 483 | ev.messageOptions = SendMessageOptions.RequireReceiver; 484 | 485 | unityEvents.Add( ev ); 486 | } 487 | 488 | AnimationUtility.SetAnimationEvents( clip, unityEvents.ToArray( ) ); 489 | } 490 | 491 | static float getNumberData( JsonData data, string animName ) { 492 | 493 | if ( data.IsDouble ) 494 | return ( float )( ( double )data ); 495 | 496 | if ( data.IsInt ) 497 | return ( float )( ( int )data ); 498 | 499 | Debug.LogError( "JSON data is wrong. Unrecognizable number format!!!! CLIP NAME: " + animName + " JsonData: " + data.ToJson( ) ); 500 | 501 | return 0.0f; 502 | } 503 | 504 | static void AddClipToLegacyAnimationComponent(GameObject rootGO, AnimationClip animationClip){ 505 | Animation animation = rootGO.GetComponent(); 506 | if (animation == null) 507 | animation = rootGO.AddComponent(); 508 | animation.AddClip(animationClip, animationClip.name); 509 | } 510 | 511 | static void createFolderIfNoExists(string root, string folderName){ 512 | string path = root+"/"+folderName; 513 | if (!Directory.Exists(path)) 514 | Directory.CreateDirectory(path); 515 | } 516 | 517 | 518 | public static string getFirstAttachmentName(SpineSlotAnimation spineSlotAnimation){ 519 | for (int i = 0; i < spineSlotAnimation.attachment.Count; i++) { 520 | if (!string.IsNullOrEmpty( spineSlotAnimation.attachment[i].name)) 521 | return spineSlotAnimation.attachment[i].name; 522 | } 523 | return ""; 524 | } 525 | 526 | public static void addDrawOrderAnimation( AnimationClip clip, 527 | List orderAnimation, 528 | SpineData spineData, 529 | float zStep, 530 | string animName, 531 | Dictionary slotNameByName ) 532 | { 533 | string[] BaseSlotOrder = new string[ spineData.slotOrder.Count ]; 534 | 535 | Dictionary< string, AnimationCurve > Curvs = new Dictionary( ); 536 | 537 | foreach ( KeyValuePair p in spineData.slotOrder ) { 538 | BaseSlotOrder[ p.Value ] = p.Key; 539 | AnimationCurve Curv = new AnimationCurve(); 540 | Keyframe keyFrame = new Keyframe( 0.0f, ( - p.Value ) * zStep ); 541 | Curv.AddKey( keyFrame ); 542 | Curvs[ p.Key ] = Curv; 543 | } 544 | 545 | foreach ( SpineDrawOrderAnimation orderAnim in orderAnimation ) { 546 | string[] NewSlotOrder = null; 547 | if ( orderAnim.offsets != null ) { 548 | NewSlotOrder = new string[ BaseSlotOrder.Length ]; 549 | string[] BaseOrder_Copy = BaseSlotOrder.Clone( ) as string[]; 550 | 551 | for ( int i = 0; i != orderAnim.offsets.Length; i++ ) { 552 | SpineDrawOrderAnimationSlot slot = orderAnim.offsets[ i ]; 553 | int newIdx = spineData.slotOrder[ slot.slot ] + slot.offset; 554 | NewSlotOrder[ newIdx ] = slot.slot; 555 | int base_idx = Array.IndexOf( BaseOrder_Copy, slot.slot ); 556 | BaseOrder_Copy[ base_idx ] = null; 557 | } 558 | 559 | int pos = 0; 560 | for ( int i = 0; i != NewSlotOrder.Length; i++ ) { 561 | if ( NewSlotOrder[ i ] == null ) { 562 | bool found = false; 563 | for ( ; pos != BaseOrder_Copy.Length; ) { 564 | if ( BaseOrder_Copy[ pos ] != null ) { 565 | found = true; 566 | NewSlotOrder[ i ] = BaseOrder_Copy[ pos ]; 567 | pos++; 568 | break; 569 | } else pos++; 570 | } 571 | 572 | if ( !found ) Debug.LogError( "Can't create new draw order" ); 573 | } 574 | } 575 | } else NewSlotOrder = BaseSlotOrder; 576 | 577 | for ( int j = 0; j != NewSlotOrder.Length; j++ ) { 578 | float t = ( float )orderAnim.time; 579 | float val = ( - j ) * zStep; 580 | AnimationCurve curv = Curvs[ NewSlotOrder[ j ] ]; 581 | float priv_val = curv.Evaluate( t ); 582 | if ( t > 0.0f ) { 583 | Keyframe keyFrameY_help = new Keyframe( t - 0.00001f, priv_val ); 584 | Keyframe keyFrameY = new Keyframe( t, val ); 585 | curv.AddKey( keyFrameY_help ); 586 | curv.AddKey( keyFrameY ); 587 | } else { 588 | Keyframe keyFrameY = new Keyframe( t, val ); 589 | curv.AddKey( keyFrameY ); 590 | } 591 | } 592 | } 593 | 594 | for ( int i = 0; i != BaseSlotOrder.Length; i++ ) { 595 | string slotpath = spineData.slotPathByName[ BaseSlotOrder[ i ] ]; 596 | AnimationCurve curv = Curvs[ BaseSlotOrder[ i ] ]; 597 | AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( slotpath, typeof( Transform ), "m_LocalPosition.z" ), curv ); 598 | } 599 | } 600 | 601 | public static void addSlotAnimationToClip(AnimationClip clip, 602 | Dictionary slotsAnimation, 603 | SpineData spineData, 604 | List skinList, 605 | AttachmentGOByNameBySlot attachmentGOByNameBySlot) 606 | { 607 | foreach(KeyValuePair kvp in slotsAnimation){ 608 | string slotName = kvp.Key; 609 | string defaultAttachment = spineData.slotDefaultAttachments[slotName]; 610 | if (string.IsNullOrEmpty(defaultAttachment)) 611 | continue; 612 | SpineSlotAnimation slotAnimation = kvp.Value; 613 | if (slotAnimation.attachment != null && slotAnimation.attachment.Count > 0){ 614 | Dictionary curveByName = new Dictionary(); 615 | 616 | 617 | for (int i = 0; i < slotAnimation.attachment.Count; i++) { 618 | bool nullAttachment = false; 619 | SpineSlotAttachmentAnimation anim = slotAnimation.attachment[i]; 620 | if (string.IsNullOrEmpty( anim.name)){ 621 | anim.name=getFirstAttachmentName(slotAnimation); 622 | nullAttachment = true; 623 | } 624 | 625 | if (anim.name.Equals("")) 626 | continue; 627 | AnimationCurve enableCurve; 628 | if (curveByName.ContainsKey(anim.name)){ 629 | enableCurve = curveByName[anim.name]; 630 | } else { 631 | enableCurve = new AnimationCurve(); 632 | if (anim.time > 0.0f) 633 | enableCurve.AddKey(KeyframeUtil.GetNew(0, 0.0f, TangentMode.Stepped)); 634 | 635 | curveByName.Add(anim.name, enableCurve); 636 | 637 | if (i==0 && !anim.name.Equals(defaultAttachment)){ 638 | AnimationCurve defSlotCurve = new AnimationCurve(); 639 | curveByName.Add(defaultAttachment, defSlotCurve); 640 | 641 | if (anim.time !=0.0f){ 642 | defSlotCurve.AddKey(KeyframeUtil.GetNew(0, nullAttachment ? 0 : 1, TangentMode.Stepped)); 643 | defSlotCurve.AddKey(KeyframeUtil.GetNew((float)anim.time, 0, TangentMode.Stepped)); 644 | } else { 645 | defSlotCurve.AddKey(KeyframeUtil.GetNew(0, 0, TangentMode.Stepped)); 646 | } 647 | 648 | } 649 | } 650 | 651 | enableCurve.AddKey(KeyframeUtil.GetNew((float)anim.time, nullAttachment ? 0 : 1, TangentMode.Stepped)); 652 | if (i< (slotAnimation.attachment.Count - 1)){ 653 | SpineSlotAttachmentAnimation nextAnim = slotAnimation.attachment[i+1]; 654 | bool nullNextAttachment =false; 655 | if (string.IsNullOrEmpty( nextAnim.name)){ 656 | nextAnim.name=getFirstAttachmentName(slotAnimation); 657 | nullNextAttachment = true; 658 | } 659 | 660 | if (!nextAnim.name.Equals(anim.name) || nullNextAttachment) 661 | enableCurve.AddKey(KeyframeUtil.GetNew((float)nextAnim.time, 0, TangentMode.Stepped)); 662 | 663 | } 664 | } 665 | foreach(KeyValuePair kvp2 in curveByName){ 666 | string attachmentName = kvp2.Key; 667 | AnimationCurve animationCurve = kvp2.Value; 668 | string attachmentPath = spineData.slotPathByName[slotName] + "/" + attachmentName.Replace("/",SLASH_REPLACEMENT); 669 | clip.SetCurve(attachmentPath, typeof(GameObject),"m_IsActive", animationCurve); 670 | } 671 | 672 | } 673 | 674 | if (slotAnimation.color != null && slotAnimation.color.Count >0){ 675 | AnimationCurve Curv_R = new AnimationCurve( ); 676 | AnimationCurve Curv_G = new AnimationCurve( ); 677 | AnimationCurve Curv_B = new AnimationCurve( ); 678 | AnimationCurve Curv_A = new AnimationCurve( ); 679 | Keyframe startKeyFrame = new Keyframe( 0.0f, 1.0f ); 680 | Curv_R.AddKey( startKeyFrame ); 681 | Curv_G.AddKey( startKeyFrame ); 682 | Curv_B.AddKey( startKeyFrame ); 683 | Curv_A.AddKey( startKeyFrame ); 684 | 685 | JsonData[] curveData = new JsonData[ slotAnimation.color.Count ]; 686 | for( int i = 0 ; i != slotAnimation.color.Count ;i++ ) { 687 | SpineSlotColorAnimation color = slotAnimation.color[ i ]; 688 | uint col = Convert.ToUInt32( color.color, 16 ); 689 | uint r = ( col ) >> 24; 690 | uint g = (col & 0xff0000) >> 16; 691 | uint b = (col & 0xff00) >> 8; 692 | uint a = (col & 0xff); 693 | float t = ( (float) (color.time) ); 694 | Keyframe keyFrame_R = new Keyframe( t, r / 255.0f ); 695 | Keyframe keyFrame_G = new Keyframe( t, g / 255.0f ); 696 | Keyframe keyFrame_B = new Keyframe( t, b / 255.0f ); 697 | Keyframe keyFrame_A = new Keyframe( t, a / 255.0f ); 698 | Curv_R.AddKey( keyFrame_R ); 699 | Curv_G.AddKey( keyFrame_G ); 700 | Curv_B.AddKey( keyFrame_B ); 701 | Curv_A.AddKey( keyFrame_A ); 702 | curveData[ i ] = color.curve; 703 | } 704 | 705 | setTangents( Curv_R, curveData ); 706 | setTangents( Curv_G, curveData ); 707 | setTangents( Curv_B, curveData ); 708 | setTangents( Curv_A, curveData ); 709 | 710 | for ( int i = 0; i != skinList.Count; i++ ) { 711 | if ( skinList[ i ].containsSlot( slotName ) ) { 712 | SkinSlot skinSlot = skinList[ i ][ slotName ]; 713 | for ( int j = 0; j != skinSlot.attachments.Length; j++ ) { 714 | SpriteRenderer sprite = skinSlot.attachments[ j ].sprite; 715 | if ( sprite != null ) { 716 | string spritePath = skinSlot.attachments[ j ].ObPath; 717 | AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( spritePath, typeof( SpriteRenderer ), "m_Color.r" ), Curv_R ); 718 | AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( spritePath, typeof( SpriteRenderer ), "m_Color.g" ), Curv_G ); 719 | AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( spritePath, typeof( SpriteRenderer ), "m_Color.b" ), Curv_B ); 720 | AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( spritePath, typeof( SpriteRenderer ), "m_Color.a" ), Curv_A ); 721 | } 722 | } 723 | } 724 | } 725 | 726 | Debug.LogWarning("slot color animation is not supported yet"); 727 | } 728 | } 729 | } 730 | 731 | public static void setTangents(AnimationCurve curve, JsonData[] curveData){ 732 | bool showWarning = true; 733 | for (int i = 0; i < curve.keys.Length; i++) { 734 | int nextI = i + 1; 735 | if (nextI < curve.keys.Length){ 736 | if (curveData[i] == null ){ 737 | //Linear 738 | setLinearInterval(curve, i, nextI); 739 | } else { 740 | if (curveData[i].IsArray){ 741 | if (showWarning){ 742 | Debug.LogWarning("be carefull, smooth bezier animation is in beta state, check result animation manually"); 743 | showWarning = false; 744 | } 745 | setCustomTangents(curve, i, nextI, curveData[i]); 746 | } else { 747 | if (((string)curveData[i]).Equals("stepped")){ 748 | setSteppedInterval(curve, i, nextI); 749 | } else { 750 | Debug.LogError("unsupported animation type "+(string)curveData[i]); 751 | } 752 | } 753 | } 754 | } 755 | } 756 | } 757 | 758 | static float parseFloat(JsonData jsonData){ 759 | if (jsonData.IsDouble) 760 | return (float)(double)jsonData; 761 | else if (jsonData.IsInt) 762 | return (float)(int)jsonData; 763 | Debug.LogError("can't parse to double ["+jsonData+"]"); 764 | return 0.0f; 765 | } 766 | 767 | 768 | // p0, p3 - start, end points 769 | // p1, p2 - conrol points 770 | // t - value on x [0,1] 771 | public static Vector2 getBezierPoint(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float t){ 772 | float y = (1 - t) * (1 - t) * (1 - t) * p0.y + 773 | 3 * t * (1 - t) * (1 - t) * p1.y + 774 | 3 * t * t * (1 - t) * p2.y + 775 | t * t * t * p3.y; 776 | return new Vector2(p0.x + t * (p3.x - p0.x) ,y); 777 | } 778 | 779 | // a - start point 780 | // b - on t= 1/3 781 | // c - on t = 2/3 782 | // d - end point 783 | // c1,c2 control points of bezier. 784 | public static void calcControlPoints(Vector2 a, Vector2 b, Vector2 c, Vector2 d, out Vector2 c1, out Vector2 c2){ 785 | c1 = (-5 * a + 18 * b - 9 * c + 2 * d)/6; 786 | c2 = ( 2 * a - 9 * b + 18 * c - 5 * d)/6; 787 | } 788 | 789 | public static void setCustomTangents(AnimationCurve curve, int i, int nextI, JsonData tangentArray){ 790 | float diffValue = curve[nextI].value - curve[i].value; 791 | float diffTime = curve[nextI].time - curve[i].time; 792 | if (diffValue == 0) 793 | return; 794 | 795 | 796 | 797 | float cx1 = parseFloat(tangentArray[0]); 798 | float cy1 = parseFloat(tangentArray[1]); 799 | float cx2 = parseFloat(tangentArray[2]); 800 | float cy2 = parseFloat(tangentArray[3]); 801 | Vector2 p0 = new Vector2(0 , curve[i].value); 802 | Vector2 p3 = new Vector2(diffTime , curve[nextI].value); 803 | Vector2 cOrig1 = new Vector2(diffTime * cx1, curve[i].value); 804 | cOrig1.y += diffValue > 0 ? diffValue * cy1 : -1.0f * Mathf.Abs(diffValue * cy1); 805 | 806 | Vector2 cOrig2 = new Vector2(diffTime * cx2, curve[i].value); 807 | cOrig2.y += diffValue > 0 ? diffValue * cy2 : -1.0f * Mathf.Abs(diffValue * cy2); 808 | 809 | Vector2 p1 = getBezierPoint(p0, cOrig1, cOrig2, p3, 1.0f / 3.0f); 810 | Vector2 p2 = getBezierPoint(p0, cOrig1, cOrig2, p3, 2.0f / 3.0f); 811 | 812 | 813 | Vector2 c1tg, c2tg, c1, c2; 814 | calcControlPoints(p0,p1,p2,p3, out c1, out c2); 815 | 816 | c1tg = c1 - p0; 817 | c2tg = c2 - p3; 818 | 819 | float outTangent = c1tg.y / c1tg.x; 820 | float inTangent = c2tg.y / c2tg.x; 821 | 822 | 823 | object thisKeyframeBoxed = curve[i]; 824 | object nextKeyframeBoxed = curve[nextI]; 825 | 826 | 827 | if (!KeyframeUtil.isKeyBroken(thisKeyframeBoxed)) 828 | KeyframeUtil.SetKeyBroken(thisKeyframeBoxed, true); 829 | KeyframeUtil.SetKeyTangentMode(thisKeyframeBoxed, 1, TangentMode.Editable); 830 | 831 | if (!KeyframeUtil.isKeyBroken(nextKeyframeBoxed)) 832 | KeyframeUtil.SetKeyBroken(nextKeyframeBoxed, true); 833 | KeyframeUtil.SetKeyTangentMode(nextKeyframeBoxed, 0, TangentMode.Editable); 834 | 835 | Keyframe thisKeyframe = (Keyframe)thisKeyframeBoxed; 836 | Keyframe nextKeyframe = (Keyframe)nextKeyframeBoxed; 837 | 838 | thisKeyframe.outTangent = outTangent; 839 | nextKeyframe.inTangent = inTangent; 840 | 841 | curve.MoveKey(i, thisKeyframe); 842 | curve.MoveKey(nextI, nextKeyframe); 843 | 844 | //* test method 845 | bool ok = true; 846 | float startTime = thisKeyframe.time; 847 | 848 | float epsilon = 0.001f; 849 | for (float j=0; j < 25f; j++) { 850 | float t = j/25.0f; 851 | Vector2 t1 = getBezierPoint(p0, cOrig1, cOrig2, p3, t); 852 | Vector2 t2 = getBezierPoint(p0, c1, c2, p3, t); 853 | float curveValue = curve.Evaluate(startTime + diffTime * t); 854 | if (!NearlyEqual(t1.y, t2.y, epsilon) 855 | || !NearlyEqual(t2.y, curveValue, epsilon)){ 856 | Debug.LogError("time = "+ t + " t1 = ["+t1.y.ToString("N8")+"] t2 = ["+t2.y.ToString("N8")+"] curve = ["+curveValue.ToString("N8")+"]"); 857 | ok = false; 858 | } 859 | } 860 | if (!ok) 861 | Debug.LogWarning("something wrong with bezier points"); 862 | //*/ 863 | 864 | } 865 | 866 | public static bool NearlyEqual(float a, float b, float epsilon) 867 | { 868 | float absA = Math.Abs(a); 869 | float absB = Math.Abs(b); 870 | float diff = Math.Abs(a - b); 871 | 872 | if (a == b) 873 | { // shortcut, handles infinities 874 | return true; 875 | } 876 | else if (a == 0 || b == 0 || diff < Double.MinValue) 877 | { 878 | // a or b is zero or both are extremely close to it 879 | // relative error is less meaningful here 880 | return diff < (epsilon * Double.MinValue); 881 | } 882 | else 883 | { // use relative error 884 | return diff / (absA + absB) < epsilon; 885 | } 886 | } 887 | 888 | 889 | public static void setSteppedInterval(AnimationCurve curve, int i, int nextI){ 890 | 891 | if (curve.keys[i].value == curve.keys[nextI].value){ 892 | return; 893 | } 894 | 895 | object thisKeyframeBoxed = curve[i]; 896 | object nextKeyframeBoxed = curve[nextI]; 897 | 898 | if (!KeyframeUtil.isKeyBroken(thisKeyframeBoxed)) 899 | KeyframeUtil.SetKeyBroken(thisKeyframeBoxed, true); 900 | if (!KeyframeUtil.isKeyBroken(nextKeyframeBoxed)) 901 | KeyframeUtil.SetKeyBroken(nextKeyframeBoxed, true); 902 | 903 | KeyframeUtil.SetKeyTangentMode(thisKeyframeBoxed, 1, TangentMode.Stepped); 904 | KeyframeUtil.SetKeyTangentMode(nextKeyframeBoxed, 0, TangentMode.Stepped); 905 | 906 | Keyframe thisKeyframe = (Keyframe)thisKeyframeBoxed; 907 | Keyframe nextKeyframe = (Keyframe)nextKeyframeBoxed; 908 | thisKeyframe.outTangent = float.PositiveInfinity; 909 | nextKeyframe.inTangent = float.PositiveInfinity; 910 | curve.MoveKey(i, thisKeyframe); 911 | curve.MoveKey(nextI, nextKeyframe); 912 | } 913 | 914 | 915 | public static void setLinearInterval(AnimationCurve curve, int i, int nextI){ 916 | Keyframe thisKeyframe = curve[i]; 917 | Keyframe nextKeyframe = curve[nextI]; 918 | thisKeyframe.outTangent = CurveExtension.CalculateLinearTangent(curve, i, nextI); 919 | nextKeyframe.inTangent = CurveExtension.CalculateLinearTangent(curve, nextI, i); 920 | 921 | KeyframeUtil.SetKeyBroken((object)thisKeyframe, true); 922 | KeyframeUtil.SetKeyBroken((object)nextKeyframe, true); 923 | 924 | KeyframeUtil.SetKeyTangentMode((object)thisKeyframe, 1, TangentMode.Linear); 925 | KeyframeUtil.SetKeyTangentMode((object)nextKeyframe, 0, TangentMode.Linear); 926 | 927 | 928 | curve.MoveKey(i, thisKeyframe); 929 | curve.MoveKey(nextI, nextKeyframe); 930 | } 931 | 932 | 933 | public static void addBoneAnimationToClip(AnimationClip clip, Dictionary bonesAnimation, 934 | SpineData spineData, Dictionary boneGOByName, float ratio){ 935 | foreach(KeyValuePair kvp in bonesAnimation){ 936 | string boneName = kvp.Key; 937 | GameObject boneGO = boneGOByName[boneName]; 938 | SpineBoneAnimation boneAnimation = kvp.Value; 939 | string bonePath = spineData.bonePathByName[boneName]; 940 | if (boneAnimation.translate != null && boneAnimation.translate.Count > 0){ 941 | AnimationCurve curveX = new AnimationCurve(); 942 | AnimationCurve curveY = new AnimationCurve(); 943 | JsonData[] curveData = new JsonData[boneAnimation.translate.Count]; 944 | for (int i = 0; i < boneAnimation.translate.Count; i++) { 945 | Keyframe keyFrameX = new Keyframe((float)boneAnimation.translate[i].time, boneGO.transform.localPosition.x + (float)boneAnimation.translate[i].x * ratio); 946 | Keyframe keyFrameY = new Keyframe((float)boneAnimation.translate[i].time, boneGO.transform.localPosition.y + (float)boneAnimation.translate[i].y * ratio); 947 | curveX.AddKey(keyFrameX); 948 | curveY.AddKey(keyFrameY); 949 | curveData[i] = boneAnimation.translate[i].curve; 950 | } 951 | 952 | setTangents(curveX, curveData); 953 | setTangents(curveY, curveData); 954 | AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(bonePath,typeof(Transform),"m_LocalPosition.x") ,curveX); 955 | AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(bonePath,typeof(Transform),"m_LocalPosition.y") ,curveY); 956 | 957 | 958 | } 959 | 960 | if (boneAnimation.rotate != null && boneAnimation.rotate.Count > 0){ 961 | AnimationCurve localRotationX = new AnimationCurve(); 962 | AnimationCurve localRotationY = new AnimationCurve(); 963 | AnimationCurve localRotationZ = new AnimationCurve(); 964 | AnimationCurve localRotationW = new AnimationCurve(); 965 | 966 | JsonData[] curveData = new JsonData[boneAnimation.rotate.Count]; 967 | Quaternion baseRotation = Quaternion.identity; 968 | for (int i = 0; i < boneAnimation.rotate.Count; i++) { 969 | float origAngle = (float)boneAnimation.rotate[i].angle; 970 | if (origAngle > 0) 971 | origAngle = origAngle > 180 ? origAngle - 360 : origAngle; 972 | else 973 | origAngle = origAngle < -180 ? origAngle + 360 : origAngle; 974 | 975 | float newZ = boneGO.transform.localRotation.eulerAngles.z + origAngle; 976 | 977 | Quaternion angle = Quaternion.Euler(0,0,newZ); 978 | float time = (float)boneAnimation.rotate[i].time; 979 | 980 | curveData[i] = boneAnimation.rotate[i].curve; 981 | 982 | localRotationX.AddKey(new Keyframe(time, angle.x)); 983 | localRotationY.AddKey(new Keyframe(time, angle.y)); 984 | localRotationZ.AddKey(new Keyframe(time, angle.z)); 985 | localRotationW.AddKey(new Keyframe(time, angle.w)); 986 | 987 | } 988 | 989 | fixAngleCurve (localRotationX , curveData, baseRotation.x); 990 | fixAngleCurve (localRotationY , curveData, baseRotation.y); 991 | fixAngleCurve (localRotationZ , curveData, baseRotation.z); 992 | fixAngleCurve (localRotationW , curveData, baseRotation.w); 993 | 994 | AnimationUtility.SetEditorCurve(clip,EditorCurveBinding.FloatCurve(bonePath,typeof(Transform),"m_LocalRotation.x"), localRotationX); 995 | AnimationUtility.SetEditorCurve(clip,EditorCurveBinding.FloatCurve(bonePath,typeof(Transform),"m_LocalRotation.y"), localRotationY); 996 | AnimationUtility.SetEditorCurve(clip,EditorCurveBinding.FloatCurve(bonePath,typeof(Transform),"m_LocalRotation.z"), localRotationZ); 997 | AnimationUtility.SetEditorCurve(clip,EditorCurveBinding.FloatCurve(bonePath,typeof(Transform),"m_LocalRotation.w"), localRotationW); 998 | 999 | } 1000 | 1001 | if (boneAnimation.scale != null && boneAnimation.scale.Count > 0){ 1002 | AnimationCurve scaleX = new AnimationCurve(); 1003 | AnimationCurve scaleY = new AnimationCurve(); 1004 | AnimationCurve scaleZ = new AnimationCurve(); 1005 | JsonData[] curveData = new JsonData[boneAnimation.scale.Count]; 1006 | for (int i = 0; i < boneAnimation.scale.Count; i++) { 1007 | Keyframe keyFrameX = new Keyframe((float)boneAnimation.scale[i].time, boneGO.transform.localScale.x * (float)boneAnimation.scale[i].x); 1008 | Keyframe keyFrameY = new Keyframe((float)boneAnimation.scale[i].time, boneGO.transform.localScale.y * (float)boneAnimation.scale[i].y); 1009 | Keyframe keyFrameZ = new Keyframe((float)boneAnimation.scale[i].time, 1); 1010 | curveData[i] = boneAnimation.scale[i].curve; 1011 | scaleX.AddKey(keyFrameX); 1012 | scaleY.AddKey(keyFrameY); 1013 | scaleZ.AddKey(keyFrameZ); 1014 | } 1015 | 1016 | setTangents(scaleX,curveData); 1017 | setTangents(scaleY,curveData); 1018 | 1019 | clip.SetCurve(bonePath, typeof(Transform),"localScale.x",scaleX); 1020 | clip.SetCurve(bonePath, typeof(Transform),"localScale.y",scaleY); 1021 | clip.SetCurve(bonePath, typeof(Transform),"localScale.z",scaleZ); 1022 | } 1023 | 1024 | } 1025 | } 1026 | 1027 | 1028 | 1029 | static void fixAngleCurve(AnimationCurve animationCurve, JsonData[] curveData, float defSingleStepValue){ 1030 | fixSingleStep(animationCurve, defSingleStepValue); 1031 | fixAngles (animationCurve, curveData); 1032 | setTangents (animationCurve, curveData); 1033 | } 1034 | 1035 | static void fixSingleStep (AnimationCurve animationCurve, float defSingleStepValue) 1036 | { 1037 | if (animationCurve.keys.Length == 1 && animationCurve.keys[0].time != 0.0f){ 1038 | Keyframe key = animationCurve.keys[0]; 1039 | key.time = 0.0f; 1040 | key.value = defSingleStepValue; 1041 | animationCurve.AddKey(key); 1042 | } 1043 | } 1044 | 1045 | static void fixAngles(AnimationCurve curve, JsonData[] curveData){ 1046 | if (curve.keys.Length <3) 1047 | return; 1048 | float currValue, previousValue; 1049 | for (int previousI=0, i = 1; i < curve.keys.Length; previousI= i++) { 1050 | if (curveData[previousI] != null && curveData[previousI].IsString && ((string)curveData[previousI]).Equals("stepped")) 1051 | continue; 1052 | 1053 | currValue = curve.keys[i].value; 1054 | previousValue = curve.keys[previousI].value; 1055 | 1056 | while ((currValue - previousValue) > 180 ){ 1057 | currValue -= 360; 1058 | } 1059 | 1060 | while ((currValue - previousValue) < -180){ 1061 | currValue += 360; 1062 | } 1063 | if (curve.keys[i].value != currValue){ 1064 | curve.MoveKey(i, new Keyframe(curve.keys[i].time , currValue)); 1065 | } 1066 | } 1067 | } 1068 | 1069 | 1070 | public static AnimationClip AddClipToAnimatorComponent(GameObject animatedObject, AnimationClip newClip) 1071 | { 1072 | Animator animator = animatedObject.GetComponent(); 1073 | if ( animator == null) 1074 | animator = animatedObject.AddComponent(); 1075 | 1076 | UnityEditor.Animations.AnimatorController animatorController = UnityInternalMethods.GetEffectiveAnimatorController(animator); 1077 | if (animatorController == null) 1078 | { 1079 | string path = Path.GetDirectoryName( AssetDatabase.GetAssetPath(newClip)) +"/"+animatedObject.name+".controller"; 1080 | 1081 | UnityEditor.Animations.AnimatorController controllerForClip = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPathWithClip(path, newClip); 1082 | UnityEditor.Animations.AnimatorController.SetAnimatorController(animator, controllerForClip); 1083 | if (controllerForClip != null) 1084 | return newClip; 1085 | else 1086 | return null; 1087 | } 1088 | else 1089 | { 1090 | animatorController.AddMotion((Motion)newClip); 1091 | return newClip; 1092 | } 1093 | } 1094 | 1095 | 1096 | public static Quaternion getAttachmentRotation(SpineSkinAttachment spineSkinAttachment, bool rotated = false){ 1097 | if (rotated) 1098 | return Quaternion.Euler(0.0f, 0.0f, (float)spineSkinAttachment.rotation - 90.0f); 1099 | else 1100 | return Quaternion.Euler(0.0f, 0.0f, (float)spineSkinAttachment.rotation); 1101 | } 1102 | 1103 | public static Vector3 getAttachmentPosition(SpineSkinAttachment spineSkinAttachment, float ratio, float z){ 1104 | return new Vector3((float)spineSkinAttachment.x * ratio, (float)spineSkinAttachment.y * ratio, z); 1105 | } 1106 | 1107 | public static Vector3 getAttachmentScale(SpineSkinAttachment spineSkinAttachment){ 1108 | return new Vector3((float)spineSkinAttachment.scaleX, (float)spineSkinAttachment.scaleY, 1.0f); 1109 | } 1110 | 1111 | public static Color32? hexStringToColor32(string hex){ 1112 | if (hex == null) 1113 | return null; 1114 | int rgba = int.Parse(hex, System.Globalization.NumberStyles.HexNumber); 1115 | return new Color32((byte)((rgba & 0xff000000)>> 0x18), 1116 | (byte)((rgba & 0xff0000)>> 0x10), 1117 | (byte)((rgba & 0xff00) >> 8), 1118 | (byte)(rgba & 0xff)); 1119 | } 1120 | } 1121 | } 1122 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/Scripts/Editor/Util/SpineUtil.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 703d4339832dc486e88c98daab00df9f 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b695b0c84170441b88c31cc12d9692cf 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/AttachmentGOByName.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | namespace UnitySpineImporter{ 5 | public class AttachmentGOByName : Dictionary{ 6 | 7 | } 8 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/AttachmentGOByName.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d32362277d8f74cbf8c6f926245b75cf 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/AttachmentGOByNameBySlot.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | namespace UnitySpineImporter{ 5 | public class AttachmentGOByNameBySlot : Dictionary { 6 | 7 | public GameObject tryGetValue(string slotName, string attachmentName ){ 8 | if (this.ContainsKey(slotName) && this[slotName].ContainsKey(attachmentName)) 9 | return this[slotName][attachmentName]; 10 | else 11 | return null; 12 | } 13 | 14 | public void add(string slotName, string attachmentName, GameObject attachmentGO){ 15 | if (this.ContainsKey(slotName)){ 16 | this[slotName].Add(attachmentName, attachmentGO); 17 | } else { 18 | AttachmentGOByName aGOByName = new AttachmentGOByName(); 19 | aGOByName.Add(attachmentName, attachmentGO); 20 | this.Add(slotName,aGOByName); 21 | } 22 | 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/AttachmentGOByNameBySlot.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 071812b6dfcc44ae28cda16712b0ceef 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8576837650f064d9199f7c33374216aa 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Editor/SkinControllerEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using UnityEditor; 4 | using System.Collections.Generic; 5 | 6 | namespace UnitySpineImporter{ 7 | [CustomEditor(typeof(SkinController))] 8 | public class SkinControllerEditor : Editor { 9 | 10 | public override void OnInspectorGUI () 11 | { 12 | DrawDefaultInspector(); 13 | SkinController sk = (SkinController)target; 14 | 15 | if(sk.skins.Length > 0 ){ 16 | List names = new List(); 17 | foreach(Skin skin in sk.skins) 18 | names.Add(skin.name); 19 | 20 | int newId = EditorGUILayout.Popup(sk.activeSkinId, names.ToArray()); 21 | if (newId != sk.activeSkinId){ 22 | sk.setSkin (newId); 23 | EditorUtility.SetDirty(target); 24 | } 25 | } 26 | } 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Editor/SkinControllerEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba0e87823eec84813a7a8d8d1475002e 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Editor/SlotPropDrawer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | 5 | namespace UnitySpineImporter{ 6 | [CustomPropertyDrawer(typeof(SkinSlot))] 7 | public class SlotPropDrawer : PropertyDrawer { 8 | 9 | public override float GetPropertyHeight (SerializedProperty property, GUIContent label){ 10 | int childCount = property.FindPropertyRelative("attachments").arraySize; 11 | if (property.isExpanded) 12 | return EditorGUIUtility.singleLineHeight * (childCount+1); 13 | else 14 | return EditorGUIUtility.singleLineHeight; 15 | } 16 | 17 | public override void OnGUI (Rect position, SerializedProperty property, GUIContent label){ 18 | float baseHeight = EditorGUIUtility.singleLineHeight; 19 | float fullWidth = position.width; 20 | float labelWidth = EditorGUIUtility.labelWidth; 21 | float fieldWidth = fullWidth - labelWidth; 22 | position.height = baseHeight; 23 | 24 | string slotName = property.FindPropertyRelative("name").stringValue; 25 | GameObject slotGO = (GameObject)property.FindPropertyRelative("gameObject").objectReferenceValue; 26 | position.width = labelWidth; 27 | property.isExpanded = EditorGUI.Foldout(position,property.isExpanded, new GUIContent(slotName)); 28 | position.x += labelWidth; 29 | position.width = fieldWidth; 30 | EditorGUI.ObjectField(position, slotGO ,typeof(GameObject), true); 31 | 32 | position.x -= labelWidth; 33 | position.width = fullWidth; 34 | if (!property.isExpanded) 35 | return; 36 | 37 | EditorGUI.indentLevel++; 38 | foreach (SerializedProperty attachment in property.FindPropertyRelative("attachments")){ 39 | position.y+=baseHeight; 40 | GameObject attachmentGO = attachment.FindPropertyRelative("gameObject").objectReferenceValue as GameObject; 41 | bool newValue = EditorGUI.Toggle(position, attachmentGO.name, attachmentGO.activeSelf, EditorStyles.radioButton); 42 | if (newValue!= attachmentGO.activeSelf){ 43 | foreach(SerializedProperty resetAttachment in property.FindPropertyRelative("attachments")){ 44 | (resetAttachment.FindPropertyRelative("gameObject").objectReferenceValue as GameObject).SetActive(false); 45 | } 46 | attachmentGO.SetActive(newValue); 47 | } 48 | } 49 | EditorGUI.indentLevel--; 50 | 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Editor/SlotPropDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bfba5a67de3534477a302661aa341ae0 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Skin.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9adee7508e42d4a8ba8d05be2e2e55d5 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Skin/Skin.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using System; 4 | 5 | namespace UnitySpineImporter{ 6 | [Serializable] 7 | public class Skin { 8 | public string name; 9 | public SkinSlot[] slots; 10 | 11 | Dictionary _slots; 12 | 13 | public SkinSlot this[string slotName]{ 14 | get{ 15 | if (_slots == null) 16 | resetCache(); 17 | if (!_slots.ContainsKey(slotName)) 18 | Debug.Log(slotName+"!!!!!" + name); 19 | return _slots[slotName]; 20 | } 21 | } 22 | 23 | public void resetCache(){ 24 | _slots = new Dictionary(); 25 | for (int i = 0; i < slots.Length; i++) { 26 | slots[i].resetCache(); 27 | _slots.Add(slots[i].name, slots[i]); 28 | } 29 | } 30 | 31 | public bool containsSlot(string slotName){ 32 | if (_slots == null) 33 | resetCache(); 34 | return _slots.ContainsKey(slotName); 35 | } 36 | 37 | public bool containsSlotAttachment(string slotName, string attachmentName){ 38 | if (_slots == null) 39 | resetCache(); 40 | if (!containsSlot(slotName)) 41 | return false; 42 | return _slots[slotName].containsAttachment(attachmentName); 43 | } 44 | 45 | public void setActive(bool value){ 46 | foreach(SkinSlot slot in slots){ 47 | foreach(SkinSlotAttachment attachment in slot.attachments){ 48 | attachment.gameObject.SetActive(value); 49 | } 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Skin/Skin.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a9fb63b6108984ed79a64f7d829760ab 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Skin/SkinSlot.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using System; 4 | 5 | namespace UnitySpineImporter{ 6 | [Serializable] 7 | public class SkinSlot { 8 | public string name; 9 | public GameObject gameObject; 10 | public SkinSlotAttachment[] attachments; 11 | 12 | Dictionary _attachments; 13 | public SkinSlotAttachment this[string attahcmentName]{ 14 | get{ 15 | if(_attachments == null) 16 | resetCache(); 17 | return _attachments[attahcmentName]; 18 | } 19 | } 20 | 21 | public void resetCache(){ 22 | _attachments = new Dictionary(); 23 | for (int i = 0; i < attachments.Length; i++) { 24 | _attachments.Add(attachments[i].name, attachments[i]); 25 | } 26 | } 27 | 28 | public bool containsAttachment(string attachmentName){ 29 | if (_attachments == null) 30 | resetCache(); 31 | return _attachments.ContainsKey(attachmentName); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Skin/SkinSlot.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8e225a16716aa4088ace856a4f6725ed 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Skin/SkinSlotAttachment.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System; 4 | 5 | namespace UnitySpineImporter{ 6 | [Serializable] 7 | public class SkinSlotAttachment { 8 | public string name; 9 | public GameObject gameObject; 10 | public SpriteRenderer sprite; 11 | public string ObPath; 12 | } 13 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Skin/SkinSlotAttachment.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dc62db0972d144fe39526a2ebc6dbf2d 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/SkinController.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System; 4 | using System.Collections.Generic; 5 | using UnitySpineImporter; 6 | 7 | 8 | 9 | 10 | 11 | namespace UnitySpineImporter{ 12 | public class SkinController : MonoBehaviour { 13 | public Skin defaultSkin; 14 | public Skin[] skins; 15 | public Slot[] slots; 16 | 17 | public int activeSkinId; 18 | 19 | 20 | Skin[] _allSkins; 21 | public Skin[] allSkins{ 22 | get{ 23 | if (_allSkins == null){ 24 | if (defaultSkin != null && defaultSkin.slots !=null && defaultSkin.slots.Length > 0){ 25 | _allSkins = new Skin[skins.Length+1]; 26 | Array.Copy(skins,_allSkins,skins.Length); 27 | _allSkins[_allSkins.Length -1] = defaultSkin; 28 | } else { 29 | _allSkins = skins; 30 | } 31 | } 32 | return _allSkins; 33 | } 34 | } 35 | 36 | public void deactivateAllAttachments(){ 37 | foreach(Skin skin in allSkins){ 38 | foreach(SkinSlot slot in skin.slots){ 39 | foreach(SkinSlotAttachment attachment in slot.attachments){ 40 | attachment.gameObject.SetActive(false); 41 | } 42 | } 43 | } 44 | } 45 | 46 | public void showDefaulSlots(){ 47 | deactivateAllAttachments(); 48 | 49 | if (skins.Length > 0){ 50 | activeSkinId = 0; 51 | setSkin(activeSkinId); 52 | } else { 53 | activeSkinId = -1; 54 | } 55 | 56 | foreach (Slot slot in slots){ 57 | slot.showDefaultAttachment(); 58 | } 59 | } 60 | 61 | public void setSkin(int skinId){ 62 | skins[activeSkinId].setActive(false); 63 | skins[skinId].setActive(true); 64 | activeSkinId = skinId; 65 | 66 | } 67 | 68 | } 69 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/SkinController.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee500af2605284600ad6db3edddc694f 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/SkinSlotGO.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using System; 4 | 5 | namespace UnitySpineImporter{ 6 | [Serializable] 7 | public class SkinSlotGO{ 8 | public GameObject attachmentGO; 9 | public SpriteRenderer[] innerSprites; 10 | 11 | Dictionary _spriteByName; 12 | public Dictionary spriteByName{ 13 | get{ 14 | if (spriteByName == null){ 15 | _spriteByName = new Dictionary(); 16 | for (int i = 0; i < innerSprites.Length; i++) { 17 | _spriteByName.Add(innerSprites[i].name, innerSprites[i]); 18 | } 19 | } 20 | return _spriteByName; 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/SkinSlotGO.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2383588ef2d364ed18239e33f70d23ac 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Slot.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a3e2778b160324424bd8627c0c3c4c95 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Slot/Attachment.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System; 4 | 5 | 6 | namespace UnitySpineImporter{ 7 | [Serializable] 8 | public class Attachment { 9 | public string name; 10 | public AttachmentType type; 11 | public GameObject gameObject; 12 | 13 | public Attachment (string name, AttachmentType type, GameObject gameObject) 14 | { 15 | this.name = name; 16 | this.type = type; 17 | this.gameObject = gameObject; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Slot/Attachment.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cc2039dbbcdf8411b96d9f9415b8e814 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Slot/AttachmentType.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | namespace UnitySpineImporter{ 5 | public enum AttachmentType { 6 | SINGLE_SPRITE, 7 | SKINED_SPRITE, 8 | BOUNDINGBOX, 9 | ANOTHER 10 | } 11 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Slot/AttachmentType.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0e754a155899f42b9a2d58ea668b3142 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Slot/Slot.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace UnitySpineImporter{ 6 | [Serializable] 7 | public class Slot { 8 | 9 | public string name; 10 | public string bone; 11 | public string defaultAttachmentName; 12 | public Color32? color; 13 | public GameObject gameObject; 14 | public Attachment[] attachments; 15 | 16 | 17 | Dictionary _attachmentByName; 18 | public Dictionary attachmentByName{ 19 | get{ 20 | if (_attachmentByName == null){ 21 | _attachmentByName = new Dictionary(); 22 | if (attachments == null) 23 | attachments = new Attachment[0]; 24 | for (int i = 0; i < attachments.Length; i++) { 25 | _attachmentByName.Add(attachments[i].name, attachments[i]); 26 | } 27 | } 28 | return _attachmentByName; 29 | } 30 | } 31 | 32 | public Slot(){} 33 | 34 | //TODO probably can delete it 35 | public Slot (string bone, string slot, string attachment = null, Color32? color = null) 36 | { 37 | this.bone = bone; 38 | this.name = slot; 39 | this.defaultAttachmentName = attachment; 40 | this.color = color; 41 | } 42 | 43 | public void hideAllAttachments(){ 44 | if (attachments == null) 45 | return; 46 | foreach(Attachment a in attachments){ 47 | a.gameObject.SetActive(false); 48 | } 49 | } 50 | 51 | public void showAttachment(string attachmentName){ 52 | hideAllAttachments(); 53 | attachmentByName[attachmentName].gameObject.SetActive(true); 54 | } 55 | 56 | public void showDefaultAttachment(){ 57 | if (string.IsNullOrEmpty(defaultAttachmentName)) 58 | hideAllAttachments(); 59 | else 60 | showAttachment(defaultAttachmentName); 61 | } 62 | 63 | public void addAttachment(Attachment attachment){ 64 | if (attachments == null){ 65 | attachments = new Attachment[]{attachment}; 66 | } else { 67 | Attachment[] newA = new Attachment[attachments.Length + 1]; 68 | Array.Copy(attachments, newA,attachments.Length); 69 | newA[newA.Length -1] = attachment; 70 | attachments = newA; 71 | } 72 | if (_attachmentByName == null) 73 | _attachmentByName = new Dictionary(); 74 | _attachmentByName.Add(attachment.name, attachment); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/Slot/Slot.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5099f7722cb5345fcbc9f8df1c78fb8f 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/SlotGOByName.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | namespace UnitySpineImporter{ 5 | public class SlotGOByName : Dictionary { 6 | } 7 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/SlotGOByName.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bc9456cdd368849188f955bb4d932584 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/SlotGOByNameBySkinName.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace UnitySpineImporter{ 4 | public class SlotGOByNameBySkinName : Dictionary { 5 | } 6 | } -------------------------------------------------------------------------------- /Assets/UnitySpineImporter/SharedScripts/SlotGOByNameBySkinName.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dc2cb5f40a2a34eeca9c402aae57c088 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/Assets/test/DrawOrder/1.png -------------------------------------------------------------------------------- /Assets/test/DrawOrder/1.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c9b5670ec656f4fd1bd569e3d7089ea4 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 2 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | linearTexture: 0 10 | correctGamma: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: .25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 0 23 | seamlessCubemap: 0 24 | textureFormat: -1 25 | maxTextureSize: 1024 26 | textureSettings: 27 | filterMode: -1 28 | aniso: -1 29 | mipBias: -1 30 | wrapMode: -1 31 | nPOTScale: 1 32 | lightmap: 0 33 | compressionQuality: 50 34 | spriteMode: 0 35 | spriteExtrude: 1 36 | spriteMeshType: 1 37 | alignment: 0 38 | spritePivot: {x: .5, y: .5} 39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 40 | spritePixelsToUnits: 100 41 | alphaIsTransparency: 0 42 | textureType: -1 43 | buildTargetSettings: [] 44 | spriteSheet: 45 | sprites: [] 46 | spritePackingTag: 47 | userData: 48 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/Assets/test/DrawOrder/2.png -------------------------------------------------------------------------------- /Assets/test/DrawOrder/2.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b21b44cbe95d431891bf70b9ebf32b0 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 2 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | linearTexture: 0 10 | correctGamma: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: .25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 0 23 | seamlessCubemap: 0 24 | textureFormat: -1 25 | maxTextureSize: 1024 26 | textureSettings: 27 | filterMode: -1 28 | aniso: -1 29 | mipBias: -1 30 | wrapMode: -1 31 | nPOTScale: 1 32 | lightmap: 0 33 | compressionQuality: 50 34 | spriteMode: 0 35 | spriteExtrude: 1 36 | spriteMeshType: 1 37 | alignment: 0 38 | spritePivot: {x: .5, y: .5} 39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 40 | spritePixelsToUnits: 100 41 | alphaIsTransparency: 0 42 | textureType: -1 43 | buildTargetSettings: [] 44 | spriteSheet: 45 | sprites: [] 46 | spritePackingTag: 47 | userData: 48 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/Assets/test/DrawOrder/3.png -------------------------------------------------------------------------------- /Assets/test/DrawOrder/3.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f874b442646954af5a8e7981913ce559 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 2 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | linearTexture: 0 10 | correctGamma: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: .25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 0 23 | seamlessCubemap: 0 24 | textureFormat: -1 25 | maxTextureSize: 1024 26 | textureSettings: 27 | filterMode: -1 28 | aniso: -1 29 | mipBias: -1 30 | wrapMode: -1 31 | nPOTScale: 1 32 | lightmap: 0 33 | compressionQuality: 50 34 | spriteMode: 0 35 | spriteExtrude: 1 36 | spriteMeshType: 1 37 | alignment: 0 38 | spritePivot: {x: .5, y: .5} 39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 40 | spritePixelsToUnits: 100 41 | alphaIsTransparency: 0 42 | textureType: -1 43 | buildTargetSettings: [] 44 | spriteSheet: 45 | sprites: [] 46 | spritePackingTag: 47 | userData: 48 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/Assets/test/DrawOrder/4.png -------------------------------------------------------------------------------- /Assets/test/DrawOrder/4.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2bf6204690c4f4db5af906e52dc8a11a 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 2 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | linearTexture: 0 10 | correctGamma: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: .25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 0 23 | seamlessCubemap: 0 24 | textureFormat: -1 25 | maxTextureSize: 1024 26 | textureSettings: 27 | filterMode: -1 28 | aniso: -1 29 | mipBias: -1 30 | wrapMode: -1 31 | nPOTScale: 1 32 | lightmap: 0 33 | compressionQuality: 50 34 | spriteMode: 0 35 | spriteExtrude: 1 36 | spriteMeshType: 1 37 | alignment: 0 38 | spritePivot: {x: .5, y: .5} 39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 40 | spritePixelsToUnits: 100 41 | alphaIsTransparency: 0 42 | textureType: -1 43 | buildTargetSettings: [] 44 | spriteSheet: 45 | sprites: [] 46 | spritePackingTag: 47 | userData: 48 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/animation.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d466aea0adaba4fedb50a95b4d2f0cfd 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/animation/test_slot_order.anim.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/Assets/test/DrawOrder/animation/test_slot_order.anim.asset -------------------------------------------------------------------------------- /Assets/test/DrawOrder/animation/test_slot_order.anim.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5bc5bd191c8714825beb1a53c39f483b 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/animation/test_slot_order.mask.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/Assets/test/DrawOrder/animation/test_slot_order.mask.asset -------------------------------------------------------------------------------- /Assets/test/DrawOrder/animation/test_slot_order.mask.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0686a0cee61304427800884f3070daa1 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/spine.spine: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/Assets/test/DrawOrder/spine.spine -------------------------------------------------------------------------------- /Assets/test/DrawOrder/spine.spine.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aa45774d4c53d4f4d8b70884ef4137fc 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/test_slot_order.atlas: -------------------------------------------------------------------------------- 1 | 2 | test_slot_order.png 3 | size: 520,130 4 | format: RGBA8888 5 | filter: Linear,Linear 6 | repeat: none 7 | 1 8 | rotate: false 9 | xy: 2, 2 10 | size: 128, 128 11 | orig: 128, 128 12 | offset: 0, 0 13 | index: -1 14 | 2 15 | rotate: false 16 | xy: 132, 2 17 | size: 128, 128 18 | orig: 128, 128 19 | offset: 0, 0 20 | index: -1 21 | 3 22 | rotate: false 23 | xy: 262, 2 24 | size: 128, 128 25 | orig: 128, 128 26 | offset: 0, 0 27 | index: -1 28 | 4 29 | rotate: false 30 | xy: 392, 2 31 | size: 128, 128 32 | orig: 128, 128 33 | offset: 0, 0 34 | index: -1 35 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/test_slot_order.atlas.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 12971e0dab7834041bb110374694b87c 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/test_slot_order.json: -------------------------------------------------------------------------------- 1 | { 2 | "skeleton": { "spine": "1.9.15", "hash": "HXT4BLqTX7yvfB45ju0PgO/401s", "width": 128, "height": 128 }, 3 | "bones": [ 4 | { "name": "root" }, 5 | { "name": "bone", "parent": "root" }, 6 | { "name": "bone2", "parent": "root" }, 7 | { "name": "bone3", "parent": "bone2" } 8 | ], 9 | "ik": [], 10 | "slots": [ 11 | { "name": "1", "bone": "root" }, 12 | { "name": "slot2", "bone": "bone", "attachment": "2" }, 13 | { "name": "slot3", "bone": "bone2", "attachment": "3" }, 14 | { "name": "slot4", "bone": "bone3", "attachment": "4" } 15 | ], 16 | "skins": { 17 | "default": { 18 | "1": { 19 | "1": { "width": 128, "height": 128 } 20 | }, 21 | "slot2": { 22 | "2": { "width": 128, "height": 128 } 23 | }, 24 | "slot3": { 25 | "3": { "width": 128, "height": 128 } 26 | }, 27 | "slot4": { 28 | "4": { "width": 128, "height": 128 } 29 | } 30 | } 31 | }, 32 | "animations": { 33 | "animation": { 34 | "draworder": [ 35 | { "time": 0 }, 36 | { 37 | "time": 0.3333, 38 | "offsets": [ 39 | { "slot": "slot4", "offset": -2 } 40 | ] 41 | }, 42 | { 43 | "time": 0.6666, 44 | "offsets": [ 45 | { "slot": "1", "offset": 3 }, 46 | { "slot": "slot4", "offset": -3 } 47 | ] 48 | }, 49 | { 50 | "time": 1, 51 | "offsets": [ 52 | { "slot": "slot2", "offset": 2 }, 53 | { "slot": "slot4", "offset": -3 } 54 | ] 55 | } 56 | ] 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Assets/test/DrawOrder/test_slot_order.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1799c10857aa64517b613fc15b0c9187 3 | TextScriptImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/test/DrawOrder/test_slot_order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/Assets/test/DrawOrder/test_slot_order.png -------------------------------------------------------------------------------- /Assets/test/DrawOrder/test_slot_order.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8fa3f2c6a3cc24a29ad74bbb68b436e0 3 | TextureImporter: 4 | fileIDToRecycleName: 5 | 21300000: 1 6 | 21300002: 2 7 | 21300004: 3 8 | 21300006: 4 9 | serializedVersion: 2 10 | mipmaps: 11 | mipMapMode: 0 12 | enableMipMap: 0 13 | linearTexture: 0 14 | correctGamma: 0 15 | fadeOut: 0 16 | borderMipMap: 0 17 | mipMapFadeDistanceStart: 1 18 | mipMapFadeDistanceEnd: 3 19 | bumpmap: 20 | convertToNormalMap: 0 21 | externalNormalMap: 0 22 | heightScale: .25 23 | normalMapFilter: 0 24 | isReadable: 0 25 | grayScaleToAlpha: 0 26 | generateCubemap: 0 27 | seamlessCubemap: 0 28 | textureFormat: -1 29 | maxTextureSize: 1024 30 | textureSettings: 31 | filterMode: -1 32 | aniso: 1 33 | mipBias: -1 34 | wrapMode: 1 35 | nPOTScale: 0 36 | lightmap: 0 37 | compressionQuality: 50 38 | spriteMode: 2 39 | spriteExtrude: 1 40 | spriteMeshType: 1 41 | alignment: 0 42 | spritePivot: {x: .5, y: .5} 43 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 44 | spritePixelsToUnits: 100 45 | alphaIsTransparency: 1 46 | textureType: 8 47 | buildTargetSettings: [] 48 | spriteSheet: 49 | sprites: 50 | - name: 1 51 | rect: 52 | serializedVersion: 2 53 | x: 2 54 | y: 126 55 | width: 128 56 | height: 128 57 | alignment: 0 58 | pivot: {x: 0, y: 0} 59 | border: {x: 0, y: 0, z: 0, w: 0} 60 | - name: 2 61 | rect: 62 | serializedVersion: 2 63 | x: 132 64 | y: 126 65 | width: 128 66 | height: 128 67 | alignment: 0 68 | pivot: {x: 0, y: 0} 69 | border: {x: 0, y: 0, z: 0, w: 0} 70 | - name: 3 71 | rect: 72 | serializedVersion: 2 73 | x: 262 74 | y: 126 75 | width: 128 76 | height: 128 77 | alignment: 0 78 | pivot: {x: 0, y: 0} 79 | border: {x: 0, y: 0, z: 0, w: 0} 80 | - name: 4 81 | rect: 82 | serializedVersion: 2 83 | x: 392 84 | y: 126 85 | width: 128 86 | height: 128 87 | alignment: 0 88 | pivot: {x: 0, y: 0} 89 | border: {x: 0, y: 0, z: 0, w: 0} 90 | spritePackingTag: 91 | userData: 92 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Nikolay 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | * Neither the name of the {organization} nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshLayers.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/NavMeshLayers.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.1.1p3 2 | m_StandardAssetsVersion: 0 3 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicloay/unity-spine-importer/5b6d04b79e6aa56eb538ce72b6e049f855f93322/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | unity-spine-importer 2 | ==================== 3 | 4 | Bring data from spine (EsotericSoftware) in to the unity3d 5 | 6 | Unity 5 users 7 | ======== 8 | Please use [latest version](../../releases/latest) ( v0.5 or above) 9 | 10 | Unity 4 users 11 | ====== 12 | Please use [v.04 version](../../releases/tag/v0.4) 13 | --------------------------------------------------------------------------------