Forráskód Böngészése

Merge branch '3.6' into 3.7-beta

badlogic 7 éve
szülő
commit
906c0b4b60
90 módosított fájl, 2015 hozzáadás és 467 törlés
  1. 2 1
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpinePlugin.cpp
  2. 1 1
      spine-unity/Assets/Spine Examples/Getting Started/1 The Spine GameObject.unity
  3. 9 3
      spine-unity/Assets/Spine Examples/Getting Started/3 Controlling Animation Continued.unity
  4. 76 75
      spine-unity/Assets/Spine Examples/Getting Started/4 Object Oriented Sample.unity
  5. 19 25
      spine-unity/Assets/Spine Examples/Other Examples/Drunkboy.unity
  6. 2 2
      spine-unity/Assets/Spine Examples/Other Examples/Freezeboy.unity
  7. 9 6
      spine-unity/Assets/Spine Examples/Other Examples/SkeletonRenderSeparator.unity
  8. 5 1
      spine-unity/Assets/Spine Examples/Other Examples/SpineGauge.unity
  9. 116 2
      spine-unity/Assets/Spine Examples/Other Examples/VertexEffect.unity
  10. 6 4
      spine-unity/Assets/Spine Examples/Scripts/AttackSpineboy.cs
  11. 3 8
      spine-unity/Assets/Spine Examples/Scripts/Getting Started Scripts/Raptor.cs
  12. 1 2
      spine-unity/Assets/Spine Examples/Scripts/Getting Started Scripts/SpineBlinkPlayer.cs
  13. 4 4
      spine-unity/Assets/Spine Examples/Scripts/Getting Started Scripts/SpineboyBeginnerView.cs
  14. 0 2
      spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipAssetExample.cs
  15. 15 0
      spine-unity/Assets/Spine Examples/Scripts/ReloadSceneOnKeyDown.cs
  16. 12 0
      spine-unity/Assets/Spine Examples/Scripts/ReloadSceneOnKeyDown.cs.meta
  17. 106 0
      spine-unity/Assets/Spine Examples/Scripts/Sample Components/Sample VertexEffects/TwoByTwoTransformEffectExample.cs
  18. 12 0
      spine-unity/Assets/Spine Examples/Scripts/Sample Components/Sample VertexEffects/TwoByTwoTransformEffectExample.cs.meta
  19. 2 11
      spine-unity/Assets/Spine Examples/Scripts/SpineGauge.cs
  20. 2 4
      spine-unity/Assets/Spine Examples/Scripts/SpineboyFreeze.cs
  21. 2 4
      spine-unity/Assets/Spine Examples/Scripts/SpineboyPole.cs
  22. 9 0
      spine-unity/Assets/Spine Examples/Spine/Gauge/ReferenceAssets.meta
  23. 15 0
      spine-unity/Assets/Spine Examples/Spine/Gauge/ReferenceAssets/Fill.asset
  24. 9 0
      spine-unity/Assets/Spine Examples/Spine/Gauge/ReferenceAssets/Fill.asset.meta
  25. 9 0
      spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets.meta
  26. 15 0
      spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/Jump.asset
  27. 9 0
      spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/Jump.asset.meta
  28. 15 0
      spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/gungrab.asset
  29. 9 0
      spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/gungrab.asset.meta
  30. 15 0
      spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/gunkeep.asset
  31. 9 0
      spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/gunkeep.asset.meta
  32. 15 0
      spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/walk.asset
  33. 9 0
      spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/walk.asset.meta
  34. 5 2
      spine-unity/Assets/Spine Examples/Spine/Raptor/raptor_Material.mat
  35. 9 0
      spine-unity/Assets/Spine Examples/Spine/Spineunitygirl/ReferenceAssets.meta
  36. 15 0
      spine-unity/Assets/Spine Examples/Spine/Spineunitygirl/ReferenceAssets/blink.asset
  37. 9 0
      spine-unity/Assets/Spine Examples/Spine/Spineunitygirl/ReferenceAssets/blink.asset.meta
  38. 15 0
      spine-unity/Assets/Spine Examples/Spine/Spineunitygirl/ReferenceAssets/main.asset
  39. 9 0
      spine-unity/Assets/Spine Examples/Spine/Spineunitygirl/ReferenceAssets/main.asset.meta
  40. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets.meta
  41. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/death.asset
  42. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/death.asset.meta
  43. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/diagonal.asset
  44. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/diagonal.asset.meta
  45. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/footstep.asset
  46. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/footstep.asset.meta
  47. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/frozen.asset
  48. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/frozen.asset.meta
  49. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/gun toss.asset
  50. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/gun toss.asset.meta
  51. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/hit old.asset
  52. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/hit old.asset.meta
  53. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/hit.asset
  54. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/hit.asset.meta
  55. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/idle.asset
  56. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/idle.asset.meta
  57. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/idlebag.asset
  58. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/idlebag.asset.meta
  59. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump old.asset
  60. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump old.asset.meta
  61. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump rm.asset
  62. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump rm.asset.meta
  63. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump.asset
  64. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump.asset.meta
  65. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/pole.asset
  66. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/pole.asset.meta
  67. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/run rm.asset
  68. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/run rm.asset.meta
  69. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/run.asset
  70. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/run.asset.meta
  71. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/shoot.asset
  72. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/shoot.asset.meta
  73. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/walk rm.asset
  74. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/walk rm.asset.meta
  75. 15 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/walk.asset
  76. 9 0
      spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/walk.asset.meta
  77. 65 0
      spine-unity/Assets/spine-unity/Asset Types/AnimationReferenceAsset.cs
  78. 12 0
      spine-unity/Assets/spine-unity/Asset Types/AnimationReferenceAsset.cs.meta
  79. 66 0
      spine-unity/Assets/spine-unity/Asset Types/EventDataReferenceAsset.cs
  80. 12 0
      spine-unity/Assets/spine-unity/Asset Types/EventDataReferenceAsset.cs.meta
  81. 0 16
      spine-unity/Assets/spine-unity/Components/SkeletonAnimator.cs
  82. 159 0
      spine-unity/Assets/spine-unity/Editor/AnimationReferenceAssetEditor.cs
  83. 12 0
      spine-unity/Assets/spine-unity/Editor/AnimationReferenceAssetEditor.cs.meta
  84. 2 2
      spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs
  85. 51 27
      spine-unity/Assets/spine-unity/Editor/SkeletonBakingWindow.cs
  86. 138 59
      spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs
  87. 184 197
      spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs
  88. 3 3
      spine-unity/Assets/spine-unity/Editor/SpineInspectorUtility.cs
  89. 124 3
      spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs
  90. 142 3
      spine-unity/Assets/spine-unity/SkeletonExtensions.cs

+ 2 - 1
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpinePlugin.cpp

@@ -53,7 +53,8 @@ static void * SpineRealloc( void* ptr, size_t size ) {
 }
 
 void FSpinePlugin::StartupModule() {
-#if !UE_EDITOR
+	// Needed for consoles, see https://github.com/EsotericSoftware/spine-runtimes/pull/1089
+#if !UE_EDITOR && !PLATFORM_WINDOWS && !PLATFORM_MAC && !PLATFORM_LINUX && !PLATFORM_IOS && !PLATFORM_ANDROID && !PLATFORM_HTML5
     _spSetMalloc( &SpineMalloc );
     _spSetRealloc( &SpineRealloc );
     _spSetFree( FMemory::Free );

+ 1 - 1
spine-unity/Assets/Spine Examples/Getting Started/1 The Spine GameObject.unity

@@ -220,7 +220,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 5a5ef44bf3e0d864794c0da71c84363d, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  blinkAnimation: blink
+  blinkAnimation: {fileID: 11400000, guid: abea4790b61cd194eab5977fc16e095d, type: 2}
   minimumDelay: 0.15
   maximumDelay: 3
 --- !u!1 &199409354

+ 9 - 3
spine-unity/Assets/Spine Examples/Getting Started/3 Controlling Animation Continued.unity

@@ -178,6 +178,12 @@ TextMesh:
   m_Text: 'The Raptor script shows how you can play animations simultaneously.
 
 
+    This also shows how to use AnimationReferenceAssets as
+
+    an alternative to using animation name strings.
+
+
+
     Here, the "walk" animation is looping.
 
     At the same time, and in its own timeframe,
@@ -360,9 +366,9 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 8b0d38dc0b91fb443a41838d475ae49b, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  walk: walk
-  gungrab: gungrab
-  gunkeep: gunkeep
+  walk: {fileID: 11400000, guid: ac5036612c87200419da1450c17b1482, type: 2}
+  gungrab: {fileID: 11400000, guid: f8a357da5599fa342beda596bc86bc35, type: 2}
+  gunkeep: {fileID: 11400000, guid: d1426f136e8d57343a64e6be7454418b, type: 2}
 --- !u!1 &1382792502
 GameObject:
   m_ObjectHideFlags: 0

+ 76 - 75
spine-unity/Assets/Spine Examples/Getting Started/4 Object Oriented Sample.unity

@@ -327,75 +327,6 @@ Transform:
   m_Father: {fileID: 0}
   m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
---- !u!1 &811622967
-GameObject:
-  m_ObjectHideFlags: 0
-  m_PrefabParentObject: {fileID: 0}
-  m_PrefabInternal: {fileID: 0}
-  serializedVersion: 5
-  m_Component:
-  - component: {fileID: 811622971}
-  - component: {fileID: 811622970}
-  - component: {fileID: 811622969}
-  m_Layer: 0
-  m_Name: PLATFORM platform
-  m_TagString: Untagged
-  m_Icon: {fileID: 0}
-  m_NavMeshLayer: 0
-  m_StaticEditorFlags: 0
-  m_IsActive: 1
---- !u!23 &811622969
-MeshRenderer:
-  m_ObjectHideFlags: 0
-  m_PrefabParentObject: {fileID: 0}
-  m_PrefabInternal: {fileID: 0}
-  m_GameObject: {fileID: 811622967}
-  m_Enabled: 1
-  m_CastShadows: 0
-  m_ReceiveShadows: 0
-  m_MotionVectors: 1
-  m_LightProbeUsage: 0
-  m_ReflectionProbeUsage: 0
-  m_Materials:
-  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
-  m_StaticBatchInfo:
-    firstSubMesh: 0
-    subMeshCount: 0
-  m_StaticBatchRoot: {fileID: 0}
-  m_ProbeAnchor: {fileID: 0}
-  m_LightProbeVolumeOverride: {fileID: 0}
-  m_ScaleInLightmap: 1
-  m_PreserveUVs: 1
-  m_IgnoreNormalsForChartDetection: 0
-  m_ImportantGI: 0
-  m_SelectedEditorRenderState: 3
-  m_MinimumChartSize: 4
-  m_AutoUVMaxDistance: 0.5
-  m_AutoUVMaxAngle: 89
-  m_LightmapParameters: {fileID: 0}
-  m_SortingLayerID: 0
-  m_SortingLayer: 0
-  m_SortingOrder: 0
---- !u!33 &811622970
-MeshFilter:
-  m_ObjectHideFlags: 0
-  m_PrefabParentObject: {fileID: 0}
-  m_PrefabInternal: {fileID: 0}
-  m_GameObject: {fileID: 811622967}
-  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
---- !u!4 &811622971
-Transform:
-  m_ObjectHideFlags: 0
-  m_PrefabParentObject: {fileID: 0}
-  m_PrefabInternal: {fileID: 0}
-  m_GameObject: {fileID: 811622967}
-  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
-  m_LocalPosition: {x: -1.08, y: -3.68, z: 2.09}
-  m_LocalScale: {x: 30.490564, y: 1, z: 1}
-  m_Children: []
-  m_Father: {fileID: 0}
-  m_RootOrder: 3
-  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 --- !u!1 &816033309
 GameObject:
   m_ObjectHideFlags: 0
@@ -515,11 +446,11 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   model: {fileID: 299828574}
   skeletonAnimation: {fileID: 816033310}
-  run: run
-  idle: idle
-  shoot: shoot
-  jump: jump
-  footstepEventName: footstep
+  run: {fileID: 11400000, guid: 2d841d20c203ff24a859b8c73f9c3817, type: 2}
+  idle: {fileID: 11400000, guid: 8a71ad90c9e356d4fa476a420aeb259d, type: 2}
+  shoot: {fileID: 11400000, guid: 6d4c548ed1818024bb6ed2ee16dbfc40, type: 2}
+  jump: {fileID: 11400000, guid: 69a6ea3cadcdebb44a8c3b5fa43880e7, type: 2}
+  footstepEvent: {fileID: 11400000, guid: 2657d9f265aa59446b055dc0c1018419, type: 2}
   footstepPitchOffset: 0.2
   gunsoundPitchOffset: 0.13
   footstepSource: {fileID: 1858851856}
@@ -1272,7 +1203,7 @@ ParticleSystem:
   moveWithTransform: 1
   moveWithCustomTransform: {fileID: 0}
   scalingMode: 1
-  randomSeed: 1048114582
+  randomSeed: 823379790
   InitialModule:
     serializedVersion: 3
     enabled: 1
@@ -4292,3 +4223,73 @@ ParticleSystem:
         m_PreInfinity: 2
         m_PostInfinity: 2
         m_RotationOrder: 4
+--- !u!1 &2111197920
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 2111197922}
+  - component: {fileID: 2111197921}
+  m_Layer: 0
+  m_Name: New Sprite
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!212 &2111197921
+SpriteRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2111197920}
+  m_Enabled: 1
+  m_CastShadows: 0
+  m_ReceiveShadows: 0
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_Materials:
+  - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_SelectedEditorRenderState: 0
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+  m_Sprite: {fileID: 21300000, guid: 718074e4e56a5404e824bf8e6571ea7d, type: 3}
+  m_Color: {r: 0.16470589, g: 0.1764706, b: 0.20000002, a: 1}
+  m_FlipX: 0
+  m_FlipY: 0
+  m_DrawMode: 0
+  m_Size: {x: 0.32, y: 0.32}
+  m_AdaptiveModeThreshold: 0.5
+  m_SpriteTileMode: 0
+  m_WasSpriteAssigned: 1
+--- !u!4 &2111197922
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 2111197920}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: -3.68, z: 0}
+  m_LocalScale: {x: 64.73077, y: 2.9312356, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

+ 19 - 25
spine-unity/Assets/Spine Examples/Other Examples/Drunkboy.unity

@@ -451,7 +451,6 @@ GameObject:
   - component: {fileID: 219783490}
   - component: {fileID: 219783489}
   - component: {fileID: 219783488}
-  - component: {fileID: 219783487}
   m_Layer: 5
   m_Name: Canvas
   m_TagString: Untagged
@@ -459,22 +458,6 @@ GameObject:
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
   m_IsActive: 1
---- !u!114 &219783487
-MonoBehaviour:
-  m_ObjectHideFlags: 0
-  m_PrefabParentObject: {fileID: 0}
-  m_PrefabInternal: {fileID: 0}
-  m_GameObject: {fileID: 219783486}
-  m_Enabled: 1
-  m_EditorHideFlags: 0
-  m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
-  m_Name: 
-  m_EditorClassIdentifier: 
-  m_IgnoreReversedGraphics: 1
-  m_BlockingObjects: 0
-  m_BlockingMask:
-    serializedVersion: 2
-    m_Bits: 4294967295
 --- !u!114 &219783488
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -1058,6 +1041,7 @@ GameObject:
   - component: {fileID: 811443165}
   - component: {fileID: 811443166}
   - component: {fileID: 811443164}
+  - component: {fileID: 811443168}
   m_Layer: 0
   m_Name: Drunkboy
   m_TagString: Untagged
@@ -1135,6 +1119,18 @@ Transform:
   m_Father: {fileID: 0}
   m_RootOrder: 1
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &811443168
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 811443163}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d655607dd16c7f644a73bd10fc7370b1, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  reloadKey: 114
 --- !u!1 &841681496
 GameObject:
   m_ObjectHideFlags: 0
@@ -1713,7 +1709,7 @@ RectTransform:
   m_GameObject: {fileID: 1701764089}
   m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
   m_LocalPosition: {x: 0, y: 0, z: 0}
-  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_LocalScale: {x: 0.8, y: 0.8, z: 0.8}
   m_Children: []
   m_Father: {fileID: 219783490}
   m_RootOrder: 0
@@ -1736,7 +1732,7 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   m_Material: {fileID: 0}
   m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
-  m_RaycastTarget: 1
+  m_RaycastTarget: 0
   m_OnCullStateChanged:
     m_PersistentCalls:
       m_Calls: []
@@ -1744,22 +1740,20 @@ MonoBehaviour:
       Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
   m_FontData:
     m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
-    m_FontSize: 32
+    m_FontSize: 35
     m_FontStyle: 0
     m_BestFit: 0
     m_MinSize: 3
-    m_MaxSize: 40
+    m_MaxSize: 56
     m_Alignment: 0
     m_AlignByGeometry: 0
     m_RichText: 1
     m_HorizontalOverflow: 0
     m_VerticalOverflow: 0
     m_LineSpacing: 1
-  m_Text: 'Enter PLAY MODE.
-
-    Click and Drag Spineboy Left and Right
+  m_Text: 'Click and Drag Spineboy Left and Right.
 
-'
+    Press <b>R</b> to reload scene.'
 --- !u!222 &1701764092
 CanvasRenderer:
   m_ObjectHideFlags: 0

+ 2 - 2
spine-unity/Assets/Spine Examples/Other Examples/Freezeboy.unity

@@ -3549,8 +3549,8 @@ MonoBehaviour:
   m_Name: 
   m_EditorClassIdentifier: 
   skeletonAnimation: {fileID: 1126206820}
-  freeze: frozen
-  idle: idle
+  freeze: {fileID: 11400000, guid: 9db45f1cea1a1d74f86992ad2f34f114, type: 2}
+  idle: {fileID: 11400000, guid: 8a71ad90c9e356d4fa476a420aeb259d, type: 2}
   freezeColor: {r: 0.71188366, g: 0.93390405, b: 0.97794116, a: 1}
   freezeBlackColor: {r: 0.020274673, g: 0.6587631, b: 0.9191176, a: 0}
   particles: {fileID: 772326264}

+ 9 - 6
spine-unity/Assets/Spine Examples/Other Examples/SkeletonRenderSeparator.unity

@@ -282,7 +282,7 @@ MeshRenderer:
   m_LightProbeUsage: 0
   m_ReflectionProbeUsage: 1
   m_Materials:
-  - {fileID: 0}
+  - {fileID: 2100000, guid: 1455e88fdb81ccc45bdeaedd657bad4d, type: 2}
   m_StaticBatchInfo:
     firstSubMesh: 0
     subMeshCount: 0
@@ -1012,7 +1012,7 @@ ParticleSystem:
     boxY: 1
     boxZ: 1
     radius:
-      value: 0.46
+      value: 0.16
       mode: 0
       spread: 0
       speed:
@@ -1119,7 +1119,7 @@ ParticleSystem:
     rateOverTime:
       serializedVersion: 2
       minMaxState: 0
-      scalar: 50
+      scalar: 40
       minScalar: 0
       maxCurve:
         serializedVersion: 2
@@ -3787,6 +3787,7 @@ SpriteRenderer:
   m_Size: {x: 1, y: 1}
   m_AdaptiveModeThreshold: 0.5
   m_SpriteTileMode: 0
+  m_WasSpriteAssigned: 1
 --- !u!4 &774732877
 Transform:
   m_ObjectHideFlags: 0
@@ -3869,6 +3870,7 @@ SpriteRenderer:
   m_Size: {x: 1, y: 1}
   m_AdaptiveModeThreshold: 0.5
   m_SpriteTileMode: 0
+  m_WasSpriteAssigned: 1
 --- !u!1 &1406277772
 GameObject:
   m_ObjectHideFlags: 0
@@ -3938,6 +3940,7 @@ SpriteRenderer:
   m_Size: {x: 1, y: 1}
   m_AdaptiveModeThreshold: 0.5
   m_SpriteTileMode: 0
+  m_WasSpriteAssigned: 1
 --- !u!1 &1498924765
 GameObject:
   m_ObjectHideFlags: 0
@@ -4461,7 +4464,7 @@ MeshRenderer:
   m_LightProbeUsage: 0
   m_ReflectionProbeUsage: 1
   m_Materials:
-  - {fileID: 0}
+  - {fileID: 2100000, guid: 1455e88fdb81ccc45bdeaedd657bad4d, type: 2}
   m_StaticBatchInfo:
     firstSubMesh: 0
     subMeshCount: 0
@@ -4515,8 +4518,8 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   skeletonAnimation: {fileID: 1918225116}
   separator: {fileID: 1918225115}
-  run: run
-  pole: pole
+  run: {fileID: 11400000, guid: 2d841d20c203ff24a859b8c73f9c3817, type: 2}
+  pole: {fileID: 11400000, guid: dff7c26e6e007e748b47240522cff0c8, type: 2}
   startX: -11.5
   endX: 2.8
 --- !u!1 &2142418130

+ 5 - 1
spine-unity/Assets/Spine Examples/Other Examples/SpineGauge.unity

@@ -395,7 +395,7 @@ MonoBehaviour:
   m_Name: 
   m_EditorClassIdentifier: 
   fillPercent: 1
-  fillAnimationName: Fill
+  fillAnimation: {fileID: 11400000, guid: 416feb17a0d192844abb17619bf81153, type: 2}
 --- !u!114 &795271515
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -520,6 +520,10 @@ MonoBehaviour:
   attackerSpineboy: {fileID: 282891644}
   gauge: {fileID: 795271514}
   healthText: {fileID: 1847717249}
+  shoot: {fileID: 11400000, guid: 6d4c548ed1818024bb6ed2ee16dbfc40, type: 2}
+  hit: {fileID: 11400000, guid: 83e1b716474ea9141983c4d570adf4f9, type: 2}
+  idle: {fileID: 11400000, guid: 8a71ad90c9e356d4fa476a420aeb259d, type: 2}
+  death: {fileID: 11400000, guid: 790b48b79d40d4e4c995da2991932ade, type: 2}
   onAttack:
     m_PersistentCalls:
       m_Calls:

+ 116 - 2
spine-unity/Assets/Spine Examples/Other Examples/VertexEffect.unity

@@ -121,7 +121,7 @@ GameObject:
   - component: {fileID: 485702172}
   - component: {fileID: 485702171}
   m_Layer: 0
-  m_Name: Spine GameObject (raptor)
+  m_Name: Jitter Raptor
   m_TagString: Untagged
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
@@ -215,7 +215,7 @@ Transform:
   m_PrefabInternal: {fileID: 0}
   m_GameObject: {fileID: 485702170}
   m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
-  m_LocalPosition: {x: -1.1, y: -5.1, z: 0}
+  m_LocalPosition: {x: -7.28, y: -5.1, z: 0}
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_Children: []
   m_Father: {fileID: 0}
@@ -310,3 +310,117 @@ Transform:
   m_Father: {fileID: 0}
   m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1619480125
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1619480130}
+  - component: {fileID: 1619480129}
+  - component: {fileID: 1619480128}
+  - component: {fileID: 1619480127}
+  - component: {fileID: 1619480126}
+  m_Layer: 0
+  m_Name: 2x2 Transform Raptor
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1619480126
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1619480125}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 8afb2340fbd3fe14f9f4e07cba073e17, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  xAxis: {x: 0.94, y: -0.01}
+  yAxis: {x: 0.8, y: 0.7}
+--- !u!114 &1619480127
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1619480125}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d247ba06193faa74d9335f5481b2b56c, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: 22c4b5e5a0fd9484d83b1aa705b9a54c, type: 2}
+  initialSkinName: default
+  initialFlipX: 0
+  initialFlipY: 0
+  separatorSlotNames: []
+  zSpacing: 0
+  useClipping: 1
+  immutableTriangles: 0
+  pmaVertexColors: 1
+  clearStateOnDisable: 0
+  tintBlack: 0
+  singleSubmesh: 0
+  addNormals: 0
+  calculateTangents: 0
+  logErrors: 0
+  disableRenderingOnOverride: 1
+  _animationName: walk
+  loop: 1
+  timeScale: 1
+--- !u!23 &1619480128
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1619480125}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_Materials:
+  - {fileID: 2100000, guid: 4e2feebfcaa26a54ab19f1ff3e0eae35, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1619480129
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1619480125}
+  m_Mesh: {fileID: 0}
+--- !u!4 &1619480130
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1619480125}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: -1.39, y: -4.94, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

+ 6 - 4
spine-unity/Assets/Spine Examples/Scripts/AttackSpineboy.cs

@@ -42,6 +42,8 @@ namespace Spine.Unity.Examples {
 		int currentHealth = 100;
 		const int maxHealth = 100;
 
+		public AnimationReferenceAsset shoot, hit, idle, death;
+
 		public UnityEngine.Events.UnityEvent onAttack;
 
 		void Update () {
@@ -49,18 +51,18 @@ namespace Spine.Unity.Examples {
 				currentHealth -= 10;
 				healthText.text = currentHealth + "/" + maxHealth;
 
-				attackerSpineboy.AnimationState.SetAnimation(1, "shoot", false);
+				attackerSpineboy.AnimationState.SetAnimation(1, shoot, false);
 				attackerSpineboy.AnimationState.AddEmptyAnimation(1, 0.5f, 2f);
 
 				if (currentHealth > 0) {
-					spineboy.AnimationState.SetAnimation(0, "hit", false);
-					spineboy.AnimationState.AddAnimation(0, "idle", true, 0);
+					spineboy.AnimationState.SetAnimation(0, hit, false);
+					spineboy.AnimationState.AddAnimation(0, idle, true, 0);
 					gauge.fillPercent = (float)currentHealth/(float)maxHealth;
 					onAttack.Invoke();
 				} else {
 					if (currentHealth >= 0) {
 						gauge.fillPercent = 0;
-						spineboy.AnimationState.SetAnimation(0, "death", false).TrackEnd = float.PositiveInfinity;
+						spineboy.AnimationState.SetAnimation(0, death, false).TrackEnd = float.PositiveInfinity;
 					}
 				}
 			}

+ 3 - 8
spine-unity/Assets/Spine Examples/Scripts/Getting Started Scripts/Raptor.cs

@@ -36,14 +36,9 @@ namespace Spine.Unity.Examples {
 	public class Raptor : MonoBehaviour {
 
 		#region Inspector
-		[SpineAnimation]
-		public string walk = "walk";
-
-		[SpineAnimation]
-		public string gungrab = "gungrab";
-
-		[SpineAnimation]
-		public string gunkeep = "gunkeep";
+		public AnimationReferenceAsset walk;
+		public AnimationReferenceAsset gungrab;
+		public AnimationReferenceAsset gunkeep;
 		#endregion
 
 		SkeletonAnimation skeletonAnimation;

+ 1 - 2
spine-unity/Assets/Spine Examples/Scripts/Getting Started Scripts/SpineBlinkPlayer.cs

@@ -36,8 +36,7 @@ namespace Spine.Unity.Examples {
 	public class SpineBlinkPlayer : MonoBehaviour {
 		const int BlinkTrack = 1;
 
-		[SpineAnimation]
-		public string blinkAnimation;
+		public AnimationReferenceAsset blinkAnimation;
 		public float minimumDelay = 0.15f;
 		public float maximumDelay = 3f;
 

+ 4 - 4
spine-unity/Assets/Spine Examples/Scripts/Getting Started Scripts/SpineboyBeginnerView.cs

@@ -40,8 +40,8 @@ namespace Spine.Unity.Examples {
 		public SpineboyBeginnerModel model;
 		public SkeletonAnimation skeletonAnimation;
 
-		[SpineAnimation] public string run, idle, shoot, jump;
-		[SpineEvent] public string footstepEventName;
+		public AnimationReferenceAsset run, idle, shoot, jump;
+		public EventDataReferenceAsset footstepEvent;
 
 		[Header("Audio")]
 		public float footstepPitchOffset = 0.2f;
@@ -61,7 +61,7 @@ namespace Spine.Unity.Examples {
 		}
 
 		void HandleEvent (Spine.TrackEntry trackEntry, Spine.Event e) {
-			if (e.Data.Name == footstepEventName)
+			if (e.Data == footstepEvent.EventData)
 				PlayFootstepSound();
 		}
 
@@ -85,7 +85,7 @@ namespace Spine.Unity.Examples {
 
 		void PlayNewStableAnimation () {
 			var newModelState = model.state;
-			string nextAnimation;
+			Animation nextAnimation;
 
 			// Add conditionals to not interrupt transient animations.
 

+ 0 - 2
spine-unity/Assets/Spine Examples/Scripts/Mix and Match Character Customize/EquipAssetExample.cs

@@ -3,12 +3,10 @@ using System.Collections.Generic;
 using UnityEngine;
 
 namespace Spine.Unity.Examples {
-	[CreateAssetMenu]
 	public class EquipAssetExample : ScriptableObject {
 		public EquipSystemExample.EquipType equipType;
 		public Sprite sprite;
 		public string description;
 		public int yourStats;
 	}
-
 }

+ 15 - 0
spine-unity/Assets/Spine Examples/Scripts/ReloadSceneOnKeyDown.cs

@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+using UnityEngine.SceneManagement;
+
+public class ReloadSceneOnKeyDown : MonoBehaviour {
+
+	public KeyCode reloadKey = KeyCode.R;
+
+	void Update () {
+		if (Input.GetKeyDown(reloadKey))
+			SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex, LoadSceneMode.Single);
+	}
+}

+ 12 - 0
spine-unity/Assets/Spine Examples/Scripts/ReloadSceneOnKeyDown.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: d655607dd16c7f644a73bd10fc7370b1
+timeCreated: 1523294158
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 106 - 0
spine-unity/Assets/Spine Examples/Scripts/Sample Components/Sample VertexEffects/TwoByTwoTransformEffectExample.cs

@@ -0,0 +1,106 @@
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace Spine.Unity.Examples {
+
+	// This is a sample component for C# vertex effects for Spine rendering components.
+	// Using shaders and materials to control vertex properties is still more performant
+	// than using this API, but in cases where your vertex effect logic cannot be
+	// expressed as shader code, these vertex effects can be useful.
+	public class TwoByTwoTransformEffectExample : MonoBehaviour {
+
+		public Vector2 xAxis = new Vector2(1, 0);
+		public Vector2 yAxis = new Vector2(0, 1);
+
+		SkeletonRenderer skeletonRenderer;
+
+		void OnEnable () {
+			skeletonRenderer = GetComponent<SkeletonRenderer>();
+			if (skeletonRenderer == null) return;
+
+			// Use the OnPostProcessVertices callback to modify the vertices at the correct time.
+			skeletonRenderer.OnPostProcessVertices -= ProcessVertices;
+			skeletonRenderer.OnPostProcessVertices += ProcessVertices;
+
+			Debug.Log("2x2 Transform Effect Enabled.");
+		}
+
+		void ProcessVertices (MeshGeneratorBuffers buffers) {
+			if (!this.enabled)
+				return;
+
+			int vertexCount = buffers.vertexCount; // For efficiency, limit your effect to the actual mesh vertex count using vertexCount
+
+			// Modify vertex positions by accessing Vector3[] vertexBuffer
+			var vertices = buffers.vertexBuffer;
+			Vector3 transformedPos = default(Vector3);
+			for (int i = 0; i < vertexCount; i++) {
+				Vector3 originalPos = vertices[i];
+				transformedPos.x = (xAxis.x * originalPos.x) + (yAxis.x * originalPos.y);
+				transformedPos.y = (xAxis.y * originalPos.x) + (yAxis.y * originalPos.y);
+				vertices[i] = transformedPos;
+			}
+
+		}
+
+		void OnDisable () {
+			if (skeletonRenderer == null) return;
+			skeletonRenderer.OnPostProcessVertices -= ProcessVertices;
+			Debug.Log("2x2 Transform Effect Disabled.");
+		}
+	}
+
+}
+
+#if UNITY_EDITOR
+[UnityEditor.CustomEditor(typeof(Spine.Unity.Examples.TwoByTwoTransformEffectExample))]
+public class TwoByTwoTransformEffectExampleEditor : UnityEditor.Editor {
+
+	Spine.Unity.Examples.TwoByTwoTransformEffectExample Target { get { return target as Spine.Unity.Examples.TwoByTwoTransformEffectExample; } }
+
+	void OnSceneGUI () {
+		var transform = Target.transform;
+		LocalVectorHandle(ref Target.xAxis, transform, Color.red);
+		LocalVectorHandle(ref Target.yAxis, transform, Color.green);
+	}
+
+	static void LocalVectorHandle (ref Vector2 v, Transform transform, Color color) {
+		Color originalColor = UnityEditor.Handles.color;
+		UnityEditor.Handles.color = color;
+		UnityEditor.Handles.DrawLine(transform.position, transform.TransformPoint(v));
+		v = transform.InverseTransformPoint(UnityEditor.Handles.FreeMoveHandle(transform.TransformPoint(v), Quaternion.identity, 0.3f, Vector3.zero, UnityEditor.Handles.CubeHandleCap));
+		UnityEditor.Handles.color = originalColor;
+	}
+}
+#endif

+ 12 - 0
spine-unity/Assets/Spine Examples/Scripts/Sample Components/Sample VertexEffects/TwoByTwoTransformEffectExample.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 8afb2340fbd3fe14f9f4e07cba073e17
+timeCreated: 1523229765
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 2 - 11
spine-unity/Assets/Spine Examples/Scripts/SpineGauge.cs

@@ -39,13 +39,10 @@ namespace Spine.Unity.Examples {
 		#region Inspector
 		[Range(0,1)]
 		public float fillPercent = 0;
-
-		[SpineAnimation]
-		public string fillAnimationName;
+		public AnimationReferenceAsset fillAnimation;
 		#endregion
 
 		SkeletonRenderer skeletonRenderer;
-		Spine.Animation fillAnimation;
 
 		void Awake () {
 			skeletonRenderer = GetComponent<SkeletonRenderer>();
@@ -59,13 +56,7 @@ namespace Spine.Unity.Examples {
 			if (skeletonRenderer == null) return;
 			var skeleton = skeletonRenderer.skeleton; if (skeleton == null) return;
 
-			// Make super-sure that fillAnimation isn't null.
-			if (fillAnimation == null) {
-				fillAnimation = skeleton.Data.FindAnimation(fillAnimationName);
-				if (fillAnimation == null) return;
-			}
-
-			fillAnimation.Apply(skeleton, 0, percent, false, null, 1f, MixPose.Setup, MixDirection.In);
+			fillAnimation.Animation.Apply(skeleton, 0, percent, false, null, 1f, MixPose.Setup, MixDirection.In);
 
 			skeleton.Update(Time.deltaTime);
 			skeleton.UpdateWorldTransform();

+ 2 - 4
spine-unity/Assets/Spine Examples/Scripts/SpineboyFreeze.cs

@@ -6,10 +6,8 @@ namespace Spine.Unity.Examples {
 	public class SpineboyFreeze : MonoBehaviour {
 
 		public SkeletonAnimation skeletonAnimation;
-		[SpineAnimation]
-		public string freeze;
-		[SpineAnimation]
-		public string idle;
+		public AnimationReferenceAsset freeze;
+		public AnimationReferenceAsset idle;
 
 		public Color freezeColor;
 		public Color freezeBlackColor;

+ 2 - 4
spine-unity/Assets/Spine Examples/Scripts/SpineboyPole.cs

@@ -40,10 +40,8 @@ namespace Spine.Unity.Examples {
 		public SkeletonRenderSeparator separator;
 
 		[Space(18)]
-		[SpineAnimation]
-		public string run;
-		[SpineAnimation]
-		public string pole;
+		public AnimationReferenceAsset run;
+		public AnimationReferenceAsset pole;
 		public float startX;
 		public float endX;
 

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/Gauge/ReferenceAssets.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 32b45fca01f880942a0f95f63800b220
+folderAsset: yes
+timeCreated: 1523324866
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/Gauge/ReferenceAssets/Fill.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: Fill
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: 22b19a38b21c15a48854f0db86b0b7d3, type: 2}
+  animationName: Fill

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/Gauge/ReferenceAssets/Fill.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 416feb17a0d192844abb17619bf81153
+timeCreated: 1523324866
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 677c9e69cddecaf4381e8c60e21dd45b
+folderAsset: yes
+timeCreated: 1523325054
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/Jump.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: Jump
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: 22c4b5e5a0fd9484d83b1aa705b9a54c, type: 2}
+  animationName: Jump

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/Jump.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: db621bd3fb32cbe46933b7a8fe1a929e
+timeCreated: 1523325055
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/gungrab.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: gungrab
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: 22c4b5e5a0fd9484d83b1aa705b9a54c, type: 2}
+  animationName: gungrab

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/gungrab.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: f8a357da5599fa342beda596bc86bc35
+timeCreated: 1523325055
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/gunkeep.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: gunkeep
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: 22c4b5e5a0fd9484d83b1aa705b9a54c, type: 2}
+  animationName: gunkeep

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/gunkeep.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: d1426f136e8d57343a64e6be7454418b
+timeCreated: 1523325055
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/walk.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: walk
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: 22c4b5e5a0fd9484d83b1aa705b9a54c, type: 2}
+  animationName: walk

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/Raptor/ReferenceAssets/walk.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: ac5036612c87200419da1450c17b1482
+timeCreated: 1523325055
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 2
spine-unity/Assets/Spine Examples/Spine/Raptor/raptor_Material.mat

@@ -7,10 +7,11 @@ Material:
   m_PrefabParentObject: {fileID: 0}
   m_PrefabInternal: {fileID: 0}
   m_Name: raptor_Material
-  m_Shader: {fileID: 4800000, guid: 1e8a610c9e01c3648bac42585e5fc676, type: 3}
+  m_Shader: {fileID: 4800000, guid: 522f03282fd79be47b306e2ef4b593fd, type: 3}
   m_ShaderKeywords: 
   m_LightmapFlags: 5
   m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
   m_CustomRenderQueue: -1
   stringTagMap: {}
   disabledShaderPasses: []
@@ -23,4 +24,6 @@ Material:
         m_Offset: {x: 0, y: 0}
     m_Floats:
     - _Cutoff: 0.1
-    m_Colors: []
+    m_Colors:
+    - _Black: {r: 0, g: 0, b: 0, a: 0}
+    - _Color: {r: 1, g: 1, b: 1, a: 1}

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/Spineunitygirl/ReferenceAssets.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 47fb096b0328f254ab494f224cec0651
+folderAsset: yes
+timeCreated: 1523550853
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/Spineunitygirl/ReferenceAssets/blink.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: blink
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: 3c48535ae5679204c950a22a7caaa5a4, type: 2}
+  animationName: blink

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/Spineunitygirl/ReferenceAssets/blink.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: abea4790b61cd194eab5977fc16e095d
+timeCreated: 1523550854
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/Spineunitygirl/ReferenceAssets/main.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: main
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: 3c48535ae5679204c950a22a7caaa5a4, type: 2}
+  animationName: main

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/Spineunitygirl/ReferenceAssets/main.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: fb9d8b4d108ca63488ba93add8c66cde
+timeCreated: 1523550854
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 071b278bb714596449eaf54d4ba2997e
+folderAsset: yes
+timeCreated: 1523317351
+licenseType: Free
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/death.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: death
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: death

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/death.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 790b48b79d40d4e4c995da2991932ade
+timeCreated: 1523317351
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/diagonal.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: diagonal
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: diagonal

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/diagonal.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6b77ce13b7ea74949bdcaa43ed3eaa66
+timeCreated: 1523317351
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/footstep.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 8e60be42c1473144db0fd3337c25b500, type: 3}
+  m_Name: footstep
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  eventName: footstep

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/footstep.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 2657d9f265aa59446b055dc0c1018419
+timeCreated: 1523330918
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/frozen.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: frozen
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: frozen

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/frozen.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 9db45f1cea1a1d74f86992ad2f34f114
+timeCreated: 1523317351
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/gun toss.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: gun toss
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: gun toss

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/gun toss.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 7e027f92ba53df14da2f0814877d1069
+timeCreated: 1523317352
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/hit old.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: hit old
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: hit old

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/hit old.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: b5b08f3750a5704428e54929cf119ece
+timeCreated: 1523317352
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/hit.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: hit
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: hit

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/hit.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 83e1b716474ea9141983c4d570adf4f9
+timeCreated: 1523317352
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/idle.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: idle
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: idle

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/idle.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 8a71ad90c9e356d4fa476a420aeb259d
+timeCreated: 1523317352
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/idlebag.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: idlebag
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: idlebag

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/idlebag.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 305a9a349ff5861408c923de95b10585
+timeCreated: 1523317352
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump old.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: jump old
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: jump old

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump old.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 1d2c7dbbee0d2fd47997013804122e94
+timeCreated: 1523548764
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump rm.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: jump rm
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: jump rm

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump rm.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: bc123feee5c3f144d8f1fa7073f78de2
+timeCreated: 1523548764
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: jump
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: jump

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/jump.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 69a6ea3cadcdebb44a8c3b5fa43880e7
+timeCreated: 1523317352
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/pole.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: pole
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: pole

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/pole.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: dff7c26e6e007e748b47240522cff0c8
+timeCreated: 1523317352
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/run rm.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: run rm
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: run rm

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/run rm.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: be90eb47d25ae1149a1ffee2bb634498
+timeCreated: 1523548764
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/run.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: run
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: run

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/run.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 2d841d20c203ff24a859b8c73f9c3817
+timeCreated: 1523317353
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/shoot.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: shoot
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: shoot

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/shoot.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6d4c548ed1818024bb6ed2ee16dbfc40
+timeCreated: 1523317353
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/walk rm.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: walk rm
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: walk rm

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/walk rm.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 7fb30b5771c5c0e4191999928e186e88
+timeCreated: 1523548765
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/walk.asset

@@ -0,0 +1,15 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6e3e95a05e4c9774397eeeb7bdee8ccb, type: 3}
+  m_Name: walk
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: a467507a4ffb1d542a558739b2fede77, type: 2}
+  animationName: walk

+ 9 - 0
spine-unity/Assets/Spine Examples/Spine/spineboy-unity/ReferenceAssets/walk.asset.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 16e355cde32442f409a2b1a2362cf0e3
+timeCreated: 1523317353
+licenseType: Free
+NativeFormatImporter:
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 65 - 0
spine-unity/Assets/spine-unity/Asset Types/AnimationReferenceAsset.cs

@@ -0,0 +1,65 @@
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#define AUTOINIT_SPINEREFERENCE
+
+using UnityEngine;
+
+namespace Spine.Unity {
+	[CreateAssetMenu(menuName = "Spine/Animation Reference Asset")]
+	public class AnimationReferenceAsset : ScriptableObject {
+		const bool QuietSkeletonData = true;
+
+		[SerializeField] protected SkeletonDataAsset skeletonDataAsset;
+		[SerializeField, SpineAnimation(dataField: "skeletonDataAsset")] protected string animationName;
+
+		private Animation animation;
+		public Animation Animation {
+			get {
+				#if AUTOINIT_SPINEREFERENCE
+				if (animation == null)
+					Initialize();
+				#endif
+
+				return animation;
+			}
+		}
+
+		public void Initialize () {
+			if (skeletonDataAsset == null) return;
+			this.animation = skeletonDataAsset.GetSkeletonData(AnimationReferenceAsset.QuietSkeletonData).FindAnimation(animationName);
+			if (this.animation == null) Debug.LogWarningFormat("Animation '{0}' not found in SkeletonData : {1}.", animationName, skeletonDataAsset.name);
+		}
+		
+		public static implicit operator Animation (AnimationReferenceAsset asset) {
+			return asset.Animation;
+		}
+	}
+}

+ 12 - 0
spine-unity/Assets/spine-unity/Asset Types/AnimationReferenceAsset.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 6e3e95a05e4c9774397eeeb7bdee8ccb
+timeCreated: 1523328498
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {fileID: 2800000, guid: 52b12ec801461494185a4d3dc66f3d1d, type: 3}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 66 - 0
spine-unity/Assets/spine-unity/Asset Types/EventDataReferenceAsset.cs

@@ -0,0 +1,66 @@
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#define AUTOINIT_SPINEREFERENCE
+
+using UnityEngine;
+
+namespace Spine.Unity {
+	[CreateAssetMenu(menuName = "Spine/EventData Reference Asset")]
+	public class EventDataReferenceAsset : ScriptableObject {
+		const bool QuietSkeletonData = true;
+
+		[SerializeField] protected SkeletonDataAsset skeletonDataAsset;
+		[SerializeField, SpineEvent(dataField: "skeletonDataAsset")] protected string eventName;
+
+		EventData eventData;
+		public EventData EventData {
+			get {
+				#if AUTOINIT_SPINEREFERENCE
+				if (eventData == null)
+					Initialize();
+				#endif
+				return eventData;
+			}
+		}
+
+		public void Initialize () {
+			if (skeletonDataAsset == null)
+				return;
+			this.eventData = skeletonDataAsset.GetSkeletonData(EventDataReferenceAsset.QuietSkeletonData).FindEvent(eventName);
+			if (this.eventData == null)
+				Debug.LogWarningFormat("Event Data '{0}' not found in SkeletonData : {1}.", eventName, skeletonDataAsset.name);
+		}
+
+		public static implicit operator EventData (EventDataReferenceAsset asset) {
+			return asset.EventData;
+		}
+	}
+}

+ 12 - 0
spine-unity/Assets/spine-unity/Asset Types/EventDataReferenceAsset.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 8e60be42c1473144db0fd3337c25b500
+timeCreated: 1523330891
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {fileID: 2800000, guid: d226a80acc775714aa78b85e16a00e9b, type: 3}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 0 - 16
spine-unity/Assets/spine-unity/Components/SkeletonAnimator.cs

@@ -28,10 +28,6 @@
  * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-#if UNITY_5_6_OR_NEWER
-#define UNITY_CLIPINFOCACHE
-#endif
-
 using UnityEngine;
 using System.Collections.Generic;
 
@@ -118,10 +114,8 @@ namespace Spine.Unity {
 			readonly Dictionary<int, Spine.Animation> animationTable = new Dictionary<int, Spine.Animation>(IntEqualityComparer.Instance);
 			readonly Dictionary<AnimationClip, int> clipNameHashCodeTable = new Dictionary<AnimationClip, int>(AnimationClipEqualityComparer.Instance);
 			readonly List<Animation> previousAnimations = new List<Animation>();
-			#if UNITY_CLIPINFOCACHE
 			readonly List<AnimatorClipInfo> clipInfoCache = new List<AnimatorClipInfo>();
 			readonly List<AnimatorClipInfo> nextClipInfoCache = new List<AnimatorClipInfo>();
-			#endif
 
 			Animator animator;
 			public Animator Animator { get { return this.animator; } }
@@ -137,10 +131,8 @@ namespace Spine.Unity {
 					animationTable.Add(a.Name.GetHashCode(), a);
 
 				clipNameHashCodeTable.Clear();
-				#if UNITY_CLIPINFOCACHE
 				clipInfoCache.Clear();
 				nextClipInfoCache.Clear();
-				#endif
 			}
 
 			public void Apply (Skeleton skeleton) {
@@ -265,7 +257,6 @@ namespace Spine.Unity {
 				out int nextClipInfoCount,
 				out IList<AnimatorClipInfo> clipInfo,
 				out IList<AnimatorClipInfo> nextClipInfo) {
-				#if UNITY_CLIPINFOCACHE
 				clipInfoCount = animator.GetCurrentAnimatorClipInfoCount(layer);
 				nextClipInfoCount = animator.GetNextAnimatorClipInfoCount(layer);
 				if (clipInfoCache.Capacity < clipInfoCount) clipInfoCache.Capacity = clipInfoCount;
@@ -275,13 +266,6 @@ namespace Spine.Unity {
 
 				clipInfo = clipInfoCache;
 				nextClipInfo = nextClipInfoCache;
-				#else
-				clipInfo = animator.GetCurrentAnimatorClipInfo(layer);
-				nextClipInfo = animator.GetNextAnimatorClipInfo(layer);
-
-				clipInfoCount = clipInfo.Count;
-				nextClipInfoCount = nextClipInfo.Count;
-				#endif
 			}
 
 			int NameHashCode (AnimationClip clip) {

+ 159 - 0
spine-unity/Assets/spine-unity/Editor/AnimationReferenceAssetEditor.cs

@@ -0,0 +1,159 @@
+/******************************************************************************
+ * Spine Runtimes Software License v2.5
+ *
+ * Copyright (c) 2013-2016, Esoteric Software
+ * All rights reserved.
+ *
+ * You are granted a perpetual, non-exclusive, non-sublicensable, and
+ * non-transferable license to use, install, execute, and perform the Spine
+ * Runtimes software and derivative works solely for personal or internal
+ * use. Without the written permission of Esoteric Software (see Section 2 of
+ * the Spine Software License Agreement), you may not (a) modify, translate,
+ * adapt, or develop new applications using the Spine Runtimes or otherwise
+ * create derivative works or improvements of the Spine Runtimes or (b) remove,
+ * delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+ * or other intellectual property or proprietary rights notices on or in the
+ * Software, including any copy thereof. Redistributions in binary or source
+ * form must include this license and terms.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+ * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+
+using System.Reflection;
+
+namespace Spine.Unity.Editor {
+	using Editor = UnityEditor.Editor;
+
+	[CustomEditor(typeof(AnimationReferenceAsset))]
+	public class AnimationReferenceAssetEditor : Editor {
+
+		const string InspectorHelpText = "This is a Spine-Unity Animation Reference Asset. It serializes a reference to a SkeletonDataAsset and an animationName. It does not contain actual animation data. At runtime, it stores a reference to a Spine.Animation.\n\n" +
+				"You can use this in your AnimationState calls instead of a string animation name or a Spine.Animation reference. Use its implicit conversion into Spine.Animation or its .Animation property.\n\n" +
+				"Use AnimationReferenceAssets as an alternative to storing strings or finding animations and caching per component. This only does the lookup by string once, and allows you to store and manage animations via asset references.";
+
+		readonly SkeletonInspectorPreview preview = new SkeletonInspectorPreview();
+		FieldInfo skeletonDataAssetField = typeof(AnimationReferenceAsset).GetField("skeletonDataAsset", BindingFlags.NonPublic | BindingFlags.Instance);
+		FieldInfo nameField = typeof(AnimationReferenceAsset).GetField("animationName", BindingFlags.NonPublic | BindingFlags.Instance);
+
+		AnimationReferenceAsset ThisAnimationReferenceAsset { get { return target as AnimationReferenceAsset; } }
+		SkeletonDataAsset ThisSkeletonDataAsset { get { return skeletonDataAssetField.GetValue(ThisAnimationReferenceAsset) as SkeletonDataAsset; } }
+		string ThisAnimationName { get { return nameField.GetValue(ThisAnimationReferenceAsset) as string; } }
+
+		bool changeNextFrame = false;
+		SerializedProperty animationNameProperty;
+		SkeletonDataAsset lastSkeletonDataAsset;
+
+		void OnEnable () { HandleOnEnablePreview(); }
+		void OnDestroy () { HandleOnDestroyPreview(); }
+
+		public override void OnInspectorGUI () {
+			animationNameProperty = animationNameProperty ?? serializedObject.FindProperty("animationName");
+			string animationName = animationNameProperty.stringValue;
+			Animation animation = ThisSkeletonDataAsset.GetSkeletonData(true).FindAnimation(animationName);
+			bool animationNotFound = animation == null;
+
+			if (changeNextFrame) {
+				changeNextFrame = false;
+				
+				if (ThisSkeletonDataAsset != lastSkeletonDataAsset) {
+					preview.Clear();
+					preview.Initialize(Repaint, ThisSkeletonDataAsset, LastSkinName);
+
+					if (animationNotFound) {
+						animationNameProperty.stringValue = "";
+						preview.ClearAnimationSetupPose();
+					}
+				}
+
+				preview.ClearAnimationSetupPose();
+
+				if (!string.IsNullOrEmpty(animationNameProperty.stringValue))
+					preview.PlayPauseAnimation(animationNameProperty.stringValue, true);
+			}
+			lastSkeletonDataAsset = ThisSkeletonDataAsset;
+
+			//EditorGUILayout.HelpBox(AnimationReferenceAssetEditor.InspectorHelpText, MessageType.Info, true);
+			EditorGUILayout.Space();
+			EditorGUI.BeginChangeCheck();
+			DrawDefaultInspector();
+			if (EditorGUI.EndChangeCheck()) {
+				changeNextFrame = true;
+			}
+
+			// Draw extra info below default inspector.
+			EditorGUILayout.Space();
+			if (ThisSkeletonDataAsset == null) {
+				EditorGUILayout.HelpBox("SkeletonDataAsset is missing.", MessageType.Error);
+			} else if (string.IsNullOrEmpty(animationName)) {
+				EditorGUILayout.HelpBox("No animation selected.", MessageType.Warning);
+			} else if (animationNotFound) {
+				EditorGUILayout.HelpBox(string.Format("Animation named {0} was not found for this Skeleton.", animationNameProperty.stringValue), MessageType.Warning);
+			} else {
+				using (new SpineInspectorUtility.BoxScope()) {
+					if (!string.Equals(SpineEditorUtilities.GetPathSafeName(animationName), ThisAnimationReferenceAsset.name, System.StringComparison.OrdinalIgnoreCase))
+						EditorGUILayout.HelpBox("Animation name value does not match this asset's name. Inspectors using this asset may be misleading.", MessageType.None);
+
+					EditorGUILayout.LabelField(SpineInspectorUtility.TempContent(animationName, SpineEditorUtilities.Icons.animation));
+					if (animation != null) {
+						EditorGUILayout.LabelField(string.Format("Timelines: {0}", animation.Timelines.Count));
+						EditorGUILayout.LabelField(string.Format("Duration: {0} sec", animation.Duration));
+					}
+				}
+			}
+		}
+
+		#region Preview Handlers
+		string TargetAssetGUID { get { return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(ThisSkeletonDataAsset)); } }
+		string LastSkinKey { get { return TargetAssetGUID + "_lastSkin"; } }
+		string LastSkinName { get { return EditorPrefs.GetString(LastSkinKey, ""); } }
+
+		void HandleOnEnablePreview () {
+			preview.Initialize(this.Repaint, ThisSkeletonDataAsset, LastSkinName);
+			preview.PlayPauseAnimation(ThisAnimationName, true);
+			preview.OnSkinChanged -= HandleOnSkinChanged;
+			preview.OnSkinChanged += HandleOnSkinChanged;
+			EditorApplication.update -= preview.HandleEditorUpdate;
+			EditorApplication.update += preview.HandleEditorUpdate;
+		}
+
+		private void HandleOnSkinChanged (string skinName) {
+			EditorPrefs.SetString(LastSkinKey, skinName);
+			preview.PlayPauseAnimation(ThisAnimationName, true);
+		}
+
+		void HandleOnDestroyPreview () {
+			EditorApplication.update -= preview.HandleEditorUpdate;
+			preview.OnDestroy();
+		}
+
+		override public bool HasPreviewGUI () {
+			if (serializedObject.isEditingMultipleObjects) return false;
+			return ThisSkeletonDataAsset != null && ThisSkeletonDataAsset.GetSkeletonData(true) != null;
+		}
+
+		override public void OnInteractivePreviewGUI (Rect r, GUIStyle background) {
+			preview.Initialize(this.Repaint, ThisSkeletonDataAsset);
+			preview.HandleInteractivePreviewGUI(r, background);
+		}
+
+		public override GUIContent GetPreviewTitle () { return SpineInspectorUtility.TempContent("Preview"); }
+		public override void OnPreviewSettings () { preview.HandleDrawSettings(); }
+		public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) { return preview.GetStaticPreview(width, height); }
+		#endregion
+	}
+
+}

+ 12 - 0
spine-unity/Assets/spine-unity/Editor/AnimationReferenceAssetEditor.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 9511532e80feed24881a5863f5485446
+timeCreated: 1523316585
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 2 - 2
spine-unity/Assets/spine-unity/Editor/SkeletonBaker.cs

@@ -543,7 +543,7 @@ namespace Spine.Unity.Editor {
 			Vector3[] verts = ExtractVerts(floatVerts);
 
 			int[] triangles = attachment.Triangles;
-			Color color = new Color(attachment.R, attachment.G, attachment.B, attachment.A);
+			Color color = attachment.GetColor();
 
 			if (mesh == null)
 				mesh = new Mesh();
@@ -596,7 +596,7 @@ namespace Spine.Unity.Editor {
 		}
 
 		internal static Mesh ExtractWeightedMeshAttachment (string name, MeshAttachment attachment, int slotIndex, SkeletonData skeletonData, List<Transform> boneList, Mesh mesh = null) {
-			if (attachment.Bones == null)
+			if (!attachment.IsWeighted())
 				throw new System.ArgumentException("Mesh is not weighted.", "attachment");
 
 			Skeleton skeleton = new Skeleton(skeletonData);

+ 51 - 27
spine-unity/Assets/spine-unity/Editor/SkeletonBakingWindow.cs

@@ -44,17 +44,24 @@ namespace Spine.Unity.Editor {
 			EditorGUIUtility.wideMode = true;
 			EditorGUILayout.LabelField("Spine Skeleton Prefab Baking", EditorStyles.boldLabel);
 
-			const string BakingWarningMessage = "\nThe main use of Baking is to export Spine projects to be used without the Spine Runtime (ie: for sale on the Asset Store, or background objects that are animated only with a wind noise generator)" +
+			const string BakingWarningMessage = "\nSkeleton baking is not the primary use case for Spine skeletons." +
+				"\nUse baking if you have specialized uses, such as simplified skeletons with movement driven by physics." +
 
-				"\n\nBaking does not support the following:" +
-				"\n\tDisabled transform inheritance" +
-				"\n\tShear" +
+				"\n\nBaked Skeletons do not support the following:" +
+				"\n\tDisabled rotation or scale inheritance" +
+				"\n\tLocal Shear" +
+				"\n\tAll Constraint types" +
+				"\n\tWeighted mesh verts with more than 4 bound bones" +
+			
+				"\n\nBaked Animations do not support the following:" +
+				"\n\tMesh Deform Keys" +
 				"\n\tColor Keys" +
 				"\n\tDraw Order Keys" +
-				"\n\tAll Constraint types" +
 
-				"\n\nCurves are sampled at 60fps and are not realtime." +
-				"\nPlease read SkeletonBaker.cs comments for full details.\n";
+				"\n\nAnimation Curves are sampled at 60fps and are not realtime." +
+				"\nConstraint animations are also baked into animation curves." +
+				"\nSee SkeletonBaker.cs comments for full details.\n";
+
 			EditorGUILayout.HelpBox(BakingWarningMessage, MessageType.Info, true);
 
 			EditorGUI.BeginChangeCheck();
@@ -69,52 +76,69 @@ namespace Spine.Unity.Editor {
 			if (skeletonDataAsset == null) return;
 			var skeletonData = skeletonDataAsset.GetSkeletonData(false);
 			if (skeletonData == null) return;
+			bool hasExtraSkins = skeletonData.Skins.Count > 1;
 
 			using (new SpineInspectorUtility.BoxScope(false)) {
 				EditorGUILayout.LabelField(skeletonDataAsset.name, EditorStyles.boldLabel);
 				using (new SpineInspectorUtility.IndentScope()) {
 					EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Bones: " + skeletonData.Bones.Count, Icons.bone));
+					EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Slots: " + skeletonData.Slots.Count, Icons.slotRoot));
 
-					int totalAttachments = 0;
-					foreach (var s in skeletonData.Skins) totalAttachments += s.Attachments.Count;
+					if (hasExtraSkins) {
+						EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Skins: " + skeletonData.Skins.Count, Icons.skinsRoot));
+						EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Current skin attachments: " + (bakeSkin == null ? 0 : bakeSkin.Attachments.Count), Icons.skinPlaceholder));
+					} else if (skeletonData.Skins.Count == 1) {
+						EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Skins: 1 (only default Skin)", Icons.skinsRoot));
+					}
 
+					int totalAttachments = 0;
+					foreach (var s in skeletonData.Skins)
+						totalAttachments += s.Attachments.Count;
 					EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Total Attachments: " + totalAttachments, Icons.genericAttachment));
-					EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Current skin attachments: " + (bakeSkin == null ? 0 : bakeSkin.Attachments.Count), Icons.skinPlaceholder));
-					EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Animations: " + skeletonData.Animations.Count, Icons.animation));
 				}
 			}
 			using (new SpineInspectorUtility.BoxScope(false)) {
-				EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel);
+				EditorGUILayout.LabelField("Animations", EditorStyles.boldLabel);
+				EditorGUILayout.LabelField(SpineInspectorUtility.TempContent("Animations: " + skeletonData.Animations.Count, Icons.animation));
+
 				using (new SpineInspectorUtility.IndentScope()) {
 					bakeAnimations = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Bake Animations", Icons.animationRoot), bakeAnimations);
-					bakeIK = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Bake IK", Icons.constraintIK), bakeIK);
-					bakeEventOptions = (SendMessageOptions)EditorGUILayout.EnumPopup(SpineInspectorUtility.TempContent("Event Options", Icons.userEvent), bakeEventOptions);
+					using (new EditorGUI.DisabledScope(!bakeAnimations)) {
+						using (new SpineInspectorUtility.IndentScope()) {
+							bakeIK = EditorGUILayout.Toggle(SpineInspectorUtility.TempContent("Bake IK", Icons.constraintIK), bakeIK);
+							bakeEventOptions = (SendMessageOptions)EditorGUILayout.EnumPopup(SpineInspectorUtility.TempContent("Event Options", Icons.userEvent), bakeEventOptions);
+						}
+					}
 				}
 			}
 			EditorGUILayout.Space();
-
-			EditorGUI.BeginChangeCheck();
-			EditorGUILayout.PropertyField(so.FindProperty("skinToBake"));
-			if (EditorGUI.EndChangeCheck()) {
-				so.ApplyModifiedProperties();
-				Repaint();
-			}
-
+			
 			if (!string.IsNullOrEmpty(skinToBake) && UnityEngine.Event.current.type == EventType.Repaint)
 				bakeSkin = skeletonData.FindSkin(skinToBake) ?? skeletonData.DefaultSkin;
 			
 			var prefabIcon = EditorGUIUtility.FindTexture("PrefabModel Icon");
 
-			if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent(string.Format("Bake Skin ({0})", (bakeSkin == null ? "default" : bakeSkin.Name)), prefabIcon))) {
-				SkeletonBaker.BakeToPrefab(skeletonDataAsset, new ExposedList<Skin>(new [] { bakeSkin }), "", bakeAnimations, bakeIK, bakeEventOptions);
-			}
+			if (hasExtraSkins) {
+				EditorGUI.BeginChangeCheck();
+				EditorGUILayout.PropertyField(so.FindProperty("skinToBake"));
+				if (EditorGUI.EndChangeCheck()) {
+					so.ApplyModifiedProperties();
+					Repaint();
+				}
 
+				if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent(string.Format("Bake Skeleton with Skin ({0})", (bakeSkin == null ? "default" : bakeSkin.Name)), prefabIcon))) {
+					SkeletonBaker.BakeToPrefab(skeletonDataAsset, new ExposedList<Skin>(new[] { bakeSkin }), "", bakeAnimations, bakeIK, bakeEventOptions);
+				}
 
-			if (skeletonData.Skins.Count > 1) {
 				if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent(string.Format("Bake All ({0} skins)", skeletonData.Skins.Count), prefabIcon))) {
 					SkeletonBaker.BakeToPrefab(skeletonDataAsset, skeletonData.Skins, "", bakeAnimations, bakeIK, bakeEventOptions);
 				}
-			}
+			} else {
+				if (SpineInspectorUtility.LargeCenteredButton(SpineInspectorUtility.TempContent("Bake Skeleton", prefabIcon))) {
+					SkeletonBaker.BakeToPrefab(skeletonDataAsset, new ExposedList<Skin>(new[] { bakeSkin }), "", bakeAnimations, bakeIK, bakeEventOptions);
+				}
+				
+			}			
 
 		}
 	}

+ 138 - 59
spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs

@@ -31,9 +31,12 @@
 #define SPINE_SKELETON_ANIMATOR
 
 using System;
+using System.Reflection;
 using System.Collections.Generic;
 using UnityEditor;
 using UnityEngine;
+
+
 using Spine;
 
 namespace Spine.Unity.Editor {
@@ -60,7 +63,6 @@ namespace Spine.Unity.Editor {
 
 		SkeletonDataAsset targetSkeletonDataAsset;
 		SkeletonData targetSkeletonData;
-		string targetSkeletonDataAssetGUIDString;
 
 		readonly List<string> warnings = new List<string>();
 		readonly SkeletonInspectorPreview preview = new SkeletonInspectorPreview();
@@ -68,17 +70,21 @@ namespace Spine.Unity.Editor {
 		GUIStyle activePlayButtonStyle, idlePlayButtonStyle;
 		readonly GUIContent DefaultMixLabel = new GUIContent("Default Mix Duration", "Sets 'SkeletonDataAsset.defaultMix' in the asset and 'AnimationState.data.defaultMix' at runtime load time.");
 
-		string LastSkinKey { get { return targetSkeletonDataAssetGUIDString + "_lastSkin"; } }
+		string TargetAssetGUID { get { return AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(targetSkeletonDataAsset)); } }
+		string LastSkinKey { get { return TargetAssetGUID + "_lastSkin"; } }
 		string LastSkinName { get { return EditorPrefs.GetString(LastSkinKey, ""); } }
 
 		void OnEnable () {
 			InitializeEditor();
 		}
 
+		void OnDestroy () {
+			HandleOnDestroyPreview();
+		}
+
 		void InitializeEditor () {
 			SpineEditorUtilities.ConfirmInitialization();
 			targetSkeletonDataAsset = (SkeletonDataAsset)target;
-			targetSkeletonDataAssetGUIDString = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(targetSkeletonDataAsset));
 
 			bool newAtlasAssets = atlasAssets == null;
 			if (newAtlasAssets) atlasAssets = serializedObject.FindProperty("atlasAssets");
@@ -101,8 +107,8 @@ namespace Spine.Unity.Editor {
 			if (newAtlasAssets) atlasAssets.isExpanded = true;
 			#endif
 
-			EditorApplication.update -= EditorUpdate;
-			EditorApplication.update += EditorUpdate;
+			EditorApplication.update -= preview.HandleEditorUpdate;
+			EditorApplication.update += preview.HandleEditorUpdate;
 			preview.OnSkinChanged -= HandlePreviewSkinChanged;
 			preview.OnSkinChanged += HandlePreviewSkinChanged;
 
@@ -115,23 +121,11 @@ namespace Spine.Unity.Editor {
 			targetSkeletonData = warnings.Count == 0 ? targetSkeletonDataAsset.GetSkeletonData(false) : null;
 
 			if (targetSkeletonData != null && warnings.Count <= 0) {
-				preview.Initialize(targetSkeletonDataAsset, this.LastSkinName);
+				preview.Initialize(this.Repaint, targetSkeletonDataAsset, this.LastSkinName);
 			}
 				
 		}
 
-		void EditorUpdate () {
-			preview.AdjustCamera();
-
-			if (preview.IsPlayingAnimation) {
-				preview.RefreshOnNextUpdate();
-				Repaint();
-			} else if (preview.requiresRefresh) {
-				Repaint();
-			} // else // needed if using smooth menus
-
-		}
-
 		void Clear () {
 			preview.Clear();
 			targetSkeletonDataAsset.Clear();
@@ -180,7 +174,7 @@ namespace Spine.Unity.Editor {
 
 			// Unity Quirk: Some code depends on valid preview. If preview is initialized elsewhere, this can cause contents to change between Layout and Repaint events, causing GUILayout control count errors.
 			if (warnings.Count <= 0)
-				preview.Initialize(targetSkeletonDataAsset, this.LastSkinName);
+				preview.Initialize(this.Repaint, targetSkeletonDataAsset, this.LastSkinName);
 
 			if (targetSkeletonData != null) {
 				GUILayout.Space(20f);
@@ -193,6 +187,13 @@ namespace Spine.Unity.Editor {
 
 				EditorGUILayout.LabelField("Preview", EditorStyles.boldLabel);
 				DrawAnimationList();
+				if (targetSkeletonData.Animations.Count > 0) {
+					const string AnimationReferenceButtonText = "Create Animation Reference Assets";
+					const string AnimationReferenceTooltipText = "AnimationReferenceAsset acts as Unity asset for a reference to a Spine.Animation. This can be used in inspectors.\n\nIt serializes  a reference to a SkeletonDataAsset and an animationName.\n\nAt runtime, a reference to its Spine.Animation is loaded and cached into the object to be used as needed. This skips the need to find and cache animation references in individual MonoBehaviours.";
+					if (GUILayout.Button(SpineInspectorUtility.TempContent(AnimationReferenceButtonText, Icons.animationRoot, AnimationReferenceTooltipText), GUILayout.Width(250), GUILayout.Height(26))) {
+						CreateAnimationReferenceAssets();
+					}
+				}
 				EditorGUILayout.Space();
 				DrawSlotList();
 				EditorGUILayout.Space();
@@ -217,6 +218,28 @@ namespace Spine.Unity.Editor {
 				serializedObject.ApplyModifiedProperties();
 		}
 
+		void CreateAnimationReferenceAssets () {
+			const string AssetFolderName = "ReferenceAssets";
+			string parentFolder = AssetDatabase.GetAssetPath(targetSkeletonDataAsset);
+			string dataPath = System.IO.Path.GetDirectoryName(parentFolder) + "/" + AssetFolderName;
+			if (!AssetDatabase.IsValidFolder(dataPath)) {
+				AssetDatabase.CreateFolder(parentFolder, AssetFolderName);
+			}
+
+			FieldInfo nameField = typeof(AnimationReferenceAsset).GetField("animationName", BindingFlags.NonPublic | BindingFlags.Instance);
+			FieldInfo skeletonDataAssetField = typeof(AnimationReferenceAsset).GetField("skeletonDataAsset", BindingFlags.NonPublic | BindingFlags.Instance);
+			foreach (var animation in targetSkeletonData.Animations) {
+				string assetPath = string.Format("{0}/{1}.asset", dataPath, SpineEditorUtilities.GetPathSafeName(animation.Name));
+				AnimationReferenceAsset existingAsset = AssetDatabase.LoadAssetAtPath<AnimationReferenceAsset>(assetPath);
+				if (existingAsset == null) {
+					AnimationReferenceAsset newAsset = ScriptableObject.CreateInstance<AnimationReferenceAsset>();
+					skeletonDataAssetField.SetValue(newAsset, targetSkeletonDataAsset);
+					nameField.SetValue(newAsset, animation.Name);
+					AssetDatabase.CreateAsset(newAsset, assetPath);
+				}
+			}
+		}
+
 		void OnInspectorGUIMulti () {
 			
 			// Skeleton data file field.
@@ -359,7 +382,7 @@ namespace Spine.Unity.Editor {
 				return;
 
 			bool isPreviewWindowOpen = preview.IsValid;
-
+			
 			if (isPreviewWindowOpen) {
 				if (GUILayout.Button(SpineInspectorUtility.TempContent("Setup Pose", Icons.skeleton), GUILayout.Width(105), GUILayout.Height(18))) {
 					preview.ClearAnimationSetupPose();
@@ -500,7 +523,7 @@ namespace Spine.Unity.Editor {
 				warnings.Add("Missing Skeleton JSON");
 			} else {
 				var fieldValue = (TextAsset)skeletonJSON.objectReferenceValue;
-				if (!SpineEditorUtilities.IsSpineData(fieldValue)) {
+				if (!SpineEditorUtilities.SkeletonDataFileValidator.IsSpineData(fieldValue)) {
 					warnings.Add("Skeleton data file is not a valid JSON or binary file.");
 				} else {
 					#if SPINE_TK2D
@@ -571,12 +594,12 @@ namespace Spine.Unity.Editor {
 			EditorPrefs.SetString(LastSkinKey, skinName);
 		}
 
-		void OnDestroy () {
-			EditorApplication.update -= EditorUpdate;
+		#region Preview Handlers
+		void HandleOnDestroyPreview () {
+			EditorApplication.update -= preview.HandleEditorUpdate;
 			preview.OnDestroy();
 		}
 
-		#region Preview Handlers
 		override public bool HasPreviewGUI () {			
 			if (serializedObject.isEditingMultipleObjects)
 				return false;
@@ -590,37 +613,20 @@ namespace Spine.Unity.Editor {
 			return skeletonJSON.objectReferenceValue != null;
 		}
 
-		override public GUIContent GetPreviewTitle () {
-			return SpineInspectorUtility.TempContent("Preview");
-		}
-
 		override public void OnInteractivePreviewGUI (Rect r, GUIStyle background) {
 			if (warnings.Count <= 0) {
-				preview.Initialize(targetSkeletonDataAsset, this.LastSkinName);
+				preview.Initialize(this.Repaint, targetSkeletonDataAsset, this.LastSkinName);
 				preview.HandleInteractivePreviewGUI(r, background);
 			}
 		}
 
-		public override void OnPreviewSettings () {
-			const float SliderWidth = 150;
-			const float SliderSnap = 0.25f;
-			const float SliderMin = 0f;
-			const float SliderMax = 2f;
-
-			if (preview.IsValid) {
-				float timeScale = GUILayout.HorizontalSlider(preview.TimeScale, SliderMin, SliderMax, GUILayout.MaxWidth(SliderWidth));
-				timeScale = Mathf.RoundToInt(timeScale/SliderSnap) * SliderSnap;
-				preview.TimeScale = timeScale;
-			}
-		}
-
-		public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) {
-			return preview.GetStaticPreview(width, height);
-		}
+		override public GUIContent GetPreviewTitle () { return SpineInspectorUtility.TempContent("Preview"); }
+		public override void OnPreviewSettings () { preview.HandleDrawSettings(); }
+		public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height) { return preview.GetStaticPreview(width, height); }
 		#endregion
 	}
 
-	class SkeletonInspectorPreview {
+	internal class SkeletonInspectorPreview {
 		Color OriginColor = new Color(0.3f, 0.3f, 0.3f, 1);
 		static readonly int SliderHash = "Slider".GetHashCode();
 
@@ -632,17 +638,14 @@ namespace Spine.Unity.Editor {
 		internal bool requiresRefresh;
 		float animationLastTime;
 
+		Action Repaint;
 		public event Action<string> OnSkinChanged;
 
 		Texture previewTexture;
 		PreviewRenderUtility previewRenderUtility;
 		Camera PreviewUtilityCamera {
 			get {
-				if (previewRenderUtility == null) {
-
-					return null;
-				}
-
+				if (previewRenderUtility == null) return null;
 				#if UNITY_2017_1_OR_NEWER
 				return previewRenderUtility.camera;
 				#else
@@ -651,6 +654,8 @@ namespace Spine.Unity.Editor {
 			}
 		}
 
+		static Vector3 lastCameraPositionGoal;
+		static float lastCameraOrthoGoal;
 		float cameraOrthoGoal = 1;
 		Vector3 cameraPositionGoal = new Vector3(0, 0, -10);
 		double cameraAdjustEndFrame = 0;
@@ -679,14 +684,27 @@ namespace Spine.Unity.Editor {
 			get { return IsValid ? skeletonAnimation.AnimationState.GetCurrent(0) : null; }
 		}
 
-		public void Initialize (SkeletonDataAsset skeletonDataAsset, string skinName = "") {
+		public Vector3 PreviewCameraPosition {
+			get { return PreviewUtilityCamera.transform.position; }
+			set { PreviewUtilityCamera.transform.position = value; }
+		}
+
+		public void Initialize (Action repaintCallback, SkeletonDataAsset skeletonDataAsset, string skinName = "") {
 			if (skeletonDataAsset == null) return;
-			if (skeletonDataAsset.GetSkeletonData(false) == null)
+			if (skeletonDataAsset.GetSkeletonData(false) == null) {
+				DestroyPreviewGameObject();
 				return;
+			}
 
+			this.Repaint = repaintCallback;
 			this.skeletonDataAsset = skeletonDataAsset;
 			this.skeletonData = skeletonDataAsset.GetSkeletonData(false);
 
+			if (skeletonData == null) {
+				DestroyPreviewGameObject();
+				return;
+			}
+
 			if (previewRenderUtility == null) {
 				previewRenderUtility = new PreviewRenderUtility(true);
 				animationLastTime = Time.realtimeSinceStartup;
@@ -697,10 +715,11 @@ namespace Spine.Unity.Editor {
 				{
 					var c = this.PreviewUtilityCamera;
 					c.orthographic = true;
-					c.orthographicSize = 1;
 					c.cullingMask = PreviewCameraCullingMask;
 					c.nearClipPlane = 0.01f;
-					c.farClipPlane = 1000f;	
+					c.farClipPlane = 1000f;
+					c.orthographicSize = lastCameraOrthoGoal;
+					c.transform.position = lastCameraPositionGoal;
 				}
 
 				DestroyPreviewGameObject();
@@ -727,6 +746,19 @@ namespace Spine.Unity.Editor {
 			}
 		}
 
+		public void HandleDrawSettings () {
+			const float SliderWidth = 150;
+			const float SliderSnap = 0.25f;
+			const float SliderMin = 0f;
+			const float SliderMax = 2f;
+
+			if (IsValid) {
+				float timeScale = GUILayout.HorizontalSlider(TimeScale, SliderMin, SliderMax, GUILayout.MaxWidth(SliderWidth));
+				timeScale = Mathf.RoundToInt(timeScale / SliderSnap) * SliderSnap;
+				TimeScale = timeScale;
+			}
+		}
+
 		public void OnDestroy () {
 			DisposePreviewRenderUtility();
 			DestroyPreviewGameObject();
@@ -765,8 +797,19 @@ namespace Spine.Unity.Editor {
 		}
 
 		public void PlayPauseAnimation (string animationName, bool loop) {
+			if (skeletonData == null) return;
+
 			if (skeletonAnimation == null) {
-				Debug.LogWarning("Animation was stopped but preview doesn't exist. It's possible that the Preview Panel is closed.");
+				//Debug.LogWarning("Animation was stopped but preview doesn't exist. It's possible that the Preview Panel is closed.");
+				return;
+			}
+
+			if (!skeletonAnimation.valid) return;
+
+			if (string.IsNullOrEmpty(animationName)) {
+				skeletonAnimation.Skeleton.SetToSetupPose();
+				skeletonAnimation.AnimationState.ClearTracks();
+				return;
 			}
 
 			var targetAnimation = skeletonData.FindAnimation(animationName);
@@ -805,7 +848,7 @@ namespace Spine.Unity.Editor {
 					}
 				}
 			} else {
-				Debug.LogFormat("Something went wrong. The Spine.Animation named '{0}' was not found.", animationName);
+				Debug.LogFormat("The Spine.Animation named '{0}' was not found for this Skeleton.", animationName);
 			}
 
 		}
@@ -823,6 +866,7 @@ namespace Spine.Unity.Editor {
 			}
 
 			DrawSkinToolbar(r);
+			//DrawSetupPoseButton(r);
 			DrawTimeBar(r);
 			MouseScroll(r);
 		}
@@ -848,13 +892,16 @@ namespace Spine.Unity.Editor {
 			if (EditorApplication.timeSinceStartup < cameraAdjustEndFrame)
 				AdjustCameraGoals();
 
+			lastCameraPositionGoal = cameraPositionGoal;
+			lastCameraOrthoGoal = cameraOrthoGoal;
+
 			var c = this.PreviewUtilityCamera;
 			float orthoSet = Mathf.Lerp(c.orthographicSize, cameraOrthoGoal, 0.1f);
 
 			c.orthographicSize = orthoSet;
 
 			float dist = Vector3.Distance(c.transform.position, cameraPositionGoal);
-			if(dist > 0f) {
+			if (dist > 0f) {
 				Vector3 pos = Vector3.Lerp(c.transform.position, cameraPositionGoal, 0.1f);
 				pos.x = 0;
 				c.transform.position = pos;
@@ -877,6 +924,16 @@ namespace Spine.Unity.Editor {
 			return tex;
 		}
 
+		public void HandleEditorUpdate () {
+			AdjustCamera();
+			if (IsPlayingAnimation) {
+				RefreshOnNextUpdate();
+				Repaint();
+			} else if (requiresRefresh) {
+				Repaint();
+			}
+		}
+
 		public void DoRenderPreview (bool drawHandles) {
 			if (this.PreviewUtilityCamera.activeTexture == null || this.PreviewUtilityCamera.targetTexture == null )
 				return;
@@ -940,6 +997,28 @@ namespace Spine.Unity.Editor {
 			}
 		}
 
+		void DrawSetupPoseButton (Rect r) {
+			if (!this.IsValid)
+				return;
+
+			var skeleton = this.Skeleton;
+
+			Rect popRect = new Rect(r);
+			popRect.y += 64;
+			popRect.x += 4;
+			popRect.height = 24;
+			popRect.width = 40;
+
+			//popRect.y += 11;
+			popRect.width = 150;
+			//popRect.x += 44;
+
+			if (GUI.Button(popRect, SpineInspectorUtility.TempContent("Reset to SetupPose", Icons.skeleton))) {
+				ClearAnimationSetupPose();
+				RefreshOnNextUpdate();
+			}
+		}
+
 		void DrawSkinDropdown () {
 			var menu = new GenericMenu();
 			foreach (Skin s in skeletonData.Skins)
@@ -953,7 +1032,7 @@ namespace Spine.Unity.Editor {
 			skeletonAnimation.initialSkinName = skin.Name;
 			skeletonAnimation.Initialize(true);
 			RefreshOnNextUpdate();
-			OnSkinChanged(skin.Name);
+			if (OnSkinChanged != null) OnSkinChanged(skin.Name);
 		}
 
 		void DrawTimeBar (Rect r) {

+ 184 - 197
spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs

@@ -44,7 +44,7 @@ using Spine;
 
 namespace Spine.Unity.Editor {
 	using EventType = UnityEngine.EventType;
-	
+
 	// Analysis disable once ConvertToStaticType
 	[InitializeOnLoad]
 	public class SpineEditorUtilities : AssetPostprocessor {
@@ -81,9 +81,7 @@ namespace Spine.Unity.Editor {
 			public static Texture2D hingeChain;
 			public static Texture2D subMeshRenderer;
 			public static Texture2D skeletonDataAssetIcon;
-
 			public static Texture2D info;
-
 			public static Texture2D unity;
 //			public static Texture2D controllerIcon;
 
@@ -156,15 +154,13 @@ namespace Spine.Unity.Editor {
 		public static bool initialized;
 
 		/// HACK: This list keeps the asset reference temporarily during importing.
-		/// 
+		///
 		/// In cases of very large projects/sufficient RAM pressure, when AssetDatabase.SaveAssets is called,
 		/// Unity can mistakenly unload assets whose references are only on the stack.
 		/// This leads to MissingReferenceException and other errors.
 		static readonly List<ScriptableObject> protectFromStackGarbageCollection = new List<ScriptableObject>();
 		static HashSet<string> assetsImportedInWrongState = new HashSet<string>();
 
-
-
 		#if SPINE_TK2D
 		const float DEFAULT_DEFAULT_SCALE = 1f;
 		#else
@@ -189,6 +185,10 @@ namespace Spine.Unity.Editor {
 		const string SHOW_HIERARCHY_ICONS_KEY = "SPINE_SHOW_HIERARCHY_ICONS";
 		public static bool showHierarchyIcons = DEFAULT_SHOW_HIERARCHY_ICONS;
 
+		const bool DEFAULT_SET_TEXTUREIMPORTER_SETTINGS = true;
+		const string SET_TEXTUREIMPORTER_SETTINGS_KEY = "SPINE_SET_TEXTUREIMPORTER_SETTINGS";
+		public static bool setTextureImporterSettings = DEFAULT_SET_TEXTUREIMPORTER_SETTINGS;
+
 		internal const float DEFAULT_MIPMAPBIAS = -0.5f;
 
 		public const float DEFAULT_SCENE_ICONS_SCALE = 1f;
@@ -203,8 +203,9 @@ namespace Spine.Unity.Editor {
 			defaultMix = EditorPrefs.GetFloat(DEFAULT_MIX_KEY, DEFAULT_DEFAULT_MIX);
 			defaultScale = EditorPrefs.GetFloat(DEFAULT_SCALE_KEY, DEFAULT_DEFAULT_SCALE);
 			defaultZSpacing = EditorPrefs.GetFloat(DEFAULT_ZSPACING_KEY, DEFAULT_DEFAULT_ZSPACING);
-			defaultShader = EditorPrefs.GetString(DEFAULT_SHADER_KEY, DEFAULT_DEFAULT_SHADER);	
+			defaultShader = EditorPrefs.GetString(DEFAULT_SHADER_KEY, DEFAULT_DEFAULT_SHADER);
 			showHierarchyIcons = EditorPrefs.GetBool(SHOW_HIERARCHY_ICONS_KEY, DEFAULT_SHOW_HIERARCHY_ICONS);
+			setTextureImporterSettings = EditorPrefs.GetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, DEFAULT_SET_TEXTUREIMPORTER_SETTINGS);
 			SpineHandles.handleScale = EditorPrefs.GetFloat(SCENE_ICONS_SCALE_KEY, DEFAULT_SCENE_ICONS_SCALE);
 			preferencesLoaded = true;
 		}
@@ -270,7 +271,7 @@ namespace Spine.Unity.Editor {
 
 			EditorGUI.BeginChangeCheck();
 			defaultMix = EditorGUILayout.FloatField("Default Mix", defaultMix);
-			if (EditorGUI.EndChangeCheck()) 
+			if (EditorGUI.EndChangeCheck())
 				EditorPrefs.SetFloat(DEFAULT_MIX_KEY, defaultMix);
 
 			EditorGUI.BeginChangeCheck();
@@ -285,12 +286,19 @@ namespace Spine.Unity.Editor {
 				EditorPrefs.SetString(DEFAULT_SHADER_KEY, defaultShader);
 			EditorGUILayout.Space();
 
+			EditorGUI.BeginChangeCheck();
+			setTextureImporterSettings = EditorGUILayout.Toggle(new GUIContent("Apply Atlas Texture Settings", "Apply the recommended settings for Texture Importers."), showHierarchyIcons);
+			if (EditorGUI.EndChangeCheck()) {
+				EditorPrefs.SetBool(SET_TEXTUREIMPORTER_SETTINGS_KEY, showHierarchyIcons);
+				SpineEditorHierarchyHandler.HierarchyIconsOnPlaymodeStateChanged();
+			}
+
 			EditorGUILayout.LabelField("Editor Instantiation", EditorStyles.boldLabel);
 			EditorGUI.BeginChangeCheck();
 			defaultZSpacing = EditorGUILayout.Slider("Default Slot Z-Spacing", defaultZSpacing, -0.1f, 0f);
 			if (EditorGUI.EndChangeCheck())
 				EditorPrefs.SetFloat(DEFAULT_ZSPACING_KEY, defaultZSpacing);
-			
+
 
 			EditorGUILayout.Space();
 			EditorGUILayout.LabelField("Handles and Gizmos", EditorStyles.boldLabel);
@@ -301,16 +309,16 @@ namespace Spine.Unity.Editor {
 				EditorPrefs.SetFloat(SCENE_ICONS_SCALE_KEY, SpineHandles.handleScale);
 				SceneView.RepaintAll();
 			}
-				
-			
+
+
 			GUILayout.Space(20);
 			EditorGUILayout.LabelField("3rd Party Settings", EditorStyles.boldLabel);
 			using (new GUILayout.HorizontalScope()) {
 				EditorGUILayout.PrefixLabel("Define TK2D");
 				if (GUILayout.Button("Enable", GUILayout.Width(64)))
-					EnableTK2D();
+					SpineTK2DEditorUtility.EnableTK2D();
 				if (GUILayout.Button("Disable", GUILayout.Width(64)))
-					DisableTK2D();
+					SpineTK2DEditorUtility.DisableTK2D();
 			}
 		}
 		#endregion
@@ -588,7 +596,7 @@ namespace Spine.Unity.Editor {
 			// which may lead to numerous importing errors.
 			// This situation also happens if Library folder is deleted from the project, which is a pretty
 			// common case, since when using version control systems, the Library folder must be excluded.
-			// 
+			//
 			// So to avoid this, in case asset database is not available, we delay loading the assets
 			// until next time.
 			//
@@ -624,18 +632,18 @@ namespace Spine.Unity.Editor {
 					break;
 				case ".json":
 					var jsonAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(str, typeof(TextAsset));
-					if (jsonAsset != null && IsSpineData(jsonAsset))
+					if (jsonAsset != null && SkeletonDataFileValidator.IsSpineData(jsonAsset))
 						skeletonPaths.Add(str);
 					break;
 				case ".bytes":
 					if (str.ToLower().EndsWith(".skel.bytes", System.StringComparison.Ordinal)) {
-						if (IsSpineData((TextAsset)AssetDatabase.LoadAssetAtPath(str, typeof(TextAsset))))
+						if (SkeletonDataFileValidator.IsSpineData((TextAsset)AssetDatabase.LoadAssetAtPath(str, typeof(TextAsset))))
 							skeletonPaths.Add(str);
 					}
 					break;
 				}
 			}
-				
+
 			// Import atlases first.
 			var atlases = new List<AtlasAsset>();
 			foreach (string ap in atlasPaths) {
@@ -647,7 +655,7 @@ namespace Spine.Unity.Editor {
 			// Import skeletons and match them with atlases.
 			bool abortSkeletonImport = false;
 			foreach (string sp in skeletonPaths) {
-				if (!reimport && CheckForValidSkeletonData(sp)) {
+				if (!reimport && SkeletonDataFileValidator.CheckForValidSkeletonData(sp)) {
 					ReloadSkeletonData(sp);
 					continue;
 				}
@@ -770,7 +778,6 @@ namespace Spine.Unity.Editor {
 		#endregion
 
 		#region Match SkeletonData with Atlases
-		//static readonly AttachmentType[] NonAtlasTypes = { AttachmentType.Boundingbox, AttachmentType.Path };
 		static readonly AttachmentType[] AtlasTypes = { AttachmentType.Region, AttachmentType.Linkedmesh, AttachmentType.Mesh };
 
 		static List<AtlasAsset> MultiAtlasDialog (List<string> requiredPaths, string initialDirectory, string filename = "") {
@@ -806,7 +813,7 @@ namespace Spine.Unity.Editor {
 							}
 						}
 					}
-						
+
 					int n = missingRegions.Count;
 					if (n == 0) break;
 
@@ -889,7 +896,7 @@ namespace Spine.Unity.Editor {
 			var root = Json.Deserialize(reader) as Dictionary<string, object>;
 
 			if (!root.ContainsKey("skins"))
-				return requiredPaths;			
+				return requiredPaths;
 
 			foreach (KeyValuePair<string, object> entry in (Dictionary<string, object>)root["skins"]) {
 				foreach (KeyValuePair<string, object> slotEntry in (Dictionary<string, object>)entry.Value) {
@@ -908,7 +915,7 @@ namespace Spine.Unity.Editor {
 								Debug.LogWarning(string.Format("Unidentified Attachment type: \"{0}\". Skeleton may have been exported from an incompatible Spine version.", typeString));
 								throw e;
 							}
-								
+
 							if (!AtlasTypes.Contains(attachmentType))
 								continue;
 						}
@@ -1042,27 +1049,24 @@ namespace Spine.Unity.Editor {
 				string texturePath = assetPath + "/" + pageFiles[i];
 				Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D));
 
-				TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath);
-				if (texImporter == null) {
-					Debug.LogWarning(string.Format("{0} ::: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath));
-					continue;
-				}
+				if (setTextureImporterSettings) {
+					TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath);
+					if (texImporter == null) {
+						Debug.LogWarning(string.Format("{0} ::: Texture asset \"{1}\" not found. Skipping. Please check your atlas file for renamed files.", atlasAsset.name, texturePath));
+						continue;
+					}
 
-				#if UNITY_5_5_OR_NEWER
-				texImporter.textureCompression = TextureImporterCompression.Uncompressed;
-				texImporter.alphaSource = TextureImporterAlphaSource.FromInput;
-				#else
-				texImporter.textureType = TextureImporterType.Advanced;
-				texImporter.textureFormat = TextureImporterFormat.AutomaticTruecolor;
-				#endif
-				texImporter.mipmapEnabled = false;
-				texImporter.alphaIsTransparency = false; // Prevent the texture importer from applying bleed to the transparent parts.
-				texImporter.spriteImportMode = SpriteImportMode.None;
-				texImporter.maxTextureSize = 2048;
+					texImporter.textureCompression = TextureImporterCompression.Uncompressed;
+					texImporter.alphaSource = TextureImporterAlphaSource.FromInput;
+					texImporter.mipmapEnabled = false;
+					texImporter.alphaIsTransparency = false; // Prevent the texture importer from applying bleed to the transparent parts for PMA.
+					texImporter.spriteImportMode = SpriteImportMode.None;
+					texImporter.maxTextureSize = 2048;
 
-				EditorUtility.SetDirty(texImporter);
-				AssetDatabase.ImportAsset(texturePath);
-				AssetDatabase.SaveAssets();
+					EditorUtility.SetDirty(texImporter);
+					AssetDatabase.ImportAsset(texturePath);
+					AssetDatabase.SaveAssets();
+				}
 
 				string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]);
 
@@ -1116,7 +1120,7 @@ namespace Spine.Unity.Editor {
 			bool hasBakedRegions = false;
 			for (int i = 0; i < regions.Count; i++) {
 				AtlasRegion region = regions[i];
-				string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/");
+				string bakedPrefabPath = Path.Combine(bakedDirPath, SpineEditorUtilities.GetPathSafeName(region.name) + ".prefab").Replace("\\", "/");
 				GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject));
 				if (prefab != null) {
 					BakeRegion(atlasAsset, region, false);
@@ -1140,7 +1144,7 @@ namespace Spine.Unity.Editor {
 			string atlasAssetPath = AssetDatabase.GetAssetPath(atlasAsset);
 			string atlasAssetDirPath = Path.GetDirectoryName(atlasAssetPath);
 			string bakedDirPath = Path.Combine(atlasAssetDirPath, atlasAsset.name);
-			string bakedPrefabPath = Path.Combine(bakedDirPath, GetPathSafeRegionName(region) + ".prefab").Replace("\\", "/");
+			string bakedPrefabPath = Path.Combine(bakedDirPath, GetPathSafeName(region.name) + ".prefab").Replace("\\", "/");
 
 			GameObject prefab = (GameObject)AssetDatabase.LoadAssetAtPath(bakedPrefabPath, typeof(GameObject));
 			GameObject root;
@@ -1239,126 +1243,103 @@ namespace Spine.Unity.Editor {
 		}
 		#endregion
 
-		#region Checking Methods
-		static int[][] compatibleBinaryVersions = { new[] {3, 7, 0} };
-		static int[][] compatibleJsonVersions = { new[] { 3, 7, 0 }, new[] { 3, 6, 0 }, new[] { 3, 5, 0 } };
-		//static bool isFixVersionRequired = false;
-
-		static bool CheckForValidSkeletonData (string skeletonJSONPath) {
-			string dir = Path.GetDirectoryName(skeletonJSONPath);
-			TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset));
-			DirectoryInfo dirInfo = new DirectoryInfo(dir);
-			FileInfo[] files = dirInfo.GetFiles("*.asset");
+		#region SkeletonDataFileValidator
+		internal static class SkeletonDataFileValidator {
+			static int[][] compatibleBinaryVersions = { new[] { 3, 6, 0 }, new[] { 3, 5, 0 } };
+			static int[][] compatibleJsonVersions = { new[] { 3, 6, 0 }, new[] { 3, 7, 0 }, new[] { 3, 5, 0 } };
+			//static bool isFixVersionRequired = false;
+
+			public static bool CheckForValidSkeletonData (string skeletonJSONPath) {
+				string dir = Path.GetDirectoryName(skeletonJSONPath);
+				TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset));
+				DirectoryInfo dirInfo = new DirectoryInfo(dir);
+				FileInfo[] files = dirInfo.GetFiles("*.asset");
+
+				foreach (var path in files) {
+					string localPath = dir + "/" + path.Name;
+					var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object));
+					var skeletonDataAsset = obj as SkeletonDataAsset;
+					if (skeletonDataAsset != null && skeletonDataAsset.skeletonJSON == textAsset)
+						return true;
+				}
 
-			foreach (var path in files) {
-				string localPath = dir + "/" + path.Name;
-				var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object));
-				var skeletonDataAsset = obj as SkeletonDataAsset;
-				if (skeletonDataAsset != null && skeletonDataAsset.skeletonJSON == textAsset)
-					return true;
+				return false;
 			}
 
-			return false;
-		}
+			public static bool IsSpineData (TextAsset asset) {
+				if (asset == null)
+					return false;
 
-		public static bool IsSpineData (TextAsset asset) {
-			if (asset == null) return false;
+				bool isSpineData = false;
+				string rawVersion = null;
+
+				int[][] compatibleVersions;
+				if (asset.name.Contains(".skel")) {
+					try {
+						rawVersion = SkeletonBinary.GetVersionString(new MemoryStream(asset.bytes));
+						isSpineData = !(string.IsNullOrEmpty(rawVersion));
+						compatibleVersions = compatibleBinaryVersions;
+					} catch (System.Exception e) {
+						Debug.LogErrorFormat("Failed to read '{0}'. It is likely not a binary Spine SkeletonData file.\n{1}", asset.name, e);
+						return false;
+					}
+				} else {
+					object obj = Json.Deserialize(new StringReader(asset.text));
+					if (obj == null) {
+						Debug.LogErrorFormat("'{0}' is not valid JSON.", asset.name);
+						return false;
+					}
 
-			bool isSpineData = false;
-			string rawVersion = null;
+					var root = obj as Dictionary<string, object>;
+					if (root == null) {
+						Debug.LogError("Parser returned an incorrect type.");
+						return false;
+					}
 
-			int[][] compatibleVersions;
-			if (asset.name.Contains(".skel")) {
-				try {
-					rawVersion = SkeletonBinary.GetVersionString(new MemoryStream(asset.bytes));
-					isSpineData = !(string.IsNullOrEmpty(rawVersion));
-					compatibleVersions = compatibleBinaryVersions;
-				} catch (System.Exception e) {
-					Debug.LogErrorFormat("Failed to read '{0}'. It is likely not a binary Spine SkeletonData file.\n{1}", asset.name, e);
-					return false;
-				}
-			} else {
-				object obj = Json.Deserialize(new StringReader(asset.text));
-				if (obj == null) {
-					Debug.LogErrorFormat("'{0}' is not valid JSON.", asset.name);
-					return false;
-				}
+					isSpineData = root.ContainsKey("skeleton");
+					if (isSpineData) {
+						var skeletonInfo = (Dictionary<string, object>)root["skeleton"];
+						object jv;
+						skeletonInfo.TryGetValue("spine", out jv);
+						rawVersion = jv as string;
+					}
 
-				var root = obj as Dictionary<string, object>;
-				if (root == null) {
-					Debug.LogError("Parser returned an incorrect type.");
-					return false;
+					compatibleVersions = compatibleJsonVersions;
 				}
 
-				isSpineData = root.ContainsKey("skeleton");
+				// Version warning
 				if (isSpineData) {
-					var skeletonInfo = (Dictionary<string, object>)root["skeleton"];
-					object jv;
-					skeletonInfo.TryGetValue("spine", out jv);
-					rawVersion = jv as string;
-				}
-
-				compatibleVersions = compatibleJsonVersions;
-			}
+					string primaryRuntimeVersionDebugString = compatibleVersions[0][0] + "." + compatibleVersions[0][1];
 
-			// Version warning
-			if (isSpineData) {
-				string primaryRuntimeVersionDebugString = compatibleVersions[0][0] + "." + compatibleVersions[0][1];
-
-				if (string.IsNullOrEmpty(rawVersion)) {
-					Debug.LogWarningFormat("Skeleton '{0}' has no version information. It may be incompatible with your runtime version: spine-unity v{1}", asset.name, primaryRuntimeVersionDebugString);
-				} else {
-					string[] versionSplit = rawVersion.Split('.');
-					bool match = false;
-					foreach (var version in compatibleVersions) {
-						bool primaryMatch = version[0] == int.Parse(versionSplit[0]);
-						bool secondaryMatch = version[1] == int.Parse(versionSplit[1]);
+					if (string.IsNullOrEmpty(rawVersion)) {
+						Debug.LogWarningFormat("Skeleton '{0}' has no version information. It may be incompatible with your runtime version: spine-unity v{1}", asset.name, primaryRuntimeVersionDebugString);
+					} else {
+						string[] versionSplit = rawVersion.Split('.');
+						bool match = false;
+						foreach (var version in compatibleVersions) {
+							bool primaryMatch = version[0] == int.Parse(versionSplit[0]);
+							bool secondaryMatch = version[1] == int.Parse(versionSplit[1]);
 
-						// if (isFixVersionRequired) secondaryMatch &= version[2] <= int.Parse(jsonVersionSplit[2]);
+							// if (isFixVersionRequired) secondaryMatch &= version[2] <= int.Parse(jsonVersionSplit[2]);
 
-						if (primaryMatch && secondaryMatch) {
-							match = true;
-							break;
+							if (primaryMatch && secondaryMatch) {
+								match = true;
+								break;
+							}
 						}
-					}
 
-					if (!match)
-						Debug.LogWarningFormat("Skeleton '{0}' (exported with Spine {1}) may be incompatible with your runtime version: spine-unity v{2}", asset.name, rawVersion, primaryRuntimeVersionDebugString);
+						if (!match)
+							Debug.LogWarningFormat("Skeleton '{0}' (exported with Spine {1}) may be incompatible with your runtime version: spine-unity v{2}", asset.name, rawVersion, primaryRuntimeVersionDebugString);
+					}
 				}
-			}
 
-			return isSpineData;
+				return isSpineData;
+			}
 		}
+
 		#endregion
 
 		#region SkeletonAnimation Menu
-//		[MenuItem("Assets/Spine/Instantiate (SkeletonAnimation)", false, 10)]
-//		static void InstantiateSkeletonAnimation () {
-//			Object[] arr = Selection.objects;
-//			foreach (Object o in arr) {
-//				string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o));
-//				string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
-//
-//				InstantiateSkeletonAnimation((SkeletonDataAsset)o, skinName, false);
-//				SceneView.RepaintAll();
-//			}
-//		}
-//
-//		[MenuItem("Assets/Spine/Instantiate (SkeletonAnimation)", true, 10)]
-//		static bool ValidateInstantiateSkeletonAnimation () {
-//			Object[] arr = Selection.objects;
-//
-//			if (arr.Length == 0)
-//				return false;
-//
-//			foreach (Object o in arr) {
-//				if (o.GetType() != typeof(SkeletonDataAsset))
-//					return false;
-//			}
-//
-//			return true;
-//		}
-
 		public static void IngestAdvancedRenderSettings (SkeletonRenderer skeletonRenderer) {
 			const string PMAShaderQuery = "Spine/Skeleton";
 			const string TintBlackShaderQuery = "Tint Black";
@@ -1501,74 +1482,80 @@ namespace Spine.Unity.Editor {
 
 			return anim;
 		}
-		#endif
+#endif
 		#endregion
 
-		#region TK2D Support
-		const string SPINE_TK2D_DEFINE = "SPINE_TK2D";
-
-		static bool IsInvalidGroup (BuildTargetGroup group) {
-			int gi = (int)group;
-			return
-				gi == 15 || gi == 16
-				||
-				group == BuildTargetGroup.Unknown;
-		}
-
-		static void EnableTK2D () {
-			bool added = false;
-			foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {				
-				if (IsInvalidGroup(group))
-					continue;
+		#region SpineTK2DEditorUtility
+		internal static class SpineTK2DEditorUtility {
+			const string SPINE_TK2D_DEFINE = "SPINE_TK2D";
+
+			static bool IsInvalidGroup (BuildTargetGroup group) {
+				int gi = (int)group;
+				return
+					gi == 15 || gi == 16
+					||
+					group == BuildTargetGroup.Unknown;
+			}
+
+			internal static void EnableTK2D () {
+				bool added = false;
+				foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
+					if (IsInvalidGroup(group))
+						continue;
+
+					string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
+					if (!defines.Contains(SPINE_TK2D_DEFINE)) {
+						added = true;
+						if (defines.EndsWith(";", System.StringComparison.Ordinal))
+							defines = defines + SPINE_TK2D_DEFINE;
+						else
+							defines = defines + ";" + SPINE_TK2D_DEFINE;
 
-				string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
-				if (!defines.Contains(SPINE_TK2D_DEFINE)) {
-					added = true;
-					if (defines.EndsWith(";", System.StringComparison.Ordinal))
-						defines = defines + SPINE_TK2D_DEFINE;
-					else
-						defines = defines + ";" + SPINE_TK2D_DEFINE;
+						PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
+					}
+				}
 
-					PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
+				if (added) {
+					Debug.LogWarning("Setting Scripting Define Symbol " + SPINE_TK2D_DEFINE);
+				} else {
+					Debug.LogWarning("Already Set Scripting Define Symbol " + SPINE_TK2D_DEFINE);
 				}
 			}
 
-			if (added) {
-				Debug.LogWarning("Setting Scripting Define Symbol " + SPINE_TK2D_DEFINE);
-			} else {
-				Debug.LogWarning("Already Set Scripting Define Symbol " + SPINE_TK2D_DEFINE);
-			}
-		}
 
+			internal static void DisableTK2D () {
+				bool removed = false;
+				foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
+					if (IsInvalidGroup(group))
+						continue;
 
-		static void DisableTK2D () {
-			bool removed = false;
-			foreach (BuildTargetGroup group in System.Enum.GetValues(typeof(BuildTargetGroup))) {
-				if (IsInvalidGroup(group))
-					continue;
-				
-				string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
-				if (defines.Contains(SPINE_TK2D_DEFINE)) {
-					removed = true;
-					if (defines.Contains(SPINE_TK2D_DEFINE + ";"))
-						defines = defines.Replace(SPINE_TK2D_DEFINE + ";", "");
-					else
-						defines = defines.Replace(SPINE_TK2D_DEFINE, "");
-
-					PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
+					string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
+					if (defines.Contains(SPINE_TK2D_DEFINE)) {
+						removed = true;
+						if (defines.Contains(SPINE_TK2D_DEFINE + ";"))
+							defines = defines.Replace(SPINE_TK2D_DEFINE + ";", "");
+						else
+							defines = defines.Replace(SPINE_TK2D_DEFINE, "");
+
+						PlayerSettings.SetScriptingDefineSymbolsForGroup(group, defines);
+					}
 				}
-			}
 
-			if (removed) {
-				Debug.LogWarning("Removing Scripting Define Symbol " + SPINE_TK2D_DEFINE);
-			} else {
-				Debug.LogWarning("Already Removed Scripting Define Symbol " + SPINE_TK2D_DEFINE);
+				if (removed) {
+					Debug.LogWarning("Removing Scripting Define Symbol " + SPINE_TK2D_DEFINE);
+				} else {
+					Debug.LogWarning("Already Removed Scripting Define Symbol " + SPINE_TK2D_DEFINE);
+				}
 			}
 		}
 		#endregion
 
-		public static string GetPathSafeRegionName (AtlasRegion region) {
-			return region.name.Replace("/", "_");
+		//public static string GetPathSafeRegionName (AtlasRegion region) {
+		//	return region.name.Replace("/", "_");
+		//}
+
+		public static string GetPathSafeName (string name) {
+			return name.Replace("/", "_");
 		}
 	}
 
@@ -1824,7 +1811,7 @@ namespace Spine.Unity.Editor {
 		}
 
 		public static void DrawDot (Vector3 position, float size) {
-			Handles.DotHandleCap(0, position, Quaternion.identity, size * HandleUtility.GetHandleSize(position), EventType.Ignore); //Handles.DotCap(0, position, Quaternion.identity, size * HandleUtility.GetHandleSize(position));			
+			Handles.DotHandleCap(0, position, Quaternion.identity, size * HandleUtility.GetHandleSize(position), EventType.Ignore); //Handles.DotCap(0, position, Quaternion.identity, size * HandleUtility.GetHandleSize(position));
 		}
 
 		public static void DrawBoundingBoxes (Transform transform, Skeleton skeleton) {
@@ -1919,7 +1906,7 @@ namespace Spine.Unity.Editor {
 							m.m03 = targetBone.WorldX * skeletonRenderScale;
 							m.m13 = targetBone.WorldY * skeletonRenderScale;
 							SpineHandles.DrawArrowhead(transform.localToWorldMatrix * m);
-							break;	
+							break;
 						}
 					case 2: {
 							Bone childBone = bones.Items[1];

+ 3 - 3
spine-unity/Assets/spine-unity/Editor/SpineInspectorUtility.cs

@@ -102,11 +102,11 @@ namespace Spine.Unity.Editor {
 					int propertyPathLength = propertyPath.Length;
 
 					int dotCount = 0;
-					const int siblingOfListDotCount = 3;
+					const int SiblingOfListDotCount = 3;
 					for (int i = 1; i < propertyPathLength; i++) {
 						if (propertyPath[propertyPathLength - i] == '.') {
 							dotCount++;
-							if (dotCount >= siblingOfListDotCount) {
+							if (dotCount >= SiblingOfListDotCount) {
 								localPathLength = i - 1;
 								break;
 							}
@@ -157,7 +157,7 @@ namespace Spine.Unity.Editor {
 				get {
 					if (boxScopeStyle == null) {
 						boxScopeStyle = new GUIStyle(EditorStyles.helpBox);
-						var p = boxScopeStyle.padding;
+						RectOffset p = boxScopeStyle.padding; // RectOffset is a class
 						p.right += 6;
 						p.top += 1;
 						p.left += 3;

+ 124 - 3
spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs

@@ -41,7 +41,7 @@ namespace Spine.Unity {
 		internal const HideFlags MeshHideflags = HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor;
 
 		/// <summary>Factory method for creating a new mesh for use in Spine components. This can be called in field initializers.</summary>
-		public static Mesh NewMesh () {
+		public static Mesh NewSkeletonMesh () {
 			var m = new Mesh();
 			m.MarkDynamic();
 			m.name = "Skeleton Mesh";
@@ -108,7 +108,6 @@ namespace Spine.Unity {
 
 		[System.Serializable]
 		public struct Settings {
-			//public bool renderMeshes;
 			public bool useClipping;
 			[Space]
 			[Range(-0.1f, 0f)] public float zSpacing;
@@ -969,6 +968,11 @@ namespace Spine.Unity {
 			var vbi = vertexBuffer.Items;
 			var ubi = uvBuffer.Items;
 			var cbi = colorBuffer.Items;
+<<<<<<< HEAD
+=======
+			//var sbi = submeshes.Items;
+			//int submeshCount = submeshes.Count;
+>>>>>>> 3.6
 
 			// Zero the extra.
 			{
@@ -1158,6 +1162,123 @@ namespace Spine.Unity {
 			}
 		}
 		#endregion
+
+		#region AttachmentRendering
+		static List<Vector3> AttachmentVerts = new List<Vector3>();
+		static List<Vector2> AttachmentUVs = new List<Vector2>();
+		static List<Color32> AttachmentColors32 = new List<Color32>();
+		static List<int> AttachmentIndices = new List<int>();
+
+		/// <summary>
+		/// Fills mesh vertex data to render a RegionAttachment.</summary>
+		public static void FillMeshLocal (Mesh mesh, RegionAttachment regionAttachment) {
+			if (mesh == null) return;
+			if (regionAttachment == null) return;
+
+			AttachmentVerts.Clear();
+			var offsets = regionAttachment.Offset;
+			AttachmentVerts.Add(new Vector3(offsets[RegionAttachment.BLX], offsets[RegionAttachment.BLY]));
+			AttachmentVerts.Add(new Vector3(offsets[RegionAttachment.ULX], offsets[RegionAttachment.ULY]));
+			AttachmentVerts.Add(new Vector3(offsets[RegionAttachment.URX], offsets[RegionAttachment.URY]));
+			AttachmentVerts.Add(new Vector3(offsets[RegionAttachment.BRX], offsets[RegionAttachment.BRY]));
+
+			AttachmentUVs.Clear();
+			var uvs = regionAttachment.UVs;
+			AttachmentUVs.Add(new Vector2(uvs[RegionAttachment.ULX], uvs[RegionAttachment.ULY]));
+			AttachmentUVs.Add(new Vector2(uvs[RegionAttachment.URX], uvs[RegionAttachment.URY]));
+			AttachmentUVs.Add(new Vector2(uvs[RegionAttachment.BRX], uvs[RegionAttachment.BRY]));
+			AttachmentUVs.Add(new Vector2(uvs[RegionAttachment.BLX], uvs[RegionAttachment.BLY]));
+
+			AttachmentColors32.Clear();
+			Color32 c = (Color32)(new Color(regionAttachment.r, regionAttachment.g, regionAttachment.b, regionAttachment.a));
+			for (int i = 0; i < 4; i++)
+				AttachmentColors32.Add(c);
+
+			AttachmentIndices.Clear();
+			AttachmentIndices.AddRange(new[] { 0, 2, 1, 0, 3, 2 });
+
+			mesh.Clear();
+			mesh.name = regionAttachment.Name;
+			mesh.SetVertices(AttachmentVerts);
+			mesh.SetUVs(0, AttachmentUVs);
+			mesh.SetColors(AttachmentColors32);
+			mesh.SetTriangles(AttachmentIndices, 0);
+			mesh.RecalculateBounds();
+
+			AttachmentVerts.Clear();
+			AttachmentUVs.Clear();
+			AttachmentColors32.Clear();
+			AttachmentIndices.Clear();
+		}
+
+		public static void FillMeshLocal (Mesh mesh, MeshAttachment meshAttachment, SkeletonData skeletonData) {
+			if (mesh == null) return;
+			if (meshAttachment == null) return;
+			int vertexCount = meshAttachment.WorldVerticesLength / 2;
+
+			AttachmentVerts.Clear();
+			if (meshAttachment.IsWeighted()) {
+				int count = meshAttachment.WorldVerticesLength;
+				int[] meshAttachmentBones = meshAttachment.bones;
+				int v = 0;
+
+				float[] vertices = meshAttachment.vertices;
+				for (int w = 0, b = 0; w < count; w += 2) {
+					float wx = 0, wy = 0;
+					int n = meshAttachmentBones[v++];
+					n += v;
+					for (; v < n; v++, b += 3) {
+						BoneMatrix bm = BoneMatrix.CalculateSetupWorld(skeletonData.bones.Items[meshAttachmentBones[v]]);
+						float vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2];
+						wx += (vx * bm.a + vy * bm.b + bm.x) * weight;
+						wy += (vx * bm.c + vy * bm.d + bm.y) * weight;
+					}
+					AttachmentVerts.Add(new Vector3(wx, wy));
+				}
+			} else {
+				var localVerts = meshAttachment.Vertices;
+				Vector3 pos = default(Vector3);
+				for (int i = 0; i < vertexCount; i++) {
+					int ii = i * 2;
+					pos.x = localVerts[ii];
+					pos.y = localVerts[ii + 1];
+					AttachmentVerts.Add(pos);
+				}
+			}
+
+			var uvs = meshAttachment.uvs;
+			Vector2 uv = default(Vector2);
+			Color32 c = (Color32)(new Color(meshAttachment.r, meshAttachment.g, meshAttachment.b, meshAttachment.a));
+			AttachmentUVs.Clear();
+			AttachmentColors32.Clear();
+			for (int i = 0; i < vertexCount; i++) {
+				int ii = i * 2;
+				uv.x = uvs[ii];
+				uv.y = uvs[ii + 1];
+				AttachmentUVs.Add(uv);
+
+				AttachmentColors32.Add(c);
+			}
+
+			AttachmentIndices.Clear();
+			AttachmentIndices.AddRange(meshAttachment.triangles);
+
+			mesh.Clear();
+			mesh.name = meshAttachment.Name;
+			mesh.SetVertices(AttachmentVerts);
+			mesh.SetUVs(0, AttachmentUVs);
+			mesh.SetColors(AttachmentColors32);
+			mesh.SetTriangles(AttachmentIndices, 0);
+			mesh.RecalculateBounds();
+
+			AttachmentVerts.Clear();
+			AttachmentUVs.Clear();
+			AttachmentColors32.Clear();
+			AttachmentIndices.Clear();
+		}
+
+		
+		#endregion
 	}
 
 	public class MeshRendererBuffers : IDisposable {
@@ -1222,7 +1343,7 @@ namespace Spine.Unity {
 
 		///<summary>This is a Mesh that also stores the instructions SkeletonRenderer generated for it.</summary>
 		public class SmartMesh : IDisposable {
-			public Mesh mesh = SpineMesh.NewMesh();
+			public Mesh mesh = SpineMesh.NewSkeletonMesh();
 			public SkeletonRendererInstruction instructionUsed = new SkeletonRendererInstruction();		
 
 			public void Dispose () {

+ 142 - 3
spine-unity/Assets/spine-unity/SkeletonExtensions.cs

@@ -28,10 +28,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-// Contributed by: Mitch Thompson and John Dy
-
 using UnityEngine;
-using Spine;
 
 namespace Spine.Unity {
 	public static class SkeletonExtensions {
@@ -286,8 +283,150 @@ namespace Spine.Unity {
 }
 
 namespace Spine {
+	using System;
 	using System.Collections.Generic;
 
+	public struct BoneMatrix {
+		public float a, b, c, d, x, y;
+
+		/// <summary>Recursively calculates a worldspace bone matrix based on BoneData.</summary>
+		public static BoneMatrix CalculateSetupWorld (BoneData boneData) {
+			if (boneData == null)
+				return default(BoneMatrix);
+
+			// End condition: isRootBone
+			if (boneData.parent == null)
+				return GetInheritedInternal(boneData, default(BoneMatrix));
+
+			BoneMatrix result = CalculateSetupWorld(boneData.parent);
+			return GetInheritedInternal(boneData, result);
+		}
+
+		static BoneMatrix GetInheritedInternal (BoneData boneData, BoneMatrix parentMatrix) {
+			var parent = boneData.parent;
+			if (parent == null) return new BoneMatrix(boneData); // isRootBone
+
+			float pa = parentMatrix.a, pb = parentMatrix.b, pc = parentMatrix.c, pd = parentMatrix.d;
+			BoneMatrix result = default(BoneMatrix);
+			result.x = pa * boneData.x + pb * boneData.y + parentMatrix.x;
+			result.y = pc * boneData.x + pd * boneData.y + parentMatrix.y;
+
+			switch (boneData.transformMode) {
+				case TransformMode.Normal: {
+					float rotationY = boneData.rotation + 90 + boneData.shearY;
+					float la = MathUtils.CosDeg(boneData.rotation + boneData.shearX) * boneData.scaleX;
+					float lb = MathUtils.CosDeg(rotationY) * boneData.scaleY;
+					float lc = MathUtils.SinDeg(boneData.rotation + boneData.shearX) * boneData.scaleX;
+					float ld = MathUtils.SinDeg(rotationY) * boneData.scaleY;
+					result.a = pa * la + pb * lc;
+					result.b = pa * lb + pb * ld;
+					result.c = pc * la + pd * lc;
+					result.d = pc * lb + pd * ld;
+					break;
+				}
+				case TransformMode.OnlyTranslation: {
+					float rotationY = boneData.rotation + 90 + boneData.shearY;
+					result.a = MathUtils.CosDeg(boneData.rotation + boneData.shearX) * boneData.scaleX;
+					result.b = MathUtils.CosDeg(rotationY) * boneData.scaleY;
+					result.c = MathUtils.SinDeg(boneData.rotation + boneData.shearX) * boneData.scaleX;
+					result.d = MathUtils.SinDeg(rotationY) * boneData.scaleY;
+					break;
+				}
+				case TransformMode.NoRotationOrReflection: {
+					float s = pa * pa + pc * pc, prx;
+					if (s > 0.0001f) {
+						s = Math.Abs(pa * pd - pb * pc) / s;
+						pb = pc * s;
+						pd = pa * s;
+						prx = MathUtils.Atan2(pc, pa) * MathUtils.RadDeg;
+					} else {
+						pa = 0;
+						pc = 0;
+						prx = 90 - MathUtils.Atan2(pd, pb) * MathUtils.RadDeg;
+					}
+					float rx = boneData.rotation + boneData.shearX - prx;
+					float ry = boneData.rotation + boneData.shearY - prx + 90;
+					float la = MathUtils.CosDeg(rx) * boneData.scaleX;
+					float lb = MathUtils.CosDeg(ry) * boneData.scaleY;
+					float lc = MathUtils.SinDeg(rx) * boneData.scaleX;
+					float ld = MathUtils.SinDeg(ry) * boneData.scaleY;
+					result.a = pa * la - pb * lc;
+					result.b = pa * lb - pb * ld;
+					result.c = pc * la + pd * lc;
+					result.d = pc * lb + pd * ld;
+					break;
+				}
+				case TransformMode.NoScale:
+				case TransformMode.NoScaleOrReflection: {
+					float cos = MathUtils.CosDeg(boneData.rotation), sin = MathUtils.SinDeg(boneData.rotation);
+					float za = pa * cos + pb * sin;
+					float zc = pc * cos + pd * sin;
+					float s = (float)Math.Sqrt(za * za + zc * zc);
+					if (s > 0.00001f)
+						s = 1 / s;
+					za *= s;
+					zc *= s;
+					s = (float)Math.Sqrt(za * za + zc * zc);
+					float r = MathUtils.PI / 2 + MathUtils.Atan2(zc, za);
+					float zb = MathUtils.Cos(r) * s;
+					float zd = MathUtils.Sin(r) * s;
+					float la = MathUtils.CosDeg(boneData.shearX) * boneData.scaleX;
+					float lb = MathUtils.CosDeg(90 + boneData.shearY) * boneData.scaleY;
+					float lc = MathUtils.SinDeg(boneData.shearX) * boneData.scaleX;
+					float ld = MathUtils.SinDeg(90 + boneData.shearY) * boneData.scaleY;
+					if (boneData.transformMode != TransformMode.NoScaleOrReflection ? pa * pd - pb * pc < 0 : false) {
+						zb = -zb;
+						zd = -zd;
+					}
+					result.a = za * la + zb * lc;
+					result.b = za * lb + zb * ld;
+					result.c = zc * la + zd * lc;
+					result.d = zc * lb + zd * ld;
+					break;
+				}
+			}
+
+			return result;
+		}
+
+		/// <summary>Constructor for a local bone matrix based on Setup Pose BoneData.</summary>
+		public BoneMatrix (BoneData boneData) {
+			float rotationY = boneData.rotation + 90 + boneData.shearY;
+			float rotationX = boneData.rotation + boneData.shearX;
+
+			a = MathUtils.CosDeg(rotationX) * boneData.scaleX;
+			c = MathUtils.SinDeg(rotationX) * boneData.scaleX;
+			b = MathUtils.CosDeg(rotationY) * boneData.scaleY;
+			d = MathUtils.SinDeg(rotationY) * boneData.scaleY;
+			x = boneData.x;
+			y = boneData.y;
+		}
+
+		/// <summary>Constructor for a local bone matrix based on a bone instance's current pose.</summary>
+		public BoneMatrix (Bone bone) {
+			float rotationY = bone.rotation + 90 + bone.shearY;
+			float rotationX = bone.rotation + bone.shearX;
+
+			a = MathUtils.CosDeg(rotationX) * bone.scaleX;
+			c = MathUtils.SinDeg(rotationX) * bone.scaleX;
+			b = MathUtils.CosDeg(rotationY) * bone.scaleY;
+			d = MathUtils.SinDeg(rotationY) * bone.scaleY;
+			x = bone.x;
+			y = bone.y;
+		}
+
+		public BoneMatrix TransformMatrix (BoneMatrix local) {
+			return new BoneMatrix {
+				a = this.a * local.a + this.b * local.c,
+				b = this.a * local.b + this.b * local.d,
+				c = this.c * local.a + this.d * local.c,
+				d = this.c * local.b + this.d * local.d,
+				x = this.a * local.x + this.b * local.y + this.x,
+				y = this.c * local.x + this.d * local.y + this.y
+			};
+		}
+	}
+
 	public static class SkeletonExtensions {
 		public static bool IsWeighted (this VertexAttachment va) {
 			return va.bones != null && va.bones.Length > 0;