瀏覽代碼

Meshes, FFD and skinning for spine-csharp and spine-xna.

Also updated example projects for spine-unity and spine-tk2d, but no meshes, FFD or skinning for those two yet.
NathanSweet 11 年之前
父節點
當前提交
5b68fe5190
共有 100 個文件被更改,包括 1749 次插入508 次删除
  1. 6 0
      spine-csharp/spine-csharp_xna.csproj
  2. 99 22
      spine-csharp/src/Animation.cs
  3. 58 19
      spine-csharp/src/Attachments/AtlasAttachmentLoader.cs
  4. 10 1
      spine-csharp/src/Attachments/AttachmentLoader.cs
  5. 1 1
      spine-csharp/src/Attachments/AttachmentType.cs
  6. 4 2
      spine-csharp/src/Attachments/BoundingBoxAttachment.cs
  7. 107 0
      spine-csharp/src/Attachments/MeshAttachment.cs
  8. 17 13
      spine-csharp/src/Attachments/RegionAttachment.cs
  9. 130 0
      spine-csharp/src/Attachments/SkinnedMeshAttachment.cs
  10. 15 3
      spine-csharp/src/Skeleton.cs
  11. 208 54
      spine-csharp/src/SkeletonJson.cs
  12. 7 0
      spine-csharp/src/Slot.cs
  13. 22 10
      spine-tk2d/Assets/Spine/BoneComponent.cs
  14. 89 38
      spine-tk2d/Assets/Spine/SpriteCollectionAttachmentLoader.cs
  15. 二進制
      spine-tk2d/Assets/examples/spineboy/Spineboy SkeletonData.asset
  16. 2 2
      spine-tk2d/Assets/examples/spineboy/Spineboy.cs
  17. 二進制
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/SpineboyAtlas.prefab
  18. 二進制
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas0 material.mat
  19. 二進制
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas0.png
  20. 10 1
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas0.png.meta
  21. 二進制
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas1 material.mat
  22. 0 4
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas1 material.mat.meta
  23. 二進制
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas1.png
  24. 0 36
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas1.png.meta
  25. 二進制
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas2 material.mat
  26. 0 4
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas2 material.mat.meta
  27. 二進制
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas2.png
  28. 0 36
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas2.png.meta
  29. 二進制
      spine-tk2d/Assets/examples/spineboy/SpineboyAtlas.prefab
  30. 二進制
      spine-tk2d/Assets/examples/spineboy/images/eye_indifferent.png
  31. 11 2
      spine-tk2d/Assets/examples/spineboy/images/eye_indifferent.png.meta
  32. 二進制
      spine-tk2d/Assets/examples/spineboy/images/eye_surprised.png
  33. 11 2
      spine-tk2d/Assets/examples/spineboy/images/eye_surprised.png.meta
  34. 二進制
      spine-tk2d/Assets/examples/spineboy/images/eyes-closed.png
  35. 二進制
      spine-tk2d/Assets/examples/spineboy/images/eyes.png
  36. 二進制
      spine-tk2d/Assets/examples/spineboy/images/front_bracer.png
  37. 11 2
      spine-tk2d/Assets/examples/spineboy/images/front_bracer.png.meta
  38. 二進制
      spine-tk2d/Assets/examples/spineboy/images/front_fist_closed.png
  39. 11 2
      spine-tk2d/Assets/examples/spineboy/images/front_fist_closed.png.meta
  40. 二進制
      spine-tk2d/Assets/examples/spineboy/images/front_fist_open.png
  41. 45 0
      spine-tk2d/Assets/examples/spineboy/images/front_fist_open.png.meta
  42. 二進制
      spine-tk2d/Assets/examples/spineboy/images/front_foot.png
  43. 45 0
      spine-tk2d/Assets/examples/spineboy/images/front_foot.png.meta
  44. 二進制
      spine-tk2d/Assets/examples/spineboy/images/front_foot_bend1.png
  45. 45 0
      spine-tk2d/Assets/examples/spineboy/images/front_foot_bend1.png.meta
  46. 二進制
      spine-tk2d/Assets/examples/spineboy/images/front_foot_bend2.png
  47. 45 0
      spine-tk2d/Assets/examples/spineboy/images/front_foot_bend2.png.meta
  48. 二進制
      spine-tk2d/Assets/examples/spineboy/images/front_shin.png
  49. 45 0
      spine-tk2d/Assets/examples/spineboy/images/front_shin.png.meta
  50. 二進制
      spine-tk2d/Assets/examples/spineboy/images/front_thigh.png
  51. 45 0
      spine-tk2d/Assets/examples/spineboy/images/front_thigh.png.meta
  52. 二進制
      spine-tk2d/Assets/examples/spineboy/images/front_upper_arm.png
  53. 45 0
      spine-tk2d/Assets/examples/spineboy/images/front_upper_arm.png.meta
  54. 二進制
      spine-tk2d/Assets/examples/spineboy/images/goggles.png
  55. 45 0
      spine-tk2d/Assets/examples/spineboy/images/goggles.png.meta
  56. 二進制
      spine-tk2d/Assets/examples/spineboy/images/gun.png
  57. 45 0
      spine-tk2d/Assets/examples/spineboy/images/gun.png.meta
  58. 二進制
      spine-tk2d/Assets/examples/spineboy/images/head.png
  59. 10 1
      spine-tk2d/Assets/examples/spineboy/images/head.png.meta
  60. 二進制
      spine-tk2d/Assets/examples/spineboy/images/left-ankle.png
  61. 二進制
      spine-tk2d/Assets/examples/spineboy/images/left-arm.png
  62. 二進制
      spine-tk2d/Assets/examples/spineboy/images/left-foot.png
  63. 0 36
      spine-tk2d/Assets/examples/spineboy/images/left-foot.png.meta
  64. 二進制
      spine-tk2d/Assets/examples/spineboy/images/left-hand.png
  65. 0 36
      spine-tk2d/Assets/examples/spineboy/images/left-hand.png.meta
  66. 二進制
      spine-tk2d/Assets/examples/spineboy/images/left-lower-leg.png
  67. 0 36
      spine-tk2d/Assets/examples/spineboy/images/left-lower-leg.png.meta
  68. 二進制
      spine-tk2d/Assets/examples/spineboy/images/left-pant-bottom.png
  69. 0 36
      spine-tk2d/Assets/examples/spineboy/images/left-pant-bottom.png.meta
  70. 二進制
      spine-tk2d/Assets/examples/spineboy/images/left-shoulder.png
  71. 0 36
      spine-tk2d/Assets/examples/spineboy/images/left-shoulder.png.meta
  72. 二進制
      spine-tk2d/Assets/examples/spineboy/images/left-upper-leg.png
  73. 0 36
      spine-tk2d/Assets/examples/spineboy/images/left-upper-leg.png.meta
  74. 二進制
      spine-tk2d/Assets/examples/spineboy/images/mouth_grind.png
  75. 45 0
      spine-tk2d/Assets/examples/spineboy/images/mouth_grind.png.meta
  76. 二進制
      spine-tk2d/Assets/examples/spineboy/images/mouth_oooo.png
  77. 45 0
      spine-tk2d/Assets/examples/spineboy/images/mouth_oooo.png.meta
  78. 二進制
      spine-tk2d/Assets/examples/spineboy/images/mouth_smile.png
  79. 45 0
      spine-tk2d/Assets/examples/spineboy/images/mouth_smile.png.meta
  80. 二進制
      spine-tk2d/Assets/examples/spineboy/images/muzzle.png
  81. 45 0
      spine-tk2d/Assets/examples/spineboy/images/muzzle.png.meta
  82. 二進制
      spine-tk2d/Assets/examples/spineboy/images/neck.png
  83. 10 1
      spine-tk2d/Assets/examples/spineboy/images/neck.png.meta
  84. 二進制
      spine-tk2d/Assets/examples/spineboy/images/pelvis.png
  85. 0 36
      spine-tk2d/Assets/examples/spineboy/images/pelvis.png.meta
  86. 二進制
      spine-tk2d/Assets/examples/spineboy/images/rear_bracer.png
  87. 45 0
      spine-tk2d/Assets/examples/spineboy/images/rear_bracer.png.meta
  88. 二進制
      spine-tk2d/Assets/examples/spineboy/images/rear_foot.png
  89. 45 0
      spine-tk2d/Assets/examples/spineboy/images/rear_foot.png.meta
  90. 二進制
      spine-tk2d/Assets/examples/spineboy/images/rear_foot_bend1.png
  91. 45 0
      spine-tk2d/Assets/examples/spineboy/images/rear_foot_bend1.png.meta
  92. 二進制
      spine-tk2d/Assets/examples/spineboy/images/rear_foot_bend2.png
  93. 45 0
      spine-tk2d/Assets/examples/spineboy/images/rear_foot_bend2.png.meta
  94. 二進制
      spine-tk2d/Assets/examples/spineboy/images/rear_shin.png
  95. 45 0
      spine-tk2d/Assets/examples/spineboy/images/rear_shin.png.meta
  96. 二進制
      spine-tk2d/Assets/examples/spineboy/images/rear_thigh.png
  97. 45 0
      spine-tk2d/Assets/examples/spineboy/images/rear_thigh.png.meta
  98. 二進制
      spine-tk2d/Assets/examples/spineboy/images/rear_upper_arm.png
  99. 45 0
      spine-tk2d/Assets/examples/spineboy/images/rear_upper_arm.png.meta
  100. 二進制
      spine-tk2d/Assets/examples/spineboy/images/right-ankle.png

+ 6 - 0
spine-csharp/spine-csharp_xna.csproj

@@ -116,6 +116,12 @@
     <Compile Include="src\Slot.cs" />
     <Compile Include="src\Slot.cs" />
     <Compile Include="src\SlotData.cs" />
     <Compile Include="src\SlotData.cs" />
   </ItemGroup>
   </ItemGroup>
+  <ItemGroup>
+    <Compile Include="src\Attachments\MeshAttachment.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="src\Attachments\SkinnedMeshAttachment.cs" />
+  </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
   <!--
   <!--

+ 99 - 22
spine-csharp/src/Animation.cs

@@ -134,7 +134,7 @@ namespace Spine {
 		}
 		}
 
 
 		/// <summary>Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
 		/// <summary>Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
-	   /// cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
+		/// cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
 		/// the difference between the keyframe's values.</summary>
 		/// the difference between the keyframe's values.</summary>
 		public void SetCurve (int frameIndex, float cx1, float cy1, float cx2, float cy2) {
 		public void SetCurve (int frameIndex, float cx1, float cy1, float cx2, float cy2) {
 			float subdiv_step = 1f / BEZIER_SEGMENTS;
 			float subdiv_step = 1f / BEZIER_SEGMENTS;
@@ -363,29 +363,30 @@ namespace Spine {
 
 
 			Slot slot = skeleton.slots[slotIndex];
 			Slot slot = skeleton.slots[slotIndex];
 
 
-			if (time >= frames[frames.Length - 5]) { // Time is after last frame.
+			float r, g, b, a;
+			if (time >= frames[frames.Length - 5]) {
+				// Time is after last frame.
 				int i = frames.Length - 1;
 				int i = frames.Length - 1;
-				slot.r = frames[i - 3];
-				slot.g = frames[i - 2];
-				slot.b = frames[i - 1];
-				slot.a = frames[i];
-				return;
+				r = frames[i - 3];
+				g = frames[i - 2];
+				b = frames[i - 1];
+				a = frames[i];
+			} else {
+				// Interpolate between the last frame and the current frame.
+				int frameIndex = Animation.binarySearch(frames, time, 5);
+				float lastFrameR = frames[frameIndex - 4];
+				float lastFrameG = frames[frameIndex - 3];
+				float lastFrameB = frames[frameIndex - 2];
+				float lastFrameA = frames[frameIndex - 1];
+				float frameTime = frames[frameIndex];
+				float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime);
+				percent = GetCurvePercent(frameIndex / 5 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
+
+				r = lastFrameR + (frames[frameIndex + FRAME_R] - lastFrameR) * percent;
+				g = lastFrameG + (frames[frameIndex + FRAME_G] - lastFrameG) * percent;
+				b = lastFrameB + (frames[frameIndex + FRAME_B] - lastFrameB) * percent;
+				a = lastFrameA + (frames[frameIndex + FRAME_A] - lastFrameA) * percent;
 			}
 			}
-
-			// Interpolate between the last frame and the current frame.
-			int frameIndex = Animation.binarySearch(frames, time, 5);
-			float lastFrameR = frames[frameIndex - 4];
-			float lastFrameG = frames[frameIndex - 3];
-			float lastFrameB = frames[frameIndex - 2];
-			float lastFrameA = frames[frameIndex - 1];
-			float frameTime = frames[frameIndex];
-			float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime);
-			percent = GetCurvePercent(frameIndex / 5 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
-
-			float r = lastFrameR + (frames[frameIndex + FRAME_R] - lastFrameR) * percent;
-			float g = lastFrameG + (frames[frameIndex + FRAME_G] - lastFrameG) * percent;
-			float b = lastFrameB + (frames[frameIndex + FRAME_B] - lastFrameB) * percent;
-			float a = lastFrameA + (frames[frameIndex + FRAME_A] - lastFrameA) * percent;
 			if (alpha < 1) {
 			if (alpha < 1) {
 				slot.r += (r - slot.r) * alpha;
 				slot.r += (r - slot.r) * alpha;
 				slot.g += (g - slot.g) * alpha;
 				slot.g += (g - slot.g) * alpha;
@@ -527,4 +528,80 @@ namespace Spine {
 			}
 			}
 		}
 		}
 	}
 	}
+
+	public class FFDTimeline : CurveTimeline {
+		internal int slotIndex;
+		internal float[] frames;
+		private float[][] frameVertices;
+		internal Attachment attachment;
+
+		public int SlotIndex { get { return slotIndex; } set { slotIndex = value; } }
+		public float[] Frames { get { return frames; } set { frames = value; } } // time, ...
+		public float[][] Vertices { get { return frameVertices; } set { frameVertices = value; } }
+		public Attachment Attachment { get { return attachment; } set { attachment = value; } }
+
+		public FFDTimeline (int frameCount)
+			: base(frameCount) {
+			frames = new float[frameCount];
+			frameVertices = new float[frameCount][];
+		}
+
+		/// <summary>Sets the time and value of the specified keyframe.</summary>
+		public void setFrame (int frameIndex, float time, float[] vertices) {
+			frames[frameIndex] = time;
+			frameVertices[frameIndex] = vertices;
+		}
+
+		override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
+			Slot slot = skeleton.slots[slotIndex];
+			if (slot.attachment != attachment) return;
+
+			float[] frames = this.frames;
+			if (time < frames[0]) {
+				slot.attachmentVerticesCount = 0;
+				return; // Time is before first frame.
+			}
+
+			float[][] frameVertices = this.frameVertices;
+			int vertexCount = frameVertices[0].Length;
+
+			float[] vertices = slot.attachmentVertices;
+			if (vertices.Length < vertexCount) {
+				vertices = new float[vertexCount];
+				slot.attachmentVertices = vertices;
+			}
+			slot.attachmentVerticesCount = vertexCount;
+
+			if (time >= frames[frames.Length - 1]) { // Time is after last frame.
+				float[] lastVertices = frameVertices[frames.Length - 1];
+				if (alpha < 1) {
+					for (int i = 0; i < vertexCount; i++)
+						vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
+				} else
+					Array.Copy(lastVertices, 0, vertices, 0, vertexCount);
+				return;
+			}
+
+			// Interpolate between the previous frame and the current frame.
+			int frameIndex = Animation.binarySearch(frames, time, 1);
+			float frameTime = frames[frameIndex];
+			float percent = 1 - (time - frameTime) / (frames[frameIndex - 1] - frameTime);
+			percent = GetCurvePercent(frameIndex - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
+
+			float[] prevVertices = frameVertices[frameIndex - 1];
+			float[] nextVertices = frameVertices[frameIndex];
+
+			if (alpha < 1) {
+				for (int i = 0; i < vertexCount; i++) {
+					float prev = prevVertices[i];
+					vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
+				}
+			} else {
+				for (int i = 0; i < vertexCount; i++) {
+					float prev = prevVertices[i];
+					vertices[i] = prev + (nextVertices[i] - prev) * percent;
+				}
+			}
+		}
+	}
 }
 }

+ 58 - 19
spine-csharp/src/Attachments/AtlasAttachmentLoader.cs

@@ -39,25 +39,64 @@ namespace Spine {
 			this.atlas = atlas;
 			this.atlas = atlas;
 		}
 		}
 
 
-		public Attachment NewAttachment (Skin skin, AttachmentType type, String name) {
-			switch (type) {
-			case AttachmentType.region:
-				AtlasRegion region = atlas.FindRegion(name);
-				if (region == null) throw new Exception("Region not found in atlas: " + name + " (" + type + ")");
-				RegionAttachment attachment = new RegionAttachment(name);
-				attachment.RendererObject = region;
-				attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate);
-				attachment.regionOffsetX = region.offsetX;
-				attachment.regionOffsetY = region.offsetY;
-				attachment.regionWidth = region.width;
-				attachment.regionHeight = region.height;
-				attachment.regionOriginalWidth = region.originalWidth;
-				attachment.regionOriginalHeight = region.originalHeight;
-				return attachment;
-			case AttachmentType.boundingbox:
-				return new BoundingBoxAttachment(name);
-			}
-			throw new Exception("Unknown attachment type: " + type);
+		public RegionAttachment NewRegionAttachment (Skin skin, String name, String path) {
+			AtlasRegion region = atlas.FindRegion(path);
+			if (region == null) throw new Exception("Region not found in atlas: " + path + " (region attachment: " + name + ")");
+			RegionAttachment attachment = new RegionAttachment(name);
+			attachment.Path = path;
+			attachment.RendererObject = region;
+			attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate);
+			attachment.regionOffsetX = region.offsetX;
+			attachment.regionOffsetY = region.offsetY;
+			attachment.regionWidth = region.width;
+			attachment.regionHeight = region.height;
+			attachment.regionOriginalWidth = region.originalWidth;
+			attachment.regionOriginalHeight = region.originalHeight;
+			return attachment;
+		}
+
+		public MeshAttachment NewMeshAttachment (Skin skin, String name, String path) {
+			AtlasRegion region = atlas.FindRegion(path);
+			if (region == null) throw new Exception("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
+			MeshAttachment attachment = new MeshAttachment(name);
+			attachment.Path = path;
+			attachment.RendererObject = region;
+			attachment.RegionU = region.u;
+			attachment.RegionV = region.v;
+			attachment.RegionU2 = region.u2;
+			attachment.RegionV2 = region.v2;
+			attachment.RegionRotate = region.rotate;
+			attachment.regionOffsetX = region.offsetX;
+			attachment.regionOffsetY = region.offsetY;
+			attachment.regionWidth = region.width;
+			attachment.regionHeight = region.height;
+			attachment.regionOriginalWidth = region.originalWidth;
+			attachment.regionOriginalHeight = region.originalHeight;
+			return attachment;
+		}
+
+		public SkinnedMeshAttachment NewSkinnedMeshAttachment (Skin skin, String name, String path) {
+			AtlasRegion region = atlas.FindRegion(path);
+			if (region == null) throw new Exception("Region not found in atlas: " + path + " (skinned mesh attachment: " + name + ")");
+			SkinnedMeshAttachment attachment = new SkinnedMeshAttachment(name);
+			attachment.Path = path;
+			attachment.RendererObject = region;
+			attachment.RegionU = region.u;
+			attachment.RegionV = region.v;
+			attachment.RegionU2 = region.u2;
+			attachment.RegionV2 = region.v2;
+			attachment.RegionRotate = region.rotate;
+			attachment.regionOffsetX = region.offsetX;
+			attachment.regionOffsetY = region.offsetY;
+			attachment.regionWidth = region.width;
+			attachment.regionHeight = region.height;
+			attachment.regionOriginalWidth = region.originalWidth;
+			attachment.regionOriginalHeight = region.originalHeight;
+			return attachment;
+		}
+
+		public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, String name) {
+			return new BoundingBoxAttachment(name);
 		}
 		}
 	}
 	}
 }
 }

+ 10 - 1
spine-csharp/src/Attachments/AttachmentLoader.cs

@@ -33,6 +33,15 @@ using System;
 namespace Spine {
 namespace Spine {
 	public interface AttachmentLoader {
 	public interface AttachmentLoader {
 		/// <return>May be null to not load any attachment.</return>
 		/// <return>May be null to not load any attachment.</return>
-		Attachment NewAttachment (Skin skin, AttachmentType type, String name);
+		RegionAttachment NewRegionAttachment (Skin skin, String name, String path);
+
+		/// <return>May be null to not load any attachment.</return>
+		MeshAttachment NewMeshAttachment (Skin skin, String name, String path);
+
+		/// <return>May be null to not load any attachment.</return>
+		SkinnedMeshAttachment NewSkinnedMeshAttachment (Skin skin, String name, String path);
+
+		/// <return>May be null to not load any attachment.</return>
+		BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, String name);
 	}
 	}
 }
 }

+ 1 - 1
spine-csharp/src/Attachments/AttachmentType.cs

@@ -30,6 +30,6 @@
 
 
 namespace Spine {
 namespace Spine {
 	public enum AttachmentType {
 	public enum AttachmentType {
-		region, regionsequence, boundingbox
+		region, boundingbox, mesh, skinnedmesh
 	}
 	}
 }
 }

+ 4 - 2
spine-csharp/src/Attachments/BoundingBoxAttachment.cs

@@ -33,7 +33,9 @@ using System;
 namespace Spine {
 namespace Spine {
 	/// <summary>Attachment that has a polygon for bounds checking.</summary>
 	/// <summary>Attachment that has a polygon for bounds checking.</summary>
 	public class BoundingBoxAttachment : Attachment {
 	public class BoundingBoxAttachment : Attachment {
-		public float[] Vertices { get; set; }
+		internal float[] vertices;
+
+		public float[] Vertices { get { return vertices; } set { vertices = value; } }
 
 
 		public BoundingBoxAttachment (string name)
 		public BoundingBoxAttachment (string name)
 			: base(name) {
 			: base(name) {
@@ -47,7 +49,7 @@ namespace Spine {
 			float m01 = bone.m01;
 			float m01 = bone.m01;
 			float m10 = bone.m10;
 			float m10 = bone.m10;
 			float m11 = bone.m11;
 			float m11 = bone.m11;
-			float[] vertices = Vertices;
+			float[] vertices = this.vertices;
 			for (int i = 0, n = vertices.Length; i < n; i += 2) {
 			for (int i = 0, n = vertices.Length; i < n; i += 2) {
 				float px = vertices[i];
 				float px = vertices[i];
 				float py = vertices[i + 1];
 				float py = vertices[i + 1];

+ 107 - 0
spine-csharp/src/Attachments/MeshAttachment.cs

@@ -0,0 +1,107 @@
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.1
+ * 
+ * Copyright (c) 2013, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable and
+ * non-transferable license to install, execute and perform the Spine Runtimes
+ * Software (the "Software") solely for internal use. Without the written
+ * permission of Esoteric Software (typically granted by licensing Spine), you
+ * may not (a) modify, translate, adapt or otherwise create derivative works,
+ * improvements of the Software or develop new applications using the Software
+ * or (b) remove, delete, alter or obscure any trademarks or any copyright,
+ * trademark, patent or other intellectual property or proprietary rights
+ * notices on or in the Software, including any copy thereof. Redistributions
+ * in binary or source form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+using System;
+
+namespace Spine {
+	/// <summary>Attachment that displays a texture region.</summary>
+	public class MeshAttachment : Attachment {
+		internal float[] vertices, uvs;
+		internal int[] triangles;
+		internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight;
+		internal float r = 1, g = 1, b = 1, a = 1;
+
+		public float[] Vertices { get { return vertices; } set { vertices = value; } }
+		public float[] UVs { get { return uvs; } set { uvs = value; } }
+		public int[] Triangles { get { return triangles; } set { triangles = value; } }
+
+		public float R { get { return r; } set { r = value; } }
+		public float G { get { return g; } set { g = value; } }
+		public float B { get { return b; } set { b = value; } }
+		public float A { get { return a; } set { a = value; } }
+
+		public String Path { get; set; }
+		public Object RendererObject { get; set; }
+		public float RegionU { get; set; }
+		public float RegionV { get; set; }
+		public float RegionU2 { get; set; }
+		public float RegionV2 { get; set; }
+		public bool RegionRotate { get; set; }
+		public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } }
+		public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
+		public float RegionWidth { get { return regionWidth; } set { regionWidth = value; } }
+		public float RegionHeight { get { return regionHeight; } set { regionHeight = value; } } // Unrotated, stripped size.
+		public float RegionOriginalWidth { get { return regionOriginalWidth; } set { regionOriginalWidth = value; } }
+		public float RegionOriginalHeight { get { return regionOriginalHeight; } set { regionOriginalHeight = value; } } // Unrotated, unstripped size.
+
+		// Nonessential.
+		public int HullLength { get; set; }
+		public int[] Edges { get; set; }
+		public float Width { get; set; }
+		public float Height { get; set; }
+
+		public MeshAttachment (string name)
+			: base(name) {
+		}
+
+		public void SetMesh (float[] vertices, int[] triangles, float[] uvs) {
+			this.vertices = vertices;
+			this.triangles = triangles;
+			this.uvs = uvs;
+			float u = RegionU, v = RegionV, width = RegionU2 - RegionU, height = RegionV2 - RegionV;
+			if (RegionRotate) {
+				for (int i = 0, n = uvs.Length; i < n; i += 2) {
+					uvs[i] = u + uvs[i + 1] * width;
+					uvs[i + 1] = v + height - uvs[i] * height;
+				}
+			} else {
+				for (int i = 0, n = uvs.Length; i < n; i += 2) {
+					uvs[i] = u + uvs[i] * width;
+					uvs[i + 1] = v + uvs[i + 1] * height;
+				}
+			}
+		}
+
+		public void ComputeWorldVertices (float x, float y, Slot slot, float[] worldVertices) {
+			Bone bone = slot.bone;
+			x += bone.worldX;
+			y += bone.worldY;
+			float m00 = bone.m00, m01 = bone.m01, m10 = bone.m10, m11 = bone.m11;
+			float[] vertices = this.vertices;
+			if (slot.attachmentVerticesCount == vertices.Length) vertices = slot.AttachmentVertices;
+			for (int i = 0, n = vertices.Length; i < n; i += 2) {
+				float vx = vertices[i];
+				float vy = vertices[i + 1];
+				worldVertices[i] = vx * m00 + vy * m01 + x;
+				worldVertices[i + 1] = vx * m10 + vy * m11 + y;
+			}
+		}
+	}
+}

+ 17 - 13
spine-csharp/src/Attachments/RegionAttachment.cs

@@ -45,6 +45,7 @@ namespace Spine {
 		internal float x, y, rotation, scaleX = 1, scaleY = 1, width, height;
 		internal float x, y, rotation, scaleX = 1, scaleY = 1, width, height;
 		internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight;
 		internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight;
 		internal float[] offset = new float[8], uvs = new float[8];
 		internal float[] offset = new float[8], uvs = new float[8];
+		internal float r = 1, g = 1, b = 1, a = 1;
 
 
 		public float X { get { return x; } set { x = value; } }
 		public float X { get { return x; } set { x = value; } }
 		public float Y { get { return y; } set { y = value; } }
 		public float Y { get { return y; } set { y = value; } }
@@ -54,6 +55,12 @@ namespace Spine {
 		public float Width { get { return width; } set { width = value; } }
 		public float Width { get { return width; } set { width = value; } }
 		public float Height { get { return height; } set { height = value; } }
 		public float Height { get { return height; } set { height = value; } }
 
 
+		public float R { get { return r; } set { r = value; } }
+		public float G { get { return g; } set { g = value; } }
+		public float B { get { return b; } set { b = value; } }
+		public float A { get { return a; } set { a = value; } }
+
+		public String Path { get; set; }
 		public Object RendererObject { get; set; }
 		public Object RendererObject { get; set; }
 		public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } }
 		public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } }
 		public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
 		public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
@@ -127,22 +134,19 @@ namespace Spine {
 			offset[Y4] = localYCos + localX2Sin;
 			offset[Y4] = localYCos + localX2Sin;
 		}
 		}
 
 
-		public void ComputeWorldVertices (float x, float y, Bone bone, float[] vertices) {
+		public void ComputeWorldVertices (float x, float y, Bone bone, float[] worldVertices) {
 			x += bone.worldX;
 			x += bone.worldX;
 			y += bone.worldY;
 			y += bone.worldY;
-			float m00 = bone.m00;
-			float m01 = bone.m01;
-			float m10 = bone.m10;
-			float m11 = bone.m11;
+			float m00 = bone.m00, m01 = bone.m01, m10 = bone.m10, m11 = bone.m11;
 			float[] offset = this.offset;
 			float[] offset = this.offset;
-			vertices[X1] = offset[X1] * m00 + offset[Y1] * m01 + x;
-			vertices[Y1] = offset[X1] * m10 + offset[Y1] * m11 + y;
-			vertices[X2] = offset[X2] * m00 + offset[Y2] * m01 + x;
-			vertices[Y2] = offset[X2] * m10 + offset[Y2] * m11 + y;
-			vertices[X3] = offset[X3] * m00 + offset[Y3] * m01 + x;
-			vertices[Y3] = offset[X3] * m10 + offset[Y3] * m11 + y;
-			vertices[X4] = offset[X4] * m00 + offset[Y4] * m01 + x;
-			vertices[Y4] = offset[X4] * m10 + offset[Y4] * m11 + y;
+			worldVertices[X1] = offset[X1] * m00 + offset[Y1] * m01 + x;
+			worldVertices[Y1] = offset[X1] * m10 + offset[Y1] * m11 + y;
+			worldVertices[X2] = offset[X2] * m00 + offset[Y2] * m01 + x;
+			worldVertices[Y2] = offset[X2] * m10 + offset[Y2] * m11 + y;
+			worldVertices[X3] = offset[X3] * m00 + offset[Y3] * m01 + x;
+			worldVertices[Y3] = offset[X3] * m10 + offset[Y3] * m11 + y;
+			worldVertices[X4] = offset[X4] * m00 + offset[Y4] * m01 + x;
+			worldVertices[Y4] = offset[X4] * m10 + offset[Y4] * m11 + y;
 		}
 		}
 	}
 	}
 }
 }

+ 130 - 0
spine-csharp/src/Attachments/SkinnedMeshAttachment.cs

@@ -0,0 +1,130 @@
+/******************************************************************************
+ * Spine Runtimes Software License
+ * Version 2.1
+ * 
+ * Copyright (c) 2013, Esoteric Software
+ * All rights reserved.
+ * 
+ * You are granted a perpetual, non-exclusive, non-sublicensable and
+ * non-transferable license to install, execute and perform the Spine Runtimes
+ * Software (the "Software") solely for internal use. Without the written
+ * permission of Esoteric Software (typically granted by licensing Spine), you
+ * may not (a) modify, translate, adapt or otherwise create derivative works,
+ * improvements of the Software or develop new applications using the Software
+ * or (b) remove, delete, alter or obscure any trademarks or any copyright,
+ * trademark, patent or other intellectual property or proprietary rights
+ * notices on or in the Software, including any copy thereof. Redistributions
+ * in binary or source form must include this license and terms.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+
+namespace Spine {
+	/// <summary>Attachment that displays a texture region.</summary>
+	public class SkinnedMeshAttachment : Attachment {
+		internal int[] bones;
+		internal float[] weights, uvs;
+		internal int[] triangles;
+		internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight;
+		internal float r = 1, g = 1, b = 1, a = 1;
+
+		public int[] Bones { get { return bones; } set { bones = value; } }
+		public float[] Weights { get { return weights; } set { weights = value; } }
+		public float[] UVs { get { return uvs; } set { uvs = value; } }
+		public int[] Triangles { get { return triangles; } set { triangles = value; } }
+
+		public float R { get { return r; } set { r = value; } }
+		public float G { get { return g; } set { g = value; } }
+		public float B { get { return b; } set { b = value; } }
+		public float A { get { return a; } set { a = value; } }
+
+		public String Path { get; set; }
+		public Object RendererObject { get; set; }
+		public float RegionU { get; set; }
+		public float RegionV { get; set; }
+		public float RegionU2 { get; set; }
+		public float RegionV2 { get; set; }
+		public bool RegionRotate { get; set; }
+		public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } }
+		public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
+		public float RegionWidth { get { return regionWidth; } set { regionWidth = value; } }
+		public float RegionHeight { get { return regionHeight; } set { regionHeight = value; } } // Unrotated, stripped size.
+		public float RegionOriginalWidth { get { return regionOriginalWidth; } set { regionOriginalWidth = value; } }
+		public float RegionOriginalHeight { get { return regionOriginalHeight; } set { regionOriginalHeight = value; } } // Unrotated, unstripped size.
+
+		// Nonessential.
+		public int HullLength { get; set; }
+		public int[] Edges { get; set; }
+		public float Width { get; set; }
+		public float Height { get; set; }
+
+		public SkinnedMeshAttachment (string name)
+			: base(name) {
+		}
+
+		public void SetMesh (int[] bones, float[] weights, int[] triangles, float[] uvs) {
+			this.bones = bones;
+			this.weights = weights;
+			this.triangles = triangles;
+			this.uvs = uvs;
+			float u = RegionU, v = RegionV, width = RegionU2 - RegionU, height = RegionV2 - RegionV;
+			if (RegionRotate) {
+				for (int i = 0, n = uvs.Length; i < n; i += 2) {
+					uvs[i] = u + uvs[i + 1] * width;
+					uvs[i + 1] = v + height - uvs[i] * height;
+				}
+			} else {
+				for (int i = 0, n = uvs.Length; i < n; i += 2) {
+					uvs[i] = u + uvs[i] * width;
+					uvs[i + 1] = v + uvs[i + 1] * height;
+				}
+			}
+		}
+
+		public void ComputeWorldVertices (float x, float y, Slot slot, float[] worldVertices) {
+			List<Bone> skeletonBones = slot.skeleton.bones;
+			float[] weights = this.weights;
+			int[] bones = this.bones;
+			if (slot.attachmentVerticesCount == 0) {
+				for (int w = 0, v = 0, b = 0, n = bones.Length; v < n; w += 2) {
+					float wx = 0, wy = 0;
+					int nn = bones[v++] + v;
+					for (; v < nn; v++, b += 3) {
+						Bone bone = (Bone)skeletonBones[bones[v]];
+						float vx = weights[b], vy = weights[b + 1], weight = weights[b + 2];
+						wx += (vx * bone.M00 + vy * bone.M01 + bone.worldX) * weight;
+						wy += (vx * bone.M10 + vy * bone.M11 + bone.worldY) * weight;
+					}
+					worldVertices[w] = wx + x;
+					worldVertices[w + 1] = wy + y;
+				}
+			} else {
+				float[] ffd = slot.AttachmentVertices;
+				for (int w = 0, v = 0, b = 0, f = 0, n = bones.Length; v < n; w += 2) {
+					float wx = 0, wy = 0;
+					int nn = bones[v++] + v;
+					for (; v < nn; v++, b += 3, f += 2) {
+						Bone bone = (Bone)skeletonBones[bones[v]];
+						float vx = weights[b] + ffd[f], vy = weights[b + 1] + ffd[f + 1], weight = weights[b + 2];
+						wx += (vx * bone.M00 + vy * bone.M01 + bone.worldX) * weight;
+						wy += (vx * bone.M10 + vy * bone.M11 + bone.worldY) * weight;
+					}
+					worldVertices[w] = wx + x;
+					worldVertices[w + 1] = wy + y;
+				}
+			}
+		}
+	}
+}

+ 15 - 3
spine-csharp/src/Skeleton.cs

@@ -153,7 +153,7 @@ namespace Spine {
 			return -1;
 			return -1;
 		}
 		}
 
 
-		/// <summary>Sets a skin by name (see setSkin).</summary>
+		/// <summary>Sets a skin by name (see SetSkin).</summary>
 		public void SetSkin (String skinName) {
 		public void SetSkin (String skinName) {
 			Skin skin = data.FindSkin(skinName);
 			Skin skin = data.FindSkin(skinName);
 			if (skin == null) throw new ArgumentException("Skin not found: " + skinName);
 			if (skin == null) throw new ArgumentException("Skin not found: " + skinName);
@@ -161,10 +161,22 @@ namespace Spine {
 		}
 		}
 
 
 		/// <summary>Sets the skin used to look up attachments not found in the {@link SkeletonData#getDefaultSkin() default skin}. Attachments
 		/// <summary>Sets the skin used to look up attachments not found in the {@link SkeletonData#getDefaultSkin() default skin}. Attachments
-		/// from the new skin are attached if the corresponding attachment from the old skin was attached.</summary>
+		/// from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no old skin, each slot's
+		/// setup mode attachment is attached from the new skin.</summary>
 		/// <param name="newSkin">May be null.</param>
 		/// <param name="newSkin">May be null.</param>
 		public void SetSkin (Skin newSkin) {
 		public void SetSkin (Skin newSkin) {
-			if (skin != null && newSkin != null) newSkin.AttachAll(this, skin);
+			if (skin == null) {
+				List<Slot> slots = this.slots;
+				for (int i = 0, n = slots.Count; i < n; i++) {
+					Slot slot = slots[i];
+					String name = slot.data.attachmentName;
+					if (name != null) {
+						Attachment attachment = newSkin.GetAttachment(i, name);
+						if (attachment != null) slot.Attachment = attachment;
+					}
+				}
+			} else if (newSkin != null) //
+				newSkin.AttachAll(this, skin);
 			skin = newSkin;
 			skin = newSkin;
 		}
 		}
 
 

+ 208 - 54
spine-csharp/src/SkeletonJson.cs

@@ -73,9 +73,9 @@ namespace Spine {
             using (StreamReader reader = new StreamReader(stream))
             using (StreamReader reader = new StreamReader(stream))
             {
             {
 #else
 #else
-            using (StreamReader reader = new StreamReader(path)) {
+			using (StreamReader reader = new StreamReader(path)) {
 #endif
 #endif
-                SkeletonData skeletonData = ReadSkeletonData(reader);
+				SkeletonData skeletonData = ReadSkeletonData(reader);
 				skeletonData.name = Path.GetFileNameWithoutExtension(path);
 				skeletonData.name = Path.GetFileNameWithoutExtension(path);
 				return skeletonData;
 				return skeletonData;
 			}
 			}
@@ -85,7 +85,7 @@ namespace Spine {
 		public SkeletonData ReadSkeletonData (TextReader reader) {
 		public SkeletonData ReadSkeletonData (TextReader reader) {
 			if (reader == null) throw new ArgumentNullException("reader cannot be null.");
 			if (reader == null) throw new ArgumentNullException("reader cannot be null.");
 
 
-			SkeletonData skeletonData = new SkeletonData();
+			var skeletonData = new SkeletonData();
 
 
 			var root = Json.Deserialize(reader) as Dictionary<String, Object>;
 			var root = Json.Deserialize(reader) as Dictionary<String, Object>;
 			if (root == null) throw new Exception("Invalid JSON.");
 			if (root == null) throw new Exception("Invalid JSON.");
@@ -98,7 +98,7 @@ namespace Spine {
 					if (parent == null)
 					if (parent == null)
 						throw new Exception("Parent bone not found: " + boneMap["parent"]);
 						throw new Exception("Parent bone not found: " + boneMap["parent"]);
 				}
 				}
-				BoneData boneData = new BoneData((String)boneMap["name"], parent);
+				var boneData = new BoneData((String)boneMap["name"], parent);
 				boneData.length = GetFloat(boneMap, "length", 0) * Scale;
 				boneData.length = GetFloat(boneMap, "length", 0) * Scale;
 				boneData.x = GetFloat(boneMap, "x", 0) * Scale;
 				boneData.x = GetFloat(boneMap, "x", 0) * Scale;
 				boneData.y = GetFloat(boneMap, "y", 0) * Scale;
 				boneData.y = GetFloat(boneMap, "y", 0) * Scale;
@@ -113,15 +113,15 @@ namespace Spine {
 			// Slots.
 			// Slots.
 			if (root.ContainsKey("slots")) {
 			if (root.ContainsKey("slots")) {
 				foreach (Dictionary<String, Object> slotMap in (List<Object>)root["slots"]) {
 				foreach (Dictionary<String, Object> slotMap in (List<Object>)root["slots"]) {
-					String slotName = (String)slotMap["name"];
-					String boneName = (String)slotMap["bone"];
+					var slotName = (String)slotMap["name"];
+					var boneName = (String)slotMap["bone"];
 					BoneData boneData = skeletonData.FindBone(boneName);
 					BoneData boneData = skeletonData.FindBone(boneName);
 					if (boneData == null)
 					if (boneData == null)
 						throw new Exception("Slot bone not found: " + boneName);
 						throw new Exception("Slot bone not found: " + boneName);
-					SlotData slotData = new SlotData(slotName, boneData);
+					var slotData = new SlotData(slotName, boneData);
 
 
 					if (slotMap.ContainsKey("color")) {
 					if (slotMap.ContainsKey("color")) {
-						String color = (String)slotMap["color"];
+						var color = (String)slotMap["color"];
 						slotData.r = ToColor(color, 0);
 						slotData.r = ToColor(color, 0);
 						slotData.g = ToColor(color, 1);
 						slotData.g = ToColor(color, 1);
 						slotData.b = ToColor(color, 2);
 						slotData.b = ToColor(color, 2);
@@ -141,7 +141,7 @@ namespace Spine {
 			// Skins.
 			// Skins.
 			if (root.ContainsKey("skins")) {
 			if (root.ContainsKey("skins")) {
 				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["skins"]) {
 				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["skins"]) {
-					Skin skin = new Skin(entry.Key);
+					var skin = new Skin(entry.Key);
 					foreach (KeyValuePair<String, Object> slotEntry in (Dictionary<String, Object>)entry.Value) {
 					foreach (KeyValuePair<String, Object> slotEntry in (Dictionary<String, Object>)entry.Value) {
 						int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key);
 						int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key);
 						foreach (KeyValuePair<String, Object> attachmentEntry in ((Dictionary<String, Object>)slotEntry.Value)) {
 						foreach (KeyValuePair<String, Object> attachmentEntry in ((Dictionary<String, Object>)slotEntry.Value)) {
@@ -159,7 +159,7 @@ namespace Spine {
 			if (root.ContainsKey("events")) {
 			if (root.ContainsKey("events")) {
 				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["events"]) {
 				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["events"]) {
 					var entryMap = (Dictionary<String, Object>)entry.Value;
 					var entryMap = (Dictionary<String, Object>)entry.Value;
-					EventData eventData = new EventData(entry.Key);
+					var eventData = new EventData(entry.Key);
 					eventData.Int = GetInt(entryMap, "int", 0);
 					eventData.Int = GetInt(entryMap, "int", 0);
 					eventData.Float = GetFloat(entryMap, "float", 0);
 					eventData.Float = GetFloat(entryMap, "float", 0);
 					eventData.String = GetString(entryMap, "string", null);
 					eventData.String = GetString(entryMap, "string", null);
@@ -184,33 +184,127 @@ namespace Spine {
 			if (map.ContainsKey("name"))
 			if (map.ContainsKey("name"))
 				name = (String)map["name"];
 				name = (String)map["name"];
 
 
-			AttachmentType type = AttachmentType.region;
+			var type = AttachmentType.region;
 			if (map.ContainsKey("type"))
 			if (map.ContainsKey("type"))
 				type = (AttachmentType)Enum.Parse(typeof(AttachmentType), (String)map["type"], false);
 				type = (AttachmentType)Enum.Parse(typeof(AttachmentType), (String)map["type"], false);
-			Attachment attachment = attachmentLoader.NewAttachment(skin, type, name);
-
-			RegionAttachment regionAttachment = attachment as RegionAttachment;
-			if (regionAttachment != null) {
-				regionAttachment.x = GetFloat(map, "x", 0) * Scale;
-				regionAttachment.y = GetFloat(map, "y", 0) * Scale;
-				regionAttachment.scaleX = GetFloat(map, "scaleX", 1);
-				regionAttachment.scaleY = GetFloat(map, "scaleY", 1);
-				regionAttachment.rotation = GetFloat(map, "rotation", 0);
-				regionAttachment.width = GetFloat(map, "width", 32) * Scale;
-				regionAttachment.height = GetFloat(map, "height", 32) * Scale;
-				regionAttachment.UpdateOffset();
+
+			String path = name;
+			if (map.ContainsKey("path"))
+				path = (String)map["path"];
+
+			switch (type) {
+			case AttachmentType.region:
+				RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path);
+				if (region == null) return null;
+				region.x = GetFloat(map, "x", 0) * Scale;
+				region.y = GetFloat(map, "y", 0) * Scale;
+				region.scaleX = GetFloat(map, "scaleX", 1);
+				region.scaleY = GetFloat(map, "scaleY", 1);
+				region.rotation = GetFloat(map, "rotation", 0);
+				region.width = GetFloat(map, "width", 32) * Scale;
+				region.height = GetFloat(map, "height", 32) * Scale;
+				region.UpdateOffset();
+
+				if (map.ContainsKey("color")) {
+					var color = (String)map["color"];
+					region.r = ToColor(color, 0);
+					region.g = ToColor(color, 1);
+					region.b = ToColor(color, 2);
+					region.a = ToColor(color, 3);
+				}
+
+				return region;
+			case AttachmentType.mesh: {
+					MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path);
+					if (mesh == null) return null;
+
+					float[] uvs = GetFloatArray(map, "uvs", 1);
+					int[] triangles = GetIntArray(map, "triangles");
+					float[] vertices = GetFloatArray(map, "vertices", 1);
+					mesh.SetMesh(vertices, triangles, uvs);
+
+					if (map.ContainsKey("color")) {
+						var color = (String)map["color"];
+						mesh.r = ToColor(color, 0);
+						mesh.g = ToColor(color, 1);
+						mesh.b = ToColor(color, 2);
+						mesh.a = ToColor(color, 3);
+					}
+
+					mesh.HullLength = GetInt(map, "hull", 0) * 2;
+					if (map.ContainsKey("edges")) mesh.Edges = GetIntArray(map, "edges");
+					mesh.Width = GetInt(map, "width", 0) * Scale;
+					mesh.Height = GetInt(map, "height", 0) * Scale;
+
+					return mesh;
+				}
+			case AttachmentType.skinnedmesh: {
+					SkinnedMeshAttachment mesh = attachmentLoader.NewSkinnedMeshAttachment(skin, name, path);
+					if (mesh == null) return null;
+
+					float[] uvs = GetFloatArray(map, "uvs", 1);
+					int[] triangles = GetIntArray(map, "triangles");
+
+					float[] vertices = GetFloatArray(map, "vertices", 1);
+					var weights = new List<float>(uvs.Length * 3 * 3);
+					var bones = new List<int>(uvs.Length * 3);
+					float scale = Scale;
+					for (int i = 0, n = vertices.Length; i < n; ) {
+						int boneCount = (int)vertices[i++];
+						bones.Add(boneCount);
+						for (int nn = i + boneCount * 4; i < nn; ) {
+							bones.Add((int)vertices[i]);
+							weights.Add(vertices[i + 1] * scale);
+							weights.Add(vertices[i + 2] * scale);
+							weights.Add(vertices[i + 3]);
+							i += 4;
+						}
+					}
+					mesh.SetMesh(bones.ToArray(), weights.ToArray(), triangles, uvs);
+
+					if (map.ContainsKey("color")) {
+						var color = (String)map["color"];
+						mesh.r = ToColor(color, 0);
+						mesh.g = ToColor(color, 1);
+						mesh.b = ToColor(color, 2);
+						mesh.a = ToColor(color, 3);
+					}
+
+					mesh.HullLength = GetInt(map, "hull", 0) * 2;
+					if (map.ContainsKey("edges")) mesh.Edges = GetIntArray(map, "edges");
+					mesh.Width = GetInt(map, "width", 0) * Scale;
+					mesh.Height = GetInt(map, "height", 0) * Scale;
+
+					return mesh;
+				}
+			case AttachmentType.boundingbox:
+				BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name);
+				if (box == null) return null;
+				box.vertices = GetFloatArray(map, "vertices", Scale);
+				return box;
 			}
 			}
+			return null;
+		}
 
 
-			BoundingBoxAttachment boundingBox = attachment as BoundingBoxAttachment;
-			if (boundingBox != null) {
-				List<Object> values = (List<Object>)map["vertices"];
-				float[] vertices = new float[values.Count];
-				for (int i = 0, n = values.Count; i < n; i++)
-					vertices[i] = (float)values[i] * Scale;
-				boundingBox.Vertices = vertices;
+		private float[] GetFloatArray (Dictionary<String, Object> map, String name, float scale) {
+			var list = (List<Object>)map[name];
+			var values = new float[list.Count];
+			if (scale == 1) {
+				for (int i = 0, n = list.Count; i < n; i++)
+					values[i] = (float)list[i];
+			} else {
+				for (int i = 0, n = list.Count; i < n; i++)
+					values[i] = (float)list[i] * scale;
 			}
 			}
+			return values;
+		}
 
 
-			return attachment;
+		private int[] GetIntArray (Dictionary<String, Object> map, String name) {
+			var list = (List<Object>)map[name];
+			var values = new int[list.Count];
+			for (int i = 0, n = list.Count; i < n; i++)
+				values[i] = (int)(float)list[i];
+			return values;
 		}
 		}
 
 
 		private float GetFloat (Dictionary<String, Object> map, String name, float defaultValue) {
 		private float GetFloat (Dictionary<String, Object> map, String name, float defaultValue) {
@@ -246,6 +340,7 @@ namespace Spine {
 		private void ReadAnimation (String name, Dictionary<String, Object> map, SkeletonData skeletonData) {
 		private void ReadAnimation (String name, Dictionary<String, Object> map, SkeletonData skeletonData) {
 			var timelines = new List<Timeline>();
 			var timelines = new List<Timeline>();
 			float duration = 0;
 			float duration = 0;
+			float scale = Scale;
 
 
 			if (map.ContainsKey("bones")) {
 			if (map.ContainsKey("bones")) {
 				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["bones"]) {
 				foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["bones"]) {
@@ -257,9 +352,9 @@ namespace Spine {
 					var timelineMap = (Dictionary<String, Object>)entry.Value;
 					var timelineMap = (Dictionary<String, Object>)entry.Value;
 					foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
 					foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
 						var values = (List<Object>)timelineEntry.Value;
 						var values = (List<Object>)timelineEntry.Value;
-						String timelineName = (String)timelineEntry.Key;
+						var timelineName = (String)timelineEntry.Key;
 						if (timelineName.Equals("rotate")) {
 						if (timelineName.Equals("rotate")) {
-							RotateTimeline timeline = new RotateTimeline(values.Count);
+							var timeline = new RotateTimeline(values.Count);
 							timeline.boneIndex = boneIndex;
 							timeline.boneIndex = boneIndex;
 
 
 							int frameIndex = 0;
 							int frameIndex = 0;
@@ -279,7 +374,7 @@ namespace Spine {
 								timeline = new ScaleTimeline(values.Count);
 								timeline = new ScaleTimeline(values.Count);
 							else {
 							else {
 								timeline = new TranslateTimeline(values.Count);
 								timeline = new TranslateTimeline(values.Count);
-								timelineScale = Scale;
+								timelineScale = scale;
 							}
 							}
 							timeline.boneIndex = boneIndex;
 							timeline.boneIndex = boneIndex;
 
 
@@ -309,9 +404,9 @@ namespace Spine {
 
 
 					foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
 					foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
 						var values = (List<Object>)timelineEntry.Value;
 						var values = (List<Object>)timelineEntry.Value;
-						String timelineName = (String)timelineEntry.Key;
+						var timelineName = (String)timelineEntry.Key;
 						if (timelineName.Equals("color")) {
 						if (timelineName.Equals("color")) {
-							ColorTimeline timeline = new ColorTimeline(values.Count);
+							var timeline = new ColorTimeline(values.Count);
 							timeline.slotIndex = slotIndex;
 							timeline.slotIndex = slotIndex;
 
 
 							int frameIndex = 0;
 							int frameIndex = 0;
@@ -326,7 +421,7 @@ namespace Spine {
 							duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]);
 							duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]);
 
 
 						} else if (timelineName.Equals("attachment")) {
 						} else if (timelineName.Equals("attachment")) {
-							AttachmentTimeline timeline = new AttachmentTimeline(values.Count);
+							var timeline = new AttachmentTimeline(values.Count);
 							timeline.slotIndex = slotIndex;
 							timeline.slotIndex = slotIndex;
 
 
 							int frameIndex = 0;
 							int frameIndex = 0;
@@ -343,26 +438,68 @@ namespace Spine {
 				}
 				}
 			}
 			}
 
 
-			if (map.ContainsKey("events")) {
-				var eventsMap = (List<Object>)map["events"];
-				EventTimeline timeline = new EventTimeline(eventsMap.Count);
-				int frameIndex = 0;
-				foreach (Dictionary<String, Object> eventMap in eventsMap) {
-					EventData eventData = skeletonData.FindEvent((String)eventMap["name"]);
-					if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
-					Event e = new Event(eventData);
-					e.Int = GetInt(eventMap, "int", eventData.Int);
-					e.Float = GetFloat(eventMap, "float", eventData.Float);
-					e.String = GetString(eventMap, "string", eventData.String);
-					timeline.setFrame(frameIndex++, (float)eventMap["time"], e);
+			if (map.ContainsKey("ffd")) {
+				foreach (KeyValuePair<String, Object> ffdMap in (Dictionary<String, Object>)map["ffd"]) {
+					Skin skin = skeletonData.FindSkin(ffdMap.Key);
+					foreach (KeyValuePair<String, Object> slotMap in (Dictionary<String, Object>)ffdMap.Value) {
+						int slotIndex = skeletonData.FindSlotIndex(slotMap.Key);
+						foreach (KeyValuePair<String, Object> meshMap in (Dictionary<String, Object>)slotMap.Value) {
+							var values = (List<Object>)meshMap.Value;
+							var timeline = new FFDTimeline(values.Count);
+							Attachment attachment = skin.GetAttachment(slotIndex, meshMap.Key);
+							if (attachment == null) throw new Exception("FFD attachment not found: " + meshMap.Key);
+							timeline.slotIndex = slotIndex;
+							timeline.attachment = attachment;
+
+							int frameIndex = 0;
+							foreach (Dictionary<String, Object> valueMap in values) {
+								float[] vertices;
+								int vertexCount;
+								if (attachment is MeshAttachment)
+									vertexCount = ((MeshAttachment)attachment).vertices.Length;
+								// BOZO
+								else
+									vertexCount = 0;
+								// else
+								//	vertexCount = ((SkinnedMeshAttachment)attachment).Weights.Length / 3 * 2;
+
+								if (!valueMap.ContainsKey("vertices")) {
+									if (attachment is MeshAttachment)
+										vertices = ((MeshAttachment)attachment).vertices;
+									else
+										vertices = new float[vertexCount];
+								} else {
+									var verticesValue = (List<Object>)valueMap["vertices"];
+									vertices = new float[vertexCount];
+									int start = GetInt(valueMap, "offset", 0);
+									if (scale == 1) {
+										for (int i = 0, n = verticesValue.Count; i < n; i++)
+											vertices[i + start] = (float)verticesValue[i];
+									} else {
+										for (int i = 0, n = verticesValue.Count; i < n; i++)
+											vertices[i + start] = (float)verticesValue[i] * scale;
+									}
+									if (attachment is MeshAttachment) {
+										float[] meshVertices = ((MeshAttachment)attachment).vertices;
+										for (int i = 0, n = vertices.Length; i < n; i++)
+											vertices[i] += meshVertices[i];
+									}
+								}
+
+								timeline.setFrame(frameIndex, (float)valueMap["time"], vertices);
+								ReadCurve(timeline, frameIndex, valueMap);
+								frameIndex++;
+							}
+							timelines.Add(timeline);
+							duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
+						}
+					}
 				}
 				}
-				timelines.Add(timeline);
-				duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
 			}
 			}
 
 
 			if (map.ContainsKey("draworder")) {
 			if (map.ContainsKey("draworder")) {
 				var values = (List<Object>)map["draworder"];
 				var values = (List<Object>)map["draworder"];
-				DrawOrderTimeline timeline = new DrawOrderTimeline(values.Count);
+				var timeline = new DrawOrderTimeline(values.Count);
 				int slotCount = skeletonData.slots.Count;
 				int slotCount = skeletonData.slots.Count;
 				int frameIndex = 0;
 				int frameIndex = 0;
 				foreach (Dictionary<String, Object> drawOrderMap in values) {
 				foreach (Dictionary<String, Object> drawOrderMap in values) {
@@ -371,7 +508,7 @@ namespace Spine {
 						drawOrder = new int[slotCount];
 						drawOrder = new int[slotCount];
 						for (int i = slotCount - 1; i >= 0; i--)
 						for (int i = slotCount - 1; i >= 0; i--)
 							drawOrder[i] = -1;
 							drawOrder[i] = -1;
-						List<Object> offsets = (List<Object>)drawOrderMap["offsets"];
+						var offsets = (List<Object>)drawOrderMap["offsets"];
 						int[] unchanged = new int[slotCount - offsets.Count];
 						int[] unchanged = new int[slotCount - offsets.Count];
 						int originalIndex = 0, unchangedIndex = 0;
 						int originalIndex = 0, unchangedIndex = 0;
 						foreach (Dictionary<String, Object> offsetMap in offsets) {
 						foreach (Dictionary<String, Object> offsetMap in offsets) {
@@ -396,6 +533,23 @@ namespace Spine {
 				duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
 				duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
 			}
 			}
 
 
+			if (map.ContainsKey("events")) {
+				var eventsMap = (List<Object>)map["events"];
+				var timeline = new EventTimeline(eventsMap.Count);
+				int frameIndex = 0;
+				foreach (Dictionary<String, Object> eventMap in eventsMap) {
+					EventData eventData = skeletonData.FindEvent((String)eventMap["name"]);
+					if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
+					var e = new Event(eventData);
+					e.Int = GetInt(eventMap, "int", eventData.Int);
+					e.Float = GetFloat(eventMap, "float", eventData.Float);
+					e.String = GetString(eventMap, "string", eventData.String);
+					timeline.setFrame(frameIndex++, (float)eventMap["time"], e);
+				}
+				timelines.Add(timeline);
+				duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
+			}
+
 			timelines.TrimExcess();
 			timelines.TrimExcess();
 			skeletonData.AddAnimation(new Animation(name, timelines, duration));
 			skeletonData.AddAnimation(new Animation(name, timelines, duration));
 		}
 		}
@@ -407,7 +561,7 @@ namespace Spine {
 			if (curveObject.Equals("stepped"))
 			if (curveObject.Equals("stepped"))
 				timeline.SetStepped(frameIndex);
 				timeline.SetStepped(frameIndex);
 			else if (curveObject is List<Object>) {
 			else if (curveObject is List<Object>) {
-				List<Object> curve = (List<Object>)curveObject;
+				var curve = (List<Object>)curveObject;
 				timeline.SetCurve(frameIndex, (float)curve[0], (float)curve[1], (float)curve[2], (float)curve[3]);
 				timeline.SetCurve(frameIndex, (float)curve[0], (float)curve[1], (float)curve[2], (float)curve[3]);
 			}
 			}
 		}
 		}

+ 7 - 0
spine-csharp/src/Slot.cs

@@ -38,6 +38,8 @@ namespace Spine {
 		internal float r, g, b, a;
 		internal float r, g, b, a;
 		internal float attachmentTime;
 		internal float attachmentTime;
 		internal Attachment attachment;
 		internal Attachment attachment;
+		internal float[] attachmentVertices = new float[0];
+		internal int attachmentVerticesCount;
 
 
 		public SlotData Data { get { return data; } }
 		public SlotData Data { get { return data; } }
 		public Bone Bone { get { return bone; } }
 		public Bone Bone { get { return bone; } }
@@ -55,6 +57,7 @@ namespace Spine {
 			set {
 			set {
 				attachment = value;
 				attachment = value;
 				attachmentTime = skeleton.time;
 				attachmentTime = skeleton.time;
+				attachmentVerticesCount = 0;
 			}
 			}
 		}
 		}
 
 
@@ -67,6 +70,9 @@ namespace Spine {
 			}
 			}
 		}
 		}
 
 
+		public float[] AttachmentVertices { get { return attachmentVertices; } set { attachmentVertices = value; } }
+		public int AttachmentVerticesCount { get { return attachmentVerticesCount; } set { attachmentVerticesCount = value; } }
+
 		public Slot (SlotData data, Skeleton skeleton, Bone bone) {
 		public Slot (SlotData data, Skeleton skeleton, Bone bone) {
 			if (data == null) throw new ArgumentNullException("data cannot be null.");
 			if (data == null) throw new ArgumentNullException("data cannot be null.");
 			if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
 			if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
@@ -83,6 +89,7 @@ namespace Spine {
 			b = data.b;
 			b = data.b;
 			a = data.a;
 			a = data.a;
 			Attachment = data.attachmentName == null ? null : skeleton.GetAttachment(slotIndex, data.attachmentName);
 			Attachment = data.attachmentName == null ? null : skeleton.GetAttachment(slotIndex, data.attachmentName);
+			attachmentVerticesCount = 0;
 		}
 		}
 
 
 		public void SetToSetupPose () {
 		public void SetToSetupPose () {

+ 22 - 10
spine-tk2d/Assets/Spine/BoneComponent.cs

@@ -44,8 +44,18 @@ public class BoneComponent : MonoBehaviour {
 	/// <summary>If a bone isn't set, boneName is used to find the bone.</summary>
 	/// <summary>If a bone isn't set, boneName is used to find the bone.</summary>
 	public String boneName;
 	public String boneName;
 
 
+	protected Transform cachedTransform;
+	protected Transform skeletonComponentTransform;
+
+	void Awake () {
+		cachedTransform = transform;
+
+		if(skeletonComponent == null) return;
+		skeletonComponentTransform = skeletonComponent.transform;
+	}
+
 	public void LateUpdate () {
 	public void LateUpdate () {
-		if (skeletonComponent == null) return;
+		if (skeletonComponent == null || skeletonComponent.skeleton == null) return;
 		if (bone == null) {
 		if (bone == null) {
 			if (boneName == null) return;
 			if (boneName == null) return;
 			bone = skeletonComponent.skeleton.FindBone(boneName);
 			bone = skeletonComponent.skeleton.FindBone(boneName);
@@ -54,16 +64,18 @@ public class BoneComponent : MonoBehaviour {
 				return;
 				return;
 			}
 			}
 		}
 		}
-		if (transform.parent == skeletonComponent.transform) {
-			transform.localPosition = new Vector3(bone.worldX, bone.worldY, transform.localPosition.z);
-			Vector3 rotation = transform.localRotation.eulerAngles;
-			transform.localRotation = Quaternion.Euler(rotation.x, rotation.y, bone.worldRotation);
+
+		if (cachedTransform.parent == skeletonComponentTransform) {
+			cachedTransform.localPosition = new Vector3(bone.worldX, bone.worldY, cachedTransform.localPosition.z);
+			Vector3 rotation = cachedTransform.localRotation.eulerAngles;
+			cachedTransform.localRotation = Quaternion.Euler(rotation.x, rotation.y, bone.worldRotation);
 		} else {
 		} else {
-			// Best effort to set this GameObject's transform when it isn't a child of the SkeletonComponent.
-			transform.position = skeletonComponent.transform.TransformPoint(new Vector3(bone.worldX, bone.worldY, transform.position.z));
-			Vector3 rotation = skeletonComponent.transform.rotation.eulerAngles;
-			transform.rotation = Quaternion.Euler(rotation.x, rotation.y, 
-			    skeletonComponent.transform.rotation.eulerAngles.z + bone.worldRotation);
+			cachedTransform.position = skeletonComponentTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY, cachedTransform.position.z));
+			Vector3 rotation = skeletonComponentTransform.rotation.eulerAngles;
+			cachedTransform.rotation = Quaternion.Euler(rotation.x, rotation.y, 
+			                                            skeletonComponentTransform.rotation.eulerAngles.z + bone.worldRotation);
 		}
 		}
+
 	}
 	}
+
 }
 }

+ 89 - 38
spine-tk2d/Assets/Spine/SpriteCollectionAttachmentLoader.cs

@@ -36,6 +36,12 @@ using Spine;
 
 
 public class SpriteCollectionAttachmentLoader : AttachmentLoader {
 public class SpriteCollectionAttachmentLoader : AttachmentLoader {
 	private tk2dSpriteCollectionData sprites;
 	private tk2dSpriteCollectionData sprites;
+	private float u, v, u2, v2;
+	private bool regionRotated;
+	private float regionOriginalWidth, regionOriginalHeight;
+	private float regionWidth, regionHeight;
+	private float regionOffsetX, regionOffsetY;
+	private Material material;
 
 
 	public SpriteCollectionAttachmentLoader (tk2dSpriteCollectionData sprites) {
 	public SpriteCollectionAttachmentLoader (tk2dSpriteCollectionData sprites) {
 		if (sprites == null)
 		if (sprites == null)
@@ -43,16 +49,7 @@ public class SpriteCollectionAttachmentLoader : AttachmentLoader {
 		this.sprites = sprites;
 		this.sprites = sprites;
 	}
 	}
 
 
-	public Attachment NewAttachment (Skin skin, AttachmentType type, String name) {
-		switch (type) {
-		case AttachmentType.region:
-			break;
-		case AttachmentType.boundingbox:
-			return new BoundingBoxAttachment(name);
-		default:
-			throw new Exception("Unknown attachment type: " + type);
-		}
-		
+	private void ProcessSpriteDefinition (String name) {
 		// Strip folder names.
 		// Strip folder names.
 		int index = name.LastIndexOfAny(new char[] {'/', '\\'});
 		int index = name.LastIndexOfAny(new char[] {'/', '\\'});
 		if (index != -1)
 		if (index != -1)
@@ -60,52 +57,106 @@ public class SpriteCollectionAttachmentLoader : AttachmentLoader {
 		
 		
 		tk2dSpriteDefinition def = sprites.inst.GetSpriteDefinition(name);
 		tk2dSpriteDefinition def = sprites.inst.GetSpriteDefinition(name);
 		
 		
-		if (def == null)
-			throw new Exception("Sprite not found in atlas: " + name + " (" + type + ")");
+		if (def == null) {
+			Debug.Log("Sprite not found in atlas: " + name, sprites);
+			throw new Exception("Sprite not found in atlas: " + name);
+		}
 		if (def.complexGeometry)
 		if (def.complexGeometry)
-			throw new NotImplementedException("Complex geometry is not supported: " + name + " (" + type + ")");
+			throw new NotImplementedException("Complex geometry is not supported: " + name);
 		if (def.flipped == tk2dSpriteDefinition.FlipMode.TPackerCW)
 		if (def.flipped == tk2dSpriteDefinition.FlipMode.TPackerCW)
-			throw new NotImplementedException("Only 2D Toolkit atlases are supported: " + name + " (" + type + ")");
+			throw new NotImplementedException("Only 2D Toolkit atlases are supported: " + name);
 
 
-		RegionAttachment attachment = new RegionAttachment(name);
-		
-		Vector2 minTexCoords = Vector2.one;
-		Vector2 maxTexCoords = Vector2.zero;
+		Vector2 minTexCoords = Vector2.one, maxTexCoords = Vector2.zero;
 		for (int i = 0; i < def.uvs.Length; ++i) {
 		for (int i = 0; i < def.uvs.Length; ++i) {
 			Vector2 uv = def.uvs[i];
 			Vector2 uv = def.uvs[i];
 			minTexCoords = Vector2.Min(minTexCoords, uv);
 			minTexCoords = Vector2.Min(minTexCoords, uv);
 			maxTexCoords = Vector2.Max(maxTexCoords, uv);
 			maxTexCoords = Vector2.Max(maxTexCoords, uv);
 		}
 		}
-		bool rotated = def.flipped == tk2dSpriteDefinition.FlipMode.Tk2d;
-		if (rotated) {
+		regionRotated = def.flipped == tk2dSpriteDefinition.FlipMode.Tk2d;
+		if (regionRotated) {
 			float temp = minTexCoords.x;
 			float temp = minTexCoords.x;
 			minTexCoords.x = maxTexCoords.x;
 			minTexCoords.x = maxTexCoords.x;
 			maxTexCoords.x = temp;
 			maxTexCoords.x = temp;
 		}
 		}
-		attachment.SetUVs(
-			minTexCoords.x,
-			maxTexCoords.y,
-			maxTexCoords.x,
-			minTexCoords.y,
-			rotated
-		);
-		
-		attachment.RegionOriginalWidth = (int)(def.untrimmedBoundsData[1].x / def.texelSize.x);
-		attachment.RegionOriginalHeight = (int)(def.untrimmedBoundsData[1].y / def.texelSize.y);
-
-		attachment.RegionWidth = (int)(def.boundsData[1].x / def.texelSize.x);
-		attachment.RegionHeight = (int)(def.boundsData[1].y / def.texelSize.y);
+		u = minTexCoords.x;
+		v = maxTexCoords.y;
+		u2 = maxTexCoords.x;
+		v2 = minTexCoords.y;
 
 
+		regionOriginalWidth = (int)(def.untrimmedBoundsData[1].x / def.texelSize.x);
+		regionOriginalHeight = (int)(def.untrimmedBoundsData[1].y / def.texelSize.y);
+		
+		regionWidth = (int)(def.boundsData[1].x / def.texelSize.x);
+		regionHeight = (int)(def.boundsData[1].y / def.texelSize.y);
+		
 		float x0 = def.untrimmedBoundsData[0].x - def.untrimmedBoundsData[1].x / 2;
 		float x0 = def.untrimmedBoundsData[0].x - def.untrimmedBoundsData[1].x / 2;
 		float x1 = def.boundsData[0].x - def.boundsData[1].x / 2;
 		float x1 = def.boundsData[0].x - def.boundsData[1].x / 2;
-		attachment.RegionOffsetX = (int)((x1 - x0) / def.texelSize.x);
-
+		regionOffsetX = (int)((x1 - x0) / def.texelSize.x);
+		
 		float y0 = def.untrimmedBoundsData[0].y - def.untrimmedBoundsData[1].y / 2;
 		float y0 = def.untrimmedBoundsData[0].y - def.untrimmedBoundsData[1].y / 2;
 		float y1 = def.boundsData[0].y - def.boundsData[1].y / 2;
 		float y1 = def.boundsData[0].y - def.boundsData[1].y / 2;
-		attachment.RegionOffsetY = (int)((y1 - y0) / def.texelSize.y);
+		regionOffsetY = (int)((y1 - y0) / def.texelSize.y);
+
+		material = def.material;
+	}
 
 
-		attachment.RendererObject = def.material;
+	public RegionAttachment NewRegionAttachment (Skin skin, String name, String path) {
+		ProcessSpriteDefinition(path);
+		
+		RegionAttachment region = new RegionAttachment(name);
+		region.Path = path;
+		region.RendererObject = material;
+		region.SetUVs(u, v, u2, v2, regionRotated);
+		region.RegionOriginalWidth = regionOriginalWidth;
+		region.RegionOriginalHeight = regionOriginalHeight;
+		region.RegionWidth = regionWidth;
+		region.RegionHeight = regionHeight;
+		region.RegionOffsetX = regionOffsetX;
+		region.RegionOffsetY = regionOffsetY;
+		return region;
+	}
+	
+	public MeshAttachment NewMeshAttachment (Skin skin, String name, String path) {
+		ProcessSpriteDefinition(path);
+		
+		MeshAttachment mesh = new MeshAttachment(name);
+		mesh.Path = path;
+		mesh.RendererObject = material;
+		mesh.RegionU = u;
+		mesh.RegionV = v;
+		mesh.RegionU2 = u2;
+		mesh.RegionV2 = v2;
+		mesh.RegionRotate = regionRotated;
+		mesh.RegionOriginalWidth = regionOriginalWidth;
+		mesh.RegionOriginalHeight = regionOriginalHeight;
+		mesh.RegionWidth = regionWidth;
+		mesh.RegionHeight = regionHeight;
+		mesh.RegionOffsetX = regionOffsetX;
+		mesh.RegionOffsetY = regionOffsetY;
+		return mesh;
+	}
+	
+	public SkinnedMeshAttachment NewSkinnedMeshAttachment (Skin skin, String name, String path) {
+		ProcessSpriteDefinition(path);
+		
+		SkinnedMeshAttachment mesh = new SkinnedMeshAttachment(name);
+		mesh.Path = path;
+		mesh.RendererObject = material;
+		mesh.RegionU = u;
+		mesh.RegionV = v;
+		mesh.RegionU2 = u2;
+		mesh.RegionV2 = v2;
+		mesh.RegionRotate = regionRotated;
+		mesh.RegionOriginalWidth = regionOriginalWidth;
+		mesh.RegionOriginalHeight = regionOriginalHeight;
+		mesh.RegionWidth = regionWidth;
+		mesh.RegionHeight = regionHeight;
+		mesh.RegionOffsetX = regionOffsetX;
+		mesh.RegionOffsetY = regionOffsetY;
+		return mesh;
+	}
 
 
-		return attachment;
+	public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, String name) {
+		return new BoundingBoxAttachment(name);
 	}
 	}
 }
 }

二進制
spine-tk2d/Assets/examples/spineboy/Spineboy SkeletonData.asset


+ 2 - 2
spine-tk2d/Assets/examples/spineboy/Spineboy.cs

@@ -44,7 +44,7 @@ public class Spineboy : MonoBehaviour {
 		// Queue jump to be played on track 0 after the starting animation.
 		// Queue jump to be played on track 0 after the starting animation.
 		skeletonAnimation.state.AddAnimation(0, "jump", false, 0);
 		skeletonAnimation.state.AddAnimation(0, "jump", false, 0);
 		// Queue walk to be looped on track 0 after the jump animation.
 		// Queue walk to be looped on track 0 after the jump animation.
-		skeletonAnimation.state.AddAnimation(0, "walk", true, 0);
+		skeletonAnimation.state.AddAnimation(0, "run", true, 0);
 	}
 	}
 
 
 	public void Event (Spine.AnimationState state, int trackIndex, Spine.Event e) {
 	public void Event (Spine.AnimationState state, int trackIndex, Spine.Event e) {
@@ -55,6 +55,6 @@ public class Spineboy : MonoBehaviour {
 		// Set jump to be played on track 0 immediately.
 		// Set jump to be played on track 0 immediately.
 		skeletonAnimation.state.SetAnimation(0, "jump", false);
 		skeletonAnimation.state.SetAnimation(0, "jump", false);
 		// Queue walk to be looped on track 0 after the jump animation.
 		// Queue walk to be looped on track 0 after the jump animation.
-		skeletonAnimation.state.AddAnimation(0, "walk", true, 0);
+		skeletonAnimation.state.AddAnimation(0, "run", true, 0);
 	}
 	}
 }
 }

二進制
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/SpineboyAtlas.prefab


二進制
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas0 material.mat


二進制
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas0.png


+ 10 - 1
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas0.png.meta

@@ -21,7 +21,7 @@ TextureImporter:
   generateCubemap: 0
   generateCubemap: 0
   seamlessCubemap: 0
   seamlessCubemap: 0
   textureFormat: -3
   textureFormat: -3
-  maxTextureSize: 512
+  maxTextureSize: 1024
   textureSettings:
   textureSettings:
     filterMode: 1
     filterMode: 1
     aniso: 1
     aniso: 1
@@ -30,7 +30,16 @@ TextureImporter:
   nPOTScale: 1
   nPOTScale: 1
   lightmap: 0
   lightmap: 0
   compressionQuality: 50
   compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
   alphaIsTransparency: 0
   alphaIsTransparency: 0
   textureType: -1
   textureType: -1
   buildTargetSettings: []
   buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
   userData: 
   userData: 

二進制
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas1 material.mat


+ 0 - 4
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas1 material.mat.meta

@@ -1,4 +0,0 @@
-fileFormatVersion: 2
-guid: 60e10894b87b9d94ea8c33e508c0554e
-NativeFormatImporter:
-  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas1.png


+ 0 - 36
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas1.png.meta

@@ -1,36 +0,0 @@
-fileFormatVersion: 2
-guid: 9375159065701de4bb882f13633b17a9
-TextureImporter:
-  serializedVersion: 2
-  mipmaps:
-    mipMapMode: 0
-    enableMipMap: 0
-    linearTexture: 0
-    correctGamma: 0
-    fadeOut: 0
-    borderMipMap: 0
-    mipMapFadeDistanceStart: 1
-    mipMapFadeDistanceEnd: 3
-  bumpmap:
-    convertToNormalMap: 0
-    externalNormalMap: 0
-    heightScale: .25
-    normalMapFilter: 0
-  isReadable: 0
-  grayScaleToAlpha: 0
-  generateCubemap: 0
-  seamlessCubemap: 0
-  textureFormat: -3
-  maxTextureSize: 512
-  textureSettings:
-    filterMode: 1
-    aniso: 1
-    mipBias: -1
-    wrapMode: 1
-  nPOTScale: 1
-  lightmap: 0
-  compressionQuality: 50
-  alphaIsTransparency: 0
-  textureType: -1
-  buildTargetSettings: []
-  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas2 material.mat


+ 0 - 4
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas2 material.mat.meta

@@ -1,4 +0,0 @@
-fileFormatVersion: 2
-guid: 52a0c49b9eed9494ba69c9ca457348a3
-NativeFormatImporter:
-  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas2.png


+ 0 - 36
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas Data/atlas2.png.meta

@@ -1,36 +0,0 @@
-fileFormatVersion: 2
-guid: 8295a1db0683dbc41a2a5c1d86adbc69
-TextureImporter:
-  serializedVersion: 2
-  mipmaps:
-    mipMapMode: 0
-    enableMipMap: 0
-    linearTexture: 0
-    correctGamma: 0
-    fadeOut: 0
-    borderMipMap: 0
-    mipMapFadeDistanceStart: 1
-    mipMapFadeDistanceEnd: 3
-  bumpmap:
-    convertToNormalMap: 0
-    externalNormalMap: 0
-    heightScale: .25
-    normalMapFilter: 0
-  isReadable: 0
-  grayScaleToAlpha: 0
-  generateCubemap: 0
-  seamlessCubemap: 0
-  textureFormat: -3
-  maxTextureSize: 512
-  textureSettings:
-    filterMode: 1
-    aniso: 1
-    mipBias: -1
-    wrapMode: 1
-  nPOTScale: 1
-  lightmap: 0
-  compressionQuality: 50
-  alphaIsTransparency: 0
-  textureType: -1
-  buildTargetSettings: []
-  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/SpineboyAtlas.prefab


二進制
spine-tk2d/Assets/examples/spineboy/images/eye_indifferent.png


+ 11 - 2
spine-tk2d/Assets/examples/spineboy/images/left-ankle.png.meta → spine-tk2d/Assets/examples/spineboy/images/eye_indifferent.png.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
 fileFormatVersion: 2
-guid: 01e73ca366ce3b54bb4087bf34ea3780
+guid: 6c0af3682888d1b44b20930c007395ed
 TextureImporter:
 TextureImporter:
   serializedVersion: 2
   serializedVersion: 2
   mipmaps:
   mipmaps:
@@ -30,7 +30,16 @@ TextureImporter:
   nPOTScale: 0
   nPOTScale: 0
   lightmap: 0
   lightmap: 0
   compressionQuality: 50
   compressionQuality: 50
-  alphaIsTransparency: 0
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
   textureType: 5
   textureType: 5
   buildTargetSettings: []
   buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
   userData: 
   userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/eye_surprised.png


+ 11 - 2
spine-tk2d/Assets/examples/spineboy/images/eyes-closed.png.meta → spine-tk2d/Assets/examples/spineboy/images/eye_surprised.png.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
 fileFormatVersion: 2
-guid: bab2bc2171d249048990e56ff8dc150e
+guid: ae61740dcd21c2a4c9664f29d3c4648d
 TextureImporter:
 TextureImporter:
   serializedVersion: 2
   serializedVersion: 2
   mipmaps:
   mipmaps:
@@ -30,7 +30,16 @@ TextureImporter:
   nPOTScale: 0
   nPOTScale: 0
   lightmap: 0
   lightmap: 0
   compressionQuality: 50
   compressionQuality: 50
-  alphaIsTransparency: 0
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
   textureType: 5
   textureType: 5
   buildTargetSettings: []
   buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
   userData: 
   userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/eyes-closed.png


二進制
spine-tk2d/Assets/examples/spineboy/images/eyes.png


二進制
spine-tk2d/Assets/examples/spineboy/images/front_bracer.png


+ 11 - 2
spine-tk2d/Assets/examples/spineboy/images/eyes.png.meta → spine-tk2d/Assets/examples/spineboy/images/front_bracer.png.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
 fileFormatVersion: 2
-guid: e8d06d84fe3fb0940aebd89e50186b67
+guid: f49cadc7ea01b0a4d9e4a54b43f9ae81
 TextureImporter:
 TextureImporter:
   serializedVersion: 2
   serializedVersion: 2
   mipmaps:
   mipmaps:
@@ -30,7 +30,16 @@ TextureImporter:
   nPOTScale: 0
   nPOTScale: 0
   lightmap: 0
   lightmap: 0
   compressionQuality: 50
   compressionQuality: 50
-  alphaIsTransparency: 0
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
   textureType: 5
   textureType: 5
   buildTargetSettings: []
   buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
   userData: 
   userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/front_fist_closed.png


+ 11 - 2
spine-tk2d/Assets/examples/spineboy/images/left-arm.png.meta → spine-tk2d/Assets/examples/spineboy/images/front_fist_closed.png.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
 fileFormatVersion: 2
-guid: 64d2ee256e7837243ae969fabe2abf13
+guid: a29fc9a5b299a584e8ef5c9fdf41b165
 TextureImporter:
 TextureImporter:
   serializedVersion: 2
   serializedVersion: 2
   mipmaps:
   mipmaps:
@@ -30,7 +30,16 @@ TextureImporter:
   nPOTScale: 0
   nPOTScale: 0
   lightmap: 0
   lightmap: 0
   compressionQuality: 50
   compressionQuality: 50
-  alphaIsTransparency: 0
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
   textureType: 5
   textureType: 5
   buildTargetSettings: []
   buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
   userData: 
   userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/front_fist_open.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/front_fist_open.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: f3263dfbb157c5043b33839d0bbf4990
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/front_foot.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/front_foot.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: c79a35fcc3cc51a438b2e2a17982a1f7
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/front_foot_bend1.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/front_foot_bend1.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 7b87c0f427cf2d64d81bf787019c8211
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/front_foot_bend2.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/front_foot_bend2.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: b3ff63c911a51b0459e1a517f1408b4a
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/front_shin.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/front_shin.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 30ef0c5f7aace9246916ecd9b26cc1c9
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/front_thigh.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/front_thigh.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 205489628a41ef844bd13b946db011fa
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/front_upper_arm.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/front_upper_arm.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: cd1afb74c1b04dc49b5a148610c03839
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/goggles.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/goggles.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: d765c8c54164b8a4fb9e39e197dc0a38
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/gun.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/gun.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 0d603abca31d5994691350ac735c7744
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/head.png


+ 10 - 1
spine-tk2d/Assets/examples/spineboy/images/head.png.meta

@@ -30,7 +30,16 @@ TextureImporter:
   nPOTScale: 0
   nPOTScale: 0
   lightmap: 0
   lightmap: 0
   compressionQuality: 50
   compressionQuality: 50
-  alphaIsTransparency: 0
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
   textureType: 5
   textureType: 5
   buildTargetSettings: []
   buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
   userData: 
   userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/left-ankle.png


二進制
spine-tk2d/Assets/examples/spineboy/images/left-arm.png


二進制
spine-tk2d/Assets/examples/spineboy/images/left-foot.png


+ 0 - 36
spine-tk2d/Assets/examples/spineboy/images/left-foot.png.meta

@@ -1,36 +0,0 @@
-fileFormatVersion: 2
-guid: fdb6e092284153146b14ad82b936112c
-TextureImporter:
-  serializedVersion: 2
-  mipmaps:
-    mipMapMode: 0
-    enableMipMap: 0
-    linearTexture: 0
-    correctGamma: 0
-    fadeOut: 0
-    borderMipMap: 0
-    mipMapFadeDistanceStart: 1
-    mipMapFadeDistanceEnd: 3
-  bumpmap:
-    convertToNormalMap: 0
-    externalNormalMap: 0
-    heightScale: .25
-    normalMapFilter: 0
-  isReadable: 1
-  grayScaleToAlpha: 0
-  generateCubemap: 0
-  seamlessCubemap: 0
-  textureFormat: -3
-  maxTextureSize: 4096
-  textureSettings:
-    filterMode: -1
-    aniso: -1
-    mipBias: -1
-    wrapMode: -1
-  nPOTScale: 0
-  lightmap: 0
-  compressionQuality: 50
-  alphaIsTransparency: 0
-  textureType: 5
-  buildTargetSettings: []
-  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/left-hand.png


+ 0 - 36
spine-tk2d/Assets/examples/spineboy/images/left-hand.png.meta

@@ -1,36 +0,0 @@
-fileFormatVersion: 2
-guid: 4164e461833c7ad4991d0df2f53506c5
-TextureImporter:
-  serializedVersion: 2
-  mipmaps:
-    mipMapMode: 0
-    enableMipMap: 0
-    linearTexture: 0
-    correctGamma: 0
-    fadeOut: 0
-    borderMipMap: 0
-    mipMapFadeDistanceStart: 1
-    mipMapFadeDistanceEnd: 3
-  bumpmap:
-    convertToNormalMap: 0
-    externalNormalMap: 0
-    heightScale: .25
-    normalMapFilter: 0
-  isReadable: 1
-  grayScaleToAlpha: 0
-  generateCubemap: 0
-  seamlessCubemap: 0
-  textureFormat: -3
-  maxTextureSize: 4096
-  textureSettings:
-    filterMode: -1
-    aniso: -1
-    mipBias: -1
-    wrapMode: -1
-  nPOTScale: 0
-  lightmap: 0
-  compressionQuality: 50
-  alphaIsTransparency: 0
-  textureType: 5
-  buildTargetSettings: []
-  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/left-lower-leg.png


+ 0 - 36
spine-tk2d/Assets/examples/spineboy/images/left-lower-leg.png.meta

@@ -1,36 +0,0 @@
-fileFormatVersion: 2
-guid: beb8b29b06f1b8a4bbe29f7ba3947435
-TextureImporter:
-  serializedVersion: 2
-  mipmaps:
-    mipMapMode: 0
-    enableMipMap: 0
-    linearTexture: 0
-    correctGamma: 0
-    fadeOut: 0
-    borderMipMap: 0
-    mipMapFadeDistanceStart: 1
-    mipMapFadeDistanceEnd: 3
-  bumpmap:
-    convertToNormalMap: 0
-    externalNormalMap: 0
-    heightScale: .25
-    normalMapFilter: 0
-  isReadable: 1
-  grayScaleToAlpha: 0
-  generateCubemap: 0
-  seamlessCubemap: 0
-  textureFormat: -3
-  maxTextureSize: 4096
-  textureSettings:
-    filterMode: -1
-    aniso: -1
-    mipBias: -1
-    wrapMode: -1
-  nPOTScale: 0
-  lightmap: 0
-  compressionQuality: 50
-  alphaIsTransparency: 0
-  textureType: 5
-  buildTargetSettings: []
-  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/left-pant-bottom.png


+ 0 - 36
spine-tk2d/Assets/examples/spineboy/images/left-pant-bottom.png.meta

@@ -1,36 +0,0 @@
-fileFormatVersion: 2
-guid: 6819bb1a487d4e7468d3cca3bc563455
-TextureImporter:
-  serializedVersion: 2
-  mipmaps:
-    mipMapMode: 0
-    enableMipMap: 0
-    linearTexture: 0
-    correctGamma: 0
-    fadeOut: 0
-    borderMipMap: 0
-    mipMapFadeDistanceStart: 1
-    mipMapFadeDistanceEnd: 3
-  bumpmap:
-    convertToNormalMap: 0
-    externalNormalMap: 0
-    heightScale: .25
-    normalMapFilter: 0
-  isReadable: 1
-  grayScaleToAlpha: 0
-  generateCubemap: 0
-  seamlessCubemap: 0
-  textureFormat: -3
-  maxTextureSize: 4096
-  textureSettings:
-    filterMode: -1
-    aniso: -1
-    mipBias: -1
-    wrapMode: -1
-  nPOTScale: 0
-  lightmap: 0
-  compressionQuality: 50
-  alphaIsTransparency: 0
-  textureType: 5
-  buildTargetSettings: []
-  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/left-shoulder.png


+ 0 - 36
spine-tk2d/Assets/examples/spineboy/images/left-shoulder.png.meta

@@ -1,36 +0,0 @@
-fileFormatVersion: 2
-guid: f54c1ea69e95f7b4686801f6e3479ae9
-TextureImporter:
-  serializedVersion: 2
-  mipmaps:
-    mipMapMode: 0
-    enableMipMap: 0
-    linearTexture: 0
-    correctGamma: 0
-    fadeOut: 0
-    borderMipMap: 0
-    mipMapFadeDistanceStart: 1
-    mipMapFadeDistanceEnd: 3
-  bumpmap:
-    convertToNormalMap: 0
-    externalNormalMap: 0
-    heightScale: .25
-    normalMapFilter: 0
-  isReadable: 1
-  grayScaleToAlpha: 0
-  generateCubemap: 0
-  seamlessCubemap: 0
-  textureFormat: -3
-  maxTextureSize: 4096
-  textureSettings:
-    filterMode: -1
-    aniso: -1
-    mipBias: -1
-    wrapMode: -1
-  nPOTScale: 0
-  lightmap: 0
-  compressionQuality: 50
-  alphaIsTransparency: 0
-  textureType: 5
-  buildTargetSettings: []
-  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/left-upper-leg.png


+ 0 - 36
spine-tk2d/Assets/examples/spineboy/images/left-upper-leg.png.meta

@@ -1,36 +0,0 @@
-fileFormatVersion: 2
-guid: 110675c0d21d411469aff96dc86f82b9
-TextureImporter:
-  serializedVersion: 2
-  mipmaps:
-    mipMapMode: 0
-    enableMipMap: 0
-    linearTexture: 0
-    correctGamma: 0
-    fadeOut: 0
-    borderMipMap: 0
-    mipMapFadeDistanceStart: 1
-    mipMapFadeDistanceEnd: 3
-  bumpmap:
-    convertToNormalMap: 0
-    externalNormalMap: 0
-    heightScale: .25
-    normalMapFilter: 0
-  isReadable: 1
-  grayScaleToAlpha: 0
-  generateCubemap: 0
-  seamlessCubemap: 0
-  textureFormat: -3
-  maxTextureSize: 4096
-  textureSettings:
-    filterMode: -1
-    aniso: -1
-    mipBias: -1
-    wrapMode: -1
-  nPOTScale: 0
-  lightmap: 0
-  compressionQuality: 50
-  alphaIsTransparency: 0
-  textureType: 5
-  buildTargetSettings: []
-  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/mouth_grind.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/mouth_grind.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 79978238279f41c4c973d521cabff9be
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/mouth_oooo.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/mouth_oooo.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: f61e69cc476126e43b4e89084bf4ccaa
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/mouth_smile.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/mouth_smile.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 8c5e45a7cc597ca4cae33efcf9c24a05
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/muzzle.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/muzzle.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 9a16764712c632b49a00e17383604fdc
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/neck.png


+ 10 - 1
spine-tk2d/Assets/examples/spineboy/images/neck.png.meta

@@ -30,7 +30,16 @@ TextureImporter:
   nPOTScale: 0
   nPOTScale: 0
   lightmap: 0
   lightmap: 0
   compressionQuality: 50
   compressionQuality: 50
-  alphaIsTransparency: 0
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
   textureType: 5
   textureType: 5
   buildTargetSettings: []
   buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
   userData: 
   userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/pelvis.png


+ 0 - 36
spine-tk2d/Assets/examples/spineboy/images/pelvis.png.meta

@@ -1,36 +0,0 @@
-fileFormatVersion: 2
-guid: da857df5d97ec254388f6aa337550084
-TextureImporter:
-  serializedVersion: 2
-  mipmaps:
-    mipMapMode: 0
-    enableMipMap: 0
-    linearTexture: 0
-    correctGamma: 0
-    fadeOut: 0
-    borderMipMap: 0
-    mipMapFadeDistanceStart: 1
-    mipMapFadeDistanceEnd: 3
-  bumpmap:
-    convertToNormalMap: 0
-    externalNormalMap: 0
-    heightScale: .25
-    normalMapFilter: 0
-  isReadable: 1
-  grayScaleToAlpha: 0
-  generateCubemap: 0
-  seamlessCubemap: 0
-  textureFormat: -3
-  maxTextureSize: 4096
-  textureSettings:
-    filterMode: -1
-    aniso: -1
-    mipBias: -1
-    wrapMode: -1
-  nPOTScale: 0
-  lightmap: 0
-  compressionQuality: 50
-  alphaIsTransparency: 0
-  textureType: 5
-  buildTargetSettings: []
-  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/rear_bracer.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/rear_bracer.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 5b233b54bf15bd84d8f892f7d60f651f
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/rear_foot.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/rear_foot.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 486dbb0e0e31aee47ad78051ffadcb67
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/rear_foot_bend1.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/rear_foot_bend1.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 5d1789963e286334ab3f6964d37caddb
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/rear_foot_bend2.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/rear_foot_bend2.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: ff57e994b04010d458a584f4ed3ba9d8
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/rear_shin.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/rear_shin.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: e035fed7792ebf34ba6424833e244f5e
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/rear_thigh.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/rear_thigh.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: ed18ae5dd9428eb4590274b5620d0dcf
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/rear_upper_arm.png


+ 45 - 0
spine-tk2d/Assets/examples/spineboy/images/rear_upper_arm.png.meta

@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: b7fd5d33d25bd59449a21c8a35dcb1ae
+TextureImporter:
+  serializedVersion: 2
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 0
+    linearTexture: 0
+    correctGamma: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: .25
+    normalMapFilter: 0
+  isReadable: 1
+  grayScaleToAlpha: 0
+  generateCubemap: 0
+  seamlessCubemap: 0
+  textureFormat: -3
+  maxTextureSize: 4096
+  textureSettings:
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapMode: -1
+  nPOTScale: 0
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: .5, y: .5}
+  spritePixelsToUnits: 100
+  alphaIsTransparency: 1
+  textureType: 5
+  buildTargetSettings: []
+  spriteSheet:
+    sprites: []
+  spritePackingTag: 
+  userData: 

二進制
spine-tk2d/Assets/examples/spineboy/images/right-ankle.png


Some files were not shown because too many files changed in this diff