浏览代码

[ue4] Start anew

badlogic 8 年之前
父节点
当前提交
27926682d6
共有 43 个文件被更改,包括 3782 次插入0 次删除
  1. 5 0
      spine-ue4/Config/DefaultEditor.ini
  2. 9 0
      spine-ue4/Config/DefaultEngine.ini
  3. 2 0
      spine-ue4/Config/DefaultGame.ini
  4. 二进制
      spine-ue4/Content/Maps/example.umap
  5. 二进制
      spine-ue4/Content/SpineBoy/Textures/NewPaperSprite.uasset
  6. 二进制
      spine-ue4/Content/SpineBoy/Textures/spineboy.uasset
  7. 216 0
      spine-ue4/Content/SpineBoy/spineboy.atlas
  8. 2419 0
      spine-ue4/Content/SpineBoy/spineboy.json
  9. 二进制
      spine-ue4/Content/SpineBoy/spineboy.png
  10. 二进制
      spine-ue4/Content/SpineBoy/spineboy.skel
  11. 二进制
      spine-ue4/Content/SpineBoy/spineboy.uasset
  12. 27 0
      spine-ue4/LICENSE
  13. 二进制
      spine-ue4/Plugins/SpinePlugin/Resources/Icon128.png
  14. 111 0
      spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineAtlasImportFactory.cpp
  15. 31 0
      spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineEditorPlugin.cpp
  16. 4 0
      spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineEditorPluginPrivatePCH.h
  17. 83 0
      spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineSkeletonImportFactory.cpp
  18. 22 0
      spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Public/SpineAtlasImportFactory.h
  19. 17 0
      spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Public/SpineEditorPlugin.h
  20. 20 0
      spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Public/SpineSkeletonImportFactory.h
  21. 32 0
      spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/SpineEditorPlugin.Build.cs
  22. 82 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineAtlasAsset.cpp
  23. 42 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpinePlugin.cpp
  24. 10 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpinePluginPrivatePCH.h
  25. 65 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp
  26. 79 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonDataAsset.cpp
  27. 118 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonRendererComponent.cpp
  28. 45 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineAtlasAsset.h
  29. 38 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpinePlugin.h
  30. 38 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonComponent.h
  31. 41 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonDataAsset.h
  32. 27 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonRendererComponent.h
  33. 16 0
      spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/SpinePlugin.Build.cs
  34. 29 0
      spine-ue4/Plugins/SpinePlugin/SpinePlugin.uplugin
  35. 29 0
      spine-ue4/README.md
  36. 25 0
      spine-ue4/Source/SpineUE4.Target.cs
  37. 21 0
      spine-ue4/Source/SpineUE4/SpineUE4.Build.cs
  38. 5 0
      spine-ue4/Source/SpineUE4/SpineUE4.cpp
  39. 6 0
      spine-ue4/Source/SpineUE4/SpineUE4.h
  40. 8 0
      spine-ue4/Source/SpineUE4/SpineUE4GameMode.cpp
  41. 19 0
      spine-ue4/Source/SpineUE4/SpineUE4GameMode.h
  42. 25 0
      spine-ue4/Source/SpineUE4Editor.Target.cs
  43. 16 0
      spine-ue4/SpineUE4.uproject

+ 5 - 0
spine-ue4/Config/DefaultEditor.ini

@@ -0,0 +1,5 @@
+[EditoronlyBP]
+bAllowClassAndBlueprintPinMatching=true
+bReplaceBlueprintWithClass=true
+bDontLoadBlueprintOutsideEditor=true
+bBlueprintIsNotBlueprintType=true

+ 9 - 0
spine-ue4/Config/DefaultEngine.ini

@@ -0,0 +1,9 @@
+[URL]
+
+[/Script/HardwareTargeting.HardwareTargetingSettings]
+TargetedHardwareClass=Desktop
+AppliedTargetedHardwareClass=Desktop
+DefaultGraphicsPerformance=Maximum
+AppliedDefaultGraphicsPerformance=Maximum
+
+

+ 2 - 0
spine-ue4/Config/DefaultGame.ini

@@ -0,0 +1,2 @@
+[/Script/EngineSettings.GeneralProjectSettings]
+ProjectID=A32BDAC45F432EB90DF445842A670D58

二进制
spine-ue4/Content/Maps/example.umap


二进制
spine-ue4/Content/SpineBoy/Textures/NewPaperSprite.uasset


二进制
spine-ue4/Content/SpineBoy/Textures/spineboy.uasset


+ 216 - 0
spine-ue4/Content/SpineBoy/spineboy.atlas

@@ -0,0 +1,216 @@
+
+spineboy.png
+size: 1024,1024
+format: RGBA8888
+filter: Linear,Linear
+repeat: none
+eye_indifferent
+  rotate: true
+  xy: 648, 629
+  size: 93, 89
+  orig: 93, 89
+  offset: 0, 0
+  index: -1
+eye_surprised
+  rotate: true
+  xy: 233, 179
+  size: 93, 89
+  orig: 93, 89
+  offset: 0, 0
+  index: -1
+front_bracer
+  rotate: false
+  xy: 245, 2
+  size: 58, 80
+  orig: 58, 80
+  offset: 0, 0
+  index: -1
+front_fist_closed
+  rotate: false
+  xy: 168, 45
+  size: 75, 82
+  orig: 75, 82
+  offset: 0, 0
+  index: -1
+front_fist_open
+  rotate: false
+  xy: 844, 646
+  size: 86, 87
+  orig: 86, 87
+  offset: 0, 0
+  index: -1
+front_foot
+  rotate: true
+  xy: 310, 326
+  size: 126, 69
+  orig: 126, 69
+  offset: 0, 0
+  index: -1
+front_foot_bend1
+  rotate: true
+  xy: 951, 894
+  size: 128, 70
+  orig: 128, 70
+  offset: 0, 0
+  index: -1
+front_foot_bend2
+  rotate: false
+  xy: 2, 33
+  size: 108, 93
+  orig: 108, 93
+  offset: 0, 0
+  index: -1
+front_shin
+  rotate: true
+  xy: 739, 735
+  size: 82, 184
+  orig: 82, 184
+  offset: 0, 0
+  index: -1
+front_thigh
+  rotate: false
+  xy: 381, 340
+  size: 48, 112
+  orig: 48, 112
+  offset: 0, 0
+  index: -1
+front_upper_arm
+  rotate: false
+  xy: 112, 29
+  size: 54, 97
+  orig: 54, 97
+  offset: 0, 0
+  index: -1
+goggles
+  rotate: false
+  xy: 156, 454
+  size: 261, 166
+  orig: 261, 166
+  offset: 0, 0
+  index: -1
+gun
+  rotate: false
+  xy: 739, 819
+  size: 210, 203
+  orig: 210, 203
+  offset: 0, 0
+  index: -1
+head
+  rotate: false
+  xy: 466, 724
+  size: 271, 298
+  orig: 271, 298
+  offset: 0, 0
+  index: -1
+hoverboard_board
+  rotate: true
+  xy: 2, 128
+  size: 492, 152
+  orig: 492, 152
+  offset: 0, 0
+  index: -1
+hoverboard_thruster
+  rotate: false
+  xy: 602, 558
+  size: 60, 64
+  orig: 60, 64
+  offset: 0, 0
+  index: -1
+hoverglow_small
+  rotate: true
+  xy: 156, 178
+  size: 274, 75
+  orig: 274, 75
+  offset: 0, 0
+  index: -1
+mouth_grind
+  rotate: true
+  xy: 951, 799
+  size: 93, 59
+  orig: 93, 59
+  offset: 0, 0
+  index: -1
+mouth_oooo
+  rotate: true
+  xy: 245, 84
+  size: 93, 59
+  orig: 93, 59
+  offset: 0, 0
+  index: -1
+mouth_smile
+  rotate: false
+  xy: 925, 738
+  size: 93, 59
+  orig: 93, 59
+  offset: 0, 0
+  index: -1
+muzzle
+  rotate: false
+  xy: 2, 622
+  size: 462, 400
+  orig: 462, 400
+  offset: 0, 0
+  index: -1
+neck
+  rotate: false
+  xy: 168, 2
+  size: 36, 41
+  orig: 36, 41
+  offset: 0, 0
+  index: -1
+rear_bracer
+  rotate: false
+  xy: 932, 664
+  size: 56, 72
+  orig: 56, 72
+  offset: 0, 0
+  index: -1
+rear_foot
+  rotate: false
+  xy: 487, 562
+  size: 113, 60
+  orig: 113, 60
+  offset: 0, 0
+  index: -1
+rear_foot_bend1
+  rotate: true
+  xy: 419, 503
+  size: 117, 66
+  orig: 117, 66
+  offset: 0, 0
+  index: -1
+rear_foot_bend2
+  rotate: false
+  xy: 739, 650
+  size: 103, 83
+  orig: 103, 83
+  offset: 0, 0
+  index: -1
+rear_shin
+  rotate: false
+  xy: 233, 274
+  size: 75, 178
+  orig: 75, 178
+  offset: 0, 0
+  index: -1
+rear_thigh
+  rotate: true
+  xy: 487, 495
+  size: 65, 104
+  orig: 65, 104
+  offset: 0, 0
+  index: -1
+rear_upper_arm
+  rotate: true
+  xy: 156, 129
+  size: 47, 87
+  orig: 47, 87
+  offset: 0, 0
+  index: -1
+torso
+  rotate: true
+  xy: 466, 624
+  size: 98, 180
+  orig: 98, 180
+  offset: 0, 0
+  index: -1

+ 2419 - 0
spine-ue4/Content/SpineBoy/spineboy.json

@@ -0,0 +1,2419 @@
+{
+"skeleton": {
+	"hash": "H7+xXqKKrnDC1fiM9L7F+WiY4ro",
+	"spine": "3.5.03-beta",
+	"width": 470.9,
+	"height": 731.49,
+	"fps": 30,
+	"images": "./images/"
+},
+"bones": [
+	{ "name": "hip", "y": 247.47 },
+	{ "name": "torso", "parent": "hip", "length": 127.55, "rotation": 103.82, "x": -1.61, "y": 4.9, "color": "e0da19ff" },
+	{ "name": "front_upper_arm", "parent": "torso", "length": 69.45, "rotation": 168.37, "x": 103.75, "y": 19.32, "color": "00ff04ff" },
+	{
+		"name": "front_bracer",
+		"parent": "front_upper_arm",
+		"length": 40.57,
+		"rotation": 18.29,
+		"x": 68.8,
+		"y": -0.68,
+		"color": "00ff04ff"
+	},
+	{ "name": "front_fist", "parent": "front_bracer", "length": 65.38, "rotation": 12.43, "x": 40.56, "y": 0.19, "color": "00ff04ff" },
+	{ "name": "front_thigh", "parent": "hip", "length": 74.8, "rotation": -95.51, "x": -17.45, "y": -11.64, "color": "00ff04ff" },
+	{ "name": "front_shin", "parent": "front_thigh", "length": 128.76, "rotation": -2.21, "x": 78.69, "y": 1.6, "color": "00ff04ff" },
+	{ "name": "front_foot", "parent": "front_shin", "length": 91.34, "rotation": 77.9, "x": 128.75, "y": -0.33, "color": "00ff04ff" },
+	{ "name": "rear_upper_arm", "parent": "torso", "length": 51.93, "rotation": -169.55, "x": 92.35, "y": -19.22, "color": "ff000dff" },
+	{ "name": "rear_bracer", "parent": "rear_upper_arm", "length": 34.55, "rotation": 23.15, "x": 51.35, "color": "ff000dff" },
+	{ "name": "gun", "parent": "rear_bracer", "length": 43.1, "rotation": 5.34, "x": 34.42, "y": -0.45, "color": "ff000dff" },
+	{ "name": "gunTip", "parent": "gun", "rotation": 6.83, "x": 201.04, "y": 52.13, "color": "ff000dff" },
+	{ "name": "neck", "parent": "torso", "length": 25.45, "rotation": -31.53, "x": 127.49, "y": -0.3, "color": "e0da19ff" },
+	{ "name": "head", "parent": "neck", "length": 263.57, "rotation": 23.18, "x": 27.66, "y": -0.25, "color": "e0da19ff" },
+	{ "name": "rear_thigh", "parent": "hip", "length": 85.71, "rotation": -72.54, "x": 8.91, "y": -5.62, "color": "ff000dff" },
+	{ "name": "rear_shin", "parent": "rear_thigh", "length": 121.87, "rotation": -19.83, "x": 86.1, "y": -1.32, "color": "ff000dff" },
+	{ "name": "rear_foot", "parent": "rear_shin", "length": 82.57, "rotation": 69.3, "x": 121.45, "y": -0.75, "color": "ff000dff" }
+],
+"slots": [
+	{ "name": "rear_upper_arm", "bone": "rear_upper_arm", "attachment": "rear_upper_arm" },
+	{ "name": "rear_bracer", "bone": "rear_bracer", "attachment": "rear_bracer" },
+	{ "name": "gun", "bone": "gun", "attachment": "gun" },
+	{ "name": "rear_foot", "bone": "rear_foot", "attachment": "rear_foot" },
+	{ "name": "rear_thigh", "bone": "rear_thigh", "attachment": "rear_thigh" },
+	{ "name": "rear_shin", "bone": "rear_shin", "attachment": "rear_shin" },
+	{ "name": "neck", "bone": "neck", "attachment": "neck" },
+	{ "name": "torso", "bone": "torso", "attachment": "torso" },
+	{ "name": "front_upper_arm", "bone": "front_upper_arm", "attachment": "front_upper_arm" },
+	{ "name": "head", "bone": "head", "attachment": "head" },
+	{ "name": "eye", "bone": "head", "attachment": "eye_indifferent" },
+	{ "name": "front_thigh", "bone": "front_thigh", "attachment": "front_thigh" },
+	{ "name": "front_foot", "bone": "front_foot", "attachment": "front_foot" },
+	{ "name": "front_shin", "bone": "front_shin", "attachment": "front_shin" },
+	{ "name": "mouth", "bone": "head", "attachment": "mouth_smile" },
+	{ "name": "goggles", "bone": "head", "attachment": "goggles" },
+	{ "name": "front_bracer", "bone": "front_bracer", "attachment": "front_bracer" },
+	{ "name": "front_fist", "bone": "front_fist", "attachment": "front_fist_closed" },
+	{ "name": "muzzle", "bone": "gunTip", "blend": "additive" },
+	{ "name": "head-bb", "bone": "head" }
+],
+"skins": {
+	"default": {
+		"eye": {
+			"eye_indifferent": { "x": 85.72, "y": -28.18, "rotation": -70.63, "width": 93, "height": 89 },
+			"eye_surprised": { "x": 85.72, "y": -28.18, "rotation": -70.63, "width": 93, "height": 89 }
+		},
+		"front_bracer": {
+			"front_bracer": { "x": 12.03, "y": -1.67, "rotation": 79.59, "width": 58, "height": 80 }
+		},
+		"front_fist": {
+			"front_fist_closed": { "x": 35.49, "y": 6, "rotation": 67.16, "width": 75, "height": 82 },
+			"front_fist_open": { "x": 39.56, "y": 7.76, "rotation": 67.16, "width": 86, "height": 87 }
+		},
+		"front_foot": {
+			"front_foot": { "x": 29.51, "y": 7.83, "rotation": 18.68, "width": 126, "height": 69 },
+			"front_foot_bend1": { "x": 29.51, "y": 7.83, "rotation": 18.68, "width": 128, "height": 70 },
+			"front_foot_bend2": { "x": 16.07, "y": 13.83, "rotation": 18.68, "width": 108, "height": 93 }
+		},
+		"front_shin": {
+			"front_shin": { "x": 55.11, "y": -3.54, "rotation": 96.59, "width": 82, "height": 184 }
+		},
+		"front_thigh": {
+			"front_thigh": { "x": 42.47, "y": 4.44, "rotation": 84.86, "width": 48, "height": 112 }
+		},
+		"front_upper_arm": {
+			"front_upper_arm": { "x": 28.3, "y": 7.37, "rotation": 97.89, "width": 54, "height": 97 }
+		},
+		"goggles": {
+			"goggles": { "x": 97.07, "y": 6.54, "rotation": -70.63, "width": 261, "height": 166 }
+		},
+		"gun": {
+			"gun": { "x": 77.3, "y": 16.4, "rotation": 60.82, "width": 210, "height": 203 }
+		},
+		"head": {
+			"head": { "x": 128.95, "y": 0.29, "rotation": -70.63, "width": 271, "height": 298 }
+		},
+		"head-bb": {
+			"head": {
+				"type": "boundingbox",
+				"vertexCount": 6,
+				"vertices": [ -19.13999, -70.3, 40.79999, -118.06999, 257.77, -115.61, 285.16, 57.18, 120.76999, 164.95, -5.05999, 76.94 ]
+			}
+		},
+		"mouth": {
+			"mouth_grind": { "x": 23.68, "y": -32.23, "rotation": -70.63, "width": 93, "height": 59 },
+			"mouth_oooo": { "x": 23.68, "y": -32.23, "rotation": -70.63, "width": 93, "height": 59 },
+			"mouth_smile": { "x": 23.68, "y": -32.23, "rotation": -70.63, "width": 93, "height": 59 }
+		},
+		"muzzle": {
+			"muzzle": { "x": 18.25, "y": 5.44, "rotation": 0.15, "width": 462, "height": 400 }
+		},
+		"neck": {
+			"neck": { "x": 9.76, "y": -3.01, "rotation": -55.22, "width": 36, "height": 41 }
+		},
+		"rear_bracer": {
+			"rear_bracer": { "x": 11.15, "y": -2.2, "rotation": 66.17, "width": 56, "height": 72 }
+		},
+		"rear_foot": {
+			"rear_foot": { "x": 31.51, "y": 3.57, "rotation": 23.07, "width": 113, "height": 60 },
+			"rear_foot_bend1": { "x": 34.39, "y": 4.8, "rotation": 23.07, "width": 117, "height": 66 },
+			"rear_foot_bend2": { "x": 30.38, "y": 12.62, "rotation": 23.07, "width": 103, "height": 83 }
+		},
+		"rear_shin": {
+			"rear_shin": { "x": 58.29, "y": -2.75, "rotation": 92.37, "width": 75, "height": 178 }
+		},
+		"rear_thigh": {
+			"rear_thigh": { "x": 33.1, "y": -4.11, "rotation": 72.54, "width": 65, "height": 104 }
+		},
+		"rear_upper_arm": {
+			"rear_upper_arm": { "x": 21.12, "y": 4.08, "rotation": 89.32, "width": 47, "height": 87 }
+		},
+		"torso": {
+			"torso": { "x": 63.61, "y": 7.12, "rotation": -94.53, "width": 98, "height": 180 }
+		}
+	}
+},
+"events": {
+	"footstep": {},
+	"headAttach": { "int": 3, "float": 4 },
+	"headBehind": { "int": 5, "float": 6, "string": "setup" },
+	"headPop": { "int": 1, "float": 2 }
+},
+"animations": {
+	"death": {
+		"slots": {
+			"eye": {
+				"attachment": [
+					{ "time": 0, "name": "eye_surprised" },
+					{ "time": 0.4666, "name": "eye_indifferent" },
+					{ "time": 2.2333, "name": "eye_surprised" },
+					{ "time": 4.5333, "name": "eye_indifferent" }
+				]
+			},
+			"front_fist": {
+				"attachment": [
+					{ "time": 0, "name": "front_fist_open" }
+				]
+			},
+			"mouth": {
+				"attachment": [
+					{ "time": 0, "name": "mouth_oooo" },
+					{ "time": 2.2333, "name": "mouth_grind" },
+					{ "time": 4.5333, "name": "mouth_oooo" }
+				]
+			}
+		},
+		"bones": {
+			"head": {
+				"rotate": [
+					{ "time": 0, "angle": -2.82 },
+					{ "time": 0.1333, "angle": -28.74 },
+					{ "time": 0.2333, "angle": 11.42 },
+					{ "time": 0.3333, "angle": -50.24 },
+					{ "time": 0.4, "angle": -72.66, "curve": "stepped" },
+					{ "time": 0.4333, "angle": -72.66 },
+					{ "time": 0.5, "angle": -20.24 },
+					{ "time": 0.5666, "angle": -85.28, "curve": "stepped" },
+					{ "time": 0.9333, "angle": -85.28, "curve": "stepped" },
+					{ "time": 2.2333, "angle": -85.28 },
+					{ "time": 2.5, "angle": -51.96, "curve": "stepped" },
+					{ "time": 4.5333, "angle": -51.96 },
+					{ "time": 4.6666, "angle": -85.28 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"neck": {
+				"rotate": [
+					{ "time": 0, "angle": -2.82 },
+					{ "time": 0.1333, "angle": 12.35 },
+					{ "time": 0.2333, "angle": 29.89 },
+					{ "time": 0.3, "angle": 70.36 },
+					{ "time": 0.4, "angle": -10.22, "curve": "stepped" },
+					{ "time": 0.4333, "angle": -10.22 },
+					{ "time": 0.5, "angle": 2.92 },
+					{ "time": 0.5666, "angle": 47.94, "curve": "stepped" },
+					{ "time": 2.2333, "angle": 47.94 },
+					{ "time": 2.5, "angle": 18.5, "curve": "stepped" },
+					{ "time": 4.5333, "angle": 18.5 },
+					{ "time": 4.6666, "angle": 47.94 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"torso": {
+				"rotate": [
+					{ "time": 0, "angle": -8.61 },
+					{ "time": 0.1333, "angle": 28.19 },
+					{ "time": 0.2666, "angle": -280.19 },
+					{ "time": 0.4, "angle": -237.22, "curve": "stepped" },
+					{ "time": 0.4333, "angle": -237.22 },
+					{ "time": 0.5, "angle": 76.03, "curve": "stepped" },
+					{ "time": 0.8, "angle": 76.03, "curve": "stepped" },
+					{ "time": 0.9333, "angle": 76.03, "curve": "stepped" },
+					{ "time": 2.2333, "angle": 76.03 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.9333, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 2.2333, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"front_upper_arm": {
+				"rotate": [
+					{ "time": 0, "angle": -38.85 },
+					{ "time": 0.1333, "angle": -299.58 },
+					{ "time": 0.2666, "angle": -244.74 },
+					{ "time": 0.4, "angle": -292.35 },
+					{ "time": 0.4333, "angle": -315.84 },
+					{ "time": 0.5, "angle": -347.94 },
+					{ "time": 0.6999, "angle": -347.33, "curve": "stepped" },
+					{ "time": 2.2333, "angle": -347.33 },
+					{ "time": 2.7, "angle": -290.68 },
+					{ "time": 2.7666, "angle": -285.1 },
+					{ "time": 4.6666, "angle": -290.68 },
+					{ "time": 4.8, "angle": 8.61 },
+					{ "time": 4.8666, "angle": 10.94 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"rear_upper_arm": {
+				"rotate": [
+					{ "time": 0, "angle": -44.69 },
+					{ "time": 0.1333, "angle": 112.26 },
+					{ "time": 0.2666, "angle": 129.07 },
+					{ "time": 0.4, "angle": 134.94, "curve": "stepped" },
+					{ "time": 0.4333, "angle": 134.94 },
+					{ "time": 0.5666, "angle": 172.6, "curve": "stepped" },
+					{ "time": 0.9333, "angle": 172.6, "curve": "stepped" },
+					{ "time": 2.2333, "angle": 172.6 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"front_bracer": {
+				"rotate": [
+					{ "time": 0, "angle": 21.88 },
+					{ "time": 0.1333, "angle": 11.48 },
+					{ "time": 0.2666, "angle": -18.81 },
+					{ "time": 0.4, "angle": -18.92 },
+					{ "time": 0.4333, "angle": -18.28 },
+					{ "time": 0.5, "angle": 60.61 },
+					{ "time": 0.6999, "angle": -18.87, "curve": "stepped" },
+					{ "time": 2.2333, "angle": -18.87 },
+					{ "time": 2.7, "angle": -1.95, "curve": "stepped" },
+					{ "time": 4.6666, "angle": -1.95 },
+					{ "time": 4.8, "angle": 34.55 },
+					{ "time": 4.9333, "angle": -18.74 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"front_fist": {
+				"rotate": [
+					{ "time": 0, "angle": -2.33 },
+					{ "time": 0.2666, "angle": 26.34 },
+					{ "time": 0.6999, "angle": -6.07, "curve": "stepped" },
+					{ "time": 2.2333, "angle": -6.07 },
+					{ "time": 2.7, "angle": 5.72, "curve": "stepped" },
+					{ "time": 4.6666, "angle": 5.72 },
+					{ "time": 4.8666, "angle": -6.52 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"rear_bracer": {
+				"rotate": [
+					{ "time": 0, "angle": 10.36 },
+					{ "time": 0.1333, "angle": -23.12 },
+					{ "time": 0.2666, "angle": -23.11 },
+					{ "time": 0.4, "angle": -23.16, "curve": "stepped" },
+					{ "time": 0.4333, "angle": -23.16 },
+					{ "time": 0.5666, "angle": -23.2, "curve": "stepped" },
+					{ "time": 0.9333, "angle": -23.2, "curve": "stepped" },
+					{ "time": 2.2333, "angle": -23.2 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"gun": {
+				"rotate": [
+					{ "time": 0, "angle": -2.78 },
+					{ "time": 0.1333, "angle": -24.58 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"hip": {
+				"rotate": [
+					{ "time": 0, "angle": 0, "curve": "stepped" },
+					{ "time": 0.9333, "angle": 0, "curve": "stepped" },
+					{ "time": 2.2333, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 },
+					{ "time": 0.2, "x": 50.34, "y": 151.73 },
+					{ "time": 0.4, "x": 5.16, "y": -119.64, "curve": "stepped" },
+					{ "time": 0.4333, "x": 5.16, "y": -119.64 },
+					{ "time": 0.5, "x": 50.34, "y": -205.18, "curve": "stepped" },
+					{ "time": 0.8, "x": 50.34, "y": -205.18, "curve": "stepped" },
+					{ "time": 0.9333, "x": 50.34, "y": -205.18, "curve": "stepped" },
+					{ "time": 2.2333, "x": 50.34, "y": -205.18 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"front_thigh": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.1333, "angle": 8.47 },
+					{ "time": 0.2666, "angle": 115.95 },
+					{ "time": 0.4, "angle": 180.66, "curve": "stepped" },
+					{ "time": 0.4333, "angle": 180.66 },
+					{ "time": 0.5, "angle": 155.22 },
+					{ "time": 0.6, "angle": 97.73 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"front_shin": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.1333, "angle": -27.37 },
+					{ "time": 0.2666, "angle": -35.1 },
+					{ "time": 0.4, "angle": -37.72, "curve": "stepped" },
+					{ "time": 0.4333, "angle": -37.72 },
+					{ "time": 0.5, "angle": -40.06 },
+					{ "time": 0.6, "angle": 2.76 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"rear_thigh": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.1333, "angle": 70.45 },
+					{ "time": 0.2666, "angle": 155.34 },
+					{ "time": 0.4, "angle": 214.31, "curve": "stepped" },
+					{ "time": 0.4333, "angle": 214.31 },
+					{ "time": 0.5, "angle": 169.67 },
+					{ "time": 0.8, "angle": 83.27 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"rear_shin": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.1333, "angle": 18.93 },
+					{ "time": 0.2666, "angle": -21.04 },
+					{ "time": 0.4, "angle": -29.93, "curve": "stepped" },
+					{ "time": 0.4333, "angle": -29.93 },
+					{ "time": 0.5, "angle": -16.79 },
+					{ "time": 0.8, "angle": 7.77 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"rear_foot": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.1333, "angle": -11.62 },
+					{ "time": 0.4, "angle": -45.59, "curve": "stepped" },
+					{ "time": 0.4333, "angle": -45.59 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"front_foot": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.4, "angle": -48.75, "curve": "stepped" },
+					{ "time": 0.4333, "angle": -48.75 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"gunTip": {
+				"rotate": [
+					{ "time": 0, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			}
+		}
+	},
+	"hit": {
+		"slots": {
+			"front_fist": {
+				"attachment": [
+					{ "time": 0.1666, "name": "front_fist_open" }
+				]
+			},
+			"mouth": {
+				"attachment": [
+					{ "time": 0, "name": "mouth_grind" },
+					{ "time": 0.3333, "name": "mouth_smile" }
+				]
+			}
+		},
+		"bones": {
+			"torso": {
+				"rotate": [
+					{ "time": 0, "angle": 56.42 },
+					{ "time": 0.3333, "angle": 8.89 }
+				]
+			},
+			"neck": {
+				"rotate": [
+					{ "time": 0, "angle": 35.38 },
+					{ "time": 0.2333, "angle": 24.94 }
+				]
+			},
+			"head": {
+				"rotate": [
+					{ "time": 0, "angle": 10.21 },
+					{ "time": 0.3333, "angle": -41.3 }
+				]
+			},
+			"front_upper_arm": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -310.92,
+						"curve": [ 0.38, 0.53, 0.744, 1 ]
+					},
+					{ "time": 0.3333, "angle": -112.59 }
+				],
+				"translate": [
+					{ "time": 0, "x": 7.23, "y": -13.13 }
+				]
+			},
+			"front_bracer": {
+				"rotate": [
+					{ "time": 0, "angle": 36.99 },
+					{ "time": 0.3333, "angle": -28.64 }
+				]
+			},
+			"front_fist": {
+				"rotate": [
+					{ "time": 0, "angle": 13.59 },
+					{ "time": 0.3333, "angle": 7.55 }
+				]
+			},
+			"rear_upper_arm": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 271.02,
+						"curve": [ 0.342, 0.36, 0.68, 0.71 ]
+					},
+					{ "time": 0.3333, "angle": -15.84 }
+				],
+				"translate": [
+					{ "time": 0.3333, "x": -0.09, "y": -0.46 }
+				]
+			},
+			"rear_bracer": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.3333, "angle": 40.03 }
+				]
+			},
+			"gun": {
+				"rotate": [
+					{ "time": 0, "angle": 14.98 },
+					{ "time": 0.3333, "angle": 39.75 }
+				]
+			},
+			"hip": {
+				"translate": [
+					{ "time": 0, "x": -75.54, "y": -78.03 },
+					{ "time": 0.2333, "x": -36.48, "y": 12.42 },
+					{ "time": 0.3333, "x": -36.48, "y": -2.99 }
+				]
+			},
+			"front_thigh": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 90.94,
+						"curve": [ 0.227, 0.26, 0.432, 1 ]
+					},
+					{ "time": 0.3333, "angle": 32.02 }
+				],
+				"translate": [
+					{ "time": 0, "x": 7.21, "y": -4 }
+				]
+			},
+			"rear_thigh": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 40.51,
+						"curve": [ 0.295, 0.3, 0.59, 0.99 ]
+					},
+					{ "time": 0.3333, "angle": 90.76 }
+				],
+				"translate": [
+					{ "time": 0, "x": -1.96, "y": -0.32 }
+				]
+			},
+			"front_shin": {
+				"rotate": [
+					{ "time": 0, "angle": -96.62 },
+					{ "time": 0.3333, "angle": -15.13 }
+				]
+			},
+			"rear_shin": {
+				"rotate": [
+					{ "time": 0, "angle": 7.99 },
+					{ "time": 0.3333, "angle": -67.54 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"front_foot": {
+				"rotate": [
+					{ "time": 0, "angle": 5.4 },
+					{ "time": 0.3333, "angle": -16.26 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"rear_foot": {
+				"rotate": [
+					{ "time": 0, "angle": 2.67 },
+					{ "time": 0.3333, "angle": -10.31 }
+				]
+			}
+		}
+	},
+	"idle": {
+		"slots": {
+			"front_fist": {
+				"attachment": [
+					{ "time": 0, "name": "front_fist_open" },
+					{ "time": 1.6666, "name": "front_fist_open" }
+				]
+			},
+			"mouth": {
+				"attachment": [
+					{ "time": 0, "name": "mouth_smile" },
+					{ "time": 1.6666, "name": "mouth_smile" }
+				]
+			}
+		},
+		"bones": {
+			"torso": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -5.61,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.8333,
+						"angle": -9.65,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": -5.61 }
+				],
+				"translate": [
+					{ "time": 0, "x": -6.49, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"front_upper_arm": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -59.85,
+						"curve": [ 0.492, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": -54.31,
+						"curve": [ 0.324, 0.11, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": -59.85 }
+				],
+				"translate": [
+					{ "time": 0, "x": -7.12, "y": -8.23 },
+					{ "time": 0.6666, "x": -6.32, "y": -8.3 },
+					{ "time": 1.6666, "x": -7.12, "y": -8.23 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"rear_upper_arm": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 62.41,
+						"curve": [ 0.504, 0.02, 0.75, 1 ]
+					},
+					{
+						"time": 0.7333,
+						"angle": 43.83,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": 62.41 }
+				],
+				"translate": [
+					{ "time": 0, "x": -1.83, "y": -16.78 },
+					{ "time": 0.6666, "x": 0.34, "y": -15.23 },
+					{ "time": 1.6666, "x": -1.83, "y": -16.78 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"neck": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.6666, "angle": 2.39 },
+					{ "time": 1.6666, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 0, "x": -1.88, "y": -4.76, "curve": "stepped" },
+					{ "time": 1.6666, "x": -1.88, "y": -4.76 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"front_thigh": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 0.64,
+						"curve": [ 0.235, 0, 0.558, 0.99 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": -4.34,
+						"curve": [ 0.594, 0, 0.653, 1 ]
+					},
+					{ "time": 1.6666, "angle": 0.64 }
+				],
+				"translate": [
+					{ "time": 0, "x": -13.39, "y": 6.69, "curve": "stepped" },
+					{ "time": 1.6666, "x": -13.39, "y": 6.69 }
+				],
+				"scale": [
+					{
+						"time": 0,
+						"x": 0.896,
+						"y": 1,
+						"curve": [ 0.235, 0, 0.558, 0.99 ]
+					},
+					{
+						"time": 0.6666,
+						"x": 0.825,
+						"y": 1,
+						"curve": [ 0.594, 0, 0.653, 1 ]
+					},
+					{ "time": 1.6666, "x": 0.896, "y": 1 }
+				]
+			},
+			"front_shin": {
+				"rotate": [
+					{ "time": 0, "angle": -19.28, "curve": "stepped" },
+					{ "time": 1.6666, "angle": -19.28 }
+				],
+				"scale": [
+					{
+						"time": 0,
+						"x": 1,
+						"y": 1,
+						"curve": [ 0.235, 0, 0.558, 0.99 ]
+					},
+					{
+						"time": 0.6666,
+						"x": 0.994,
+						"y": 1,
+						"curve": [ 0.594, 0, 0.653, 1 ]
+					},
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"rear_thigh": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 30.5,
+						"curve": [ 0.235, 0, 0.558, 0.99 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": 40.15,
+						"curve": [ 0.594, 0, 0.653, 1 ]
+					},
+					{ "time": 1.6666, "angle": 30.5 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"rear_shin": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -23.83,
+						"curve": [ 0.235, 0, 0.558, 0.99 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": -43.77,
+						"curve": [ 0.594, 0, 0.653, 1 ]
+					},
+					{ "time": 1.6666, "angle": -23.83 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"front_foot": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 5.13,
+						"curve": [ 0.235, 0, 0.558, 0.99 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": 10.04,
+						"curve": [ 0.594, 0, 0.653, 1 ]
+					},
+					{ "time": 1.6666, "angle": 5.13 }
+				],
+				"scale": [
+					{ "time": 0, "x": 0.755, "y": 1.309, "curve": "stepped" },
+					{ "time": 1.6666, "x": 0.755, "y": 1.309 }
+				]
+			},
+			"hip": {
+				"translate": [
+					{
+						"time": 0,
+						"x": -6.63,
+						"y": -23.01,
+						"curve": [ 0.235, 0, 0.558, 0.99 ]
+					},
+					{
+						"time": 0.6666,
+						"x": 6.27,
+						"y": -35,
+						"curve": [ 0.594, 0, 0.653, 1 ]
+					},
+					{ "time": 1.6666, "x": -6.63, "y": -23.01 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"rear_foot": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -7.34,
+						"curve": [ 0.235, 0, 0.558, 0.99 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": 3.85,
+						"curve": [ 0.594, 0, 0.653, 1 ]
+					},
+					{ "time": 1.6666, "angle": -7.34 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"rear_bracer": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -17.16,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": 12.52,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": -17.16 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"head": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -5.51,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": -3.12,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": -5.51 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"front_bracer": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 45.46,
+						"curve": [ 0.492, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": 41.33,
+						"curve": [ 0.32, 0.1, 0.736, 0.91 ]
+					},
+					{ "time": 1.6666, "angle": 45.46 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"gun": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 0,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": -15.59,
+						"curve": [ 0.732, 0, 0.769, 0.99 ]
+					},
+					{ "time": 1.6666, "angle": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			},
+			"front_fist": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -6.84,
+						"curve": [ 0.492, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": -14.63,
+						"curve": [ 0.324, 0.11, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "angle": -6.84 }
+				],
+				"scale": [
+					{
+						"time": 0,
+						"x": 1,
+						"y": 1,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.6666,
+						"x": 0.689,
+						"y": 1.1,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 1.6666, "x": 1, "y": 1 }
+				]
+			}
+		}
+	},
+	"jump": {
+		"slots": {
+			"front_fist": {
+				"attachment": [
+					{ "time": 0, "name": "front_fist_open" },
+					{ "time": 0.2, "name": "front_fist_closed" },
+					{ "time": 0.6666, "name": "front_fist_open" }
+				]
+			},
+			"mouth": {
+				"attachment": [
+					{ "time": 0, "name": "mouth_grind" }
+				]
+			},
+			"torso": {
+				"attachment": [
+					{ "time": 0, "name": "torso" }
+				]
+			}
+		},
+		"bones": {
+			"front_thigh": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 91.53,
+						"curve": [ 0.278, 0.46, 0.763, 1 ]
+					},
+					{
+						"time": 0.2,
+						"angle": -35.83,
+						"curve": [ 0.761, 0, 0.75, 1 ]
+					},
+					{ "time": 0.4333, "angle": 127.74 },
+					{
+						"time": 0.7333,
+						"angle": 48.18,
+						"curve": [ 0.227, 0.26, 0.432, 1 ]
+					},
+					{ "time": 0.8333, "angle": 25.35 },
+					{ "time": 0.9333, "angle": 45.37 },
+					{ "time": 1.0333, "angle": 38.12 },
+					{ "time": 1.1333, "angle": 25.35 },
+					{ "time": 1.3333, "angle": 91.53 }
+				],
+				"translate": [
+					{ "time": 0, "x": -2.56, "y": 5.77 },
+					{ "time": 0.4333, "x": 8.3, "y": 7.98 },
+					{ "time": 0.7333, "x": 7.21, "y": -4 },
+					{ "time": 1.3333, "x": -2.56, "y": 5.77 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"torso": {
+				"rotate": [
+					{ "time": 0, "angle": -42.63 },
+					{ "time": 0.2, "angle": -5.74 },
+					{ "time": 0.4333, "angle": -50.76 },
+					{ "time": 0.7333, "angle": 1.89 },
+					{ "time": 0.8333, "angle": 11.58 },
+					{ "time": 0.9666, "angle": -1.89 },
+					{ "time": 1.1333, "angle": 11.58 },
+					{ "time": 1.3333, "angle": -42.63 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"rear_thigh": {
+				"rotate": [
+					{ "time": 0, "angle": -26.32 },
+					{ "time": 0.2, "angle": 121.44 },
+					{ "time": 0.4333, "angle": 70.54 },
+					{
+						"time": 0.7333,
+						"angle": 79.89,
+						"curve": [ 0.295, 0.3, 0.59, 0.99 ]
+					},
+					{ "time": 0.8333, "angle": 99.12 },
+					{ "time": 0.9333, "angle": 74.05 },
+					{ "time": 1.0333, "angle": 98.04 },
+					{ "time": 1.1333, "angle": 99.12 },
+					{ "time": 1.3333, "angle": -26.32 }
+				],
+				"translate": [
+					{ "time": 0, "x": -0.56, "y": -0.32 },
+					{ "time": 0.4333, "x": -8.5, "y": 10.58 },
+					{ "time": 0.7333, "x": -1.96, "y": -0.32 },
+					{ "time": 1.3333, "x": -0.56, "y": -0.32 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"rear_shin": {
+				"rotate": [
+					{ "time": 0, "angle": -78.69 },
+					{ "time": 0.4333, "angle": -55.56 },
+					{ "time": 0.7333, "angle": -62.84 },
+					{ "time": 0.8333, "angle": -80.74 },
+					{ "time": 0.9333, "angle": -41.12 },
+					{ "time": 1.0333, "angle": -77.4 },
+					{ "time": 1.1333, "angle": -80.74 },
+					{ "time": 1.3333, "angle": -78.69 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.7333, "x": 1, "y": 1 }
+				]
+			},
+			"front_upper_arm": {
+				"rotate": [
+					{ "time": 0, "angle": -22.61 },
+					{ "time": 0.2, "angle": -246.68 },
+					{
+						"time": 0.6,
+						"angle": 11.28,
+						"curve": [ 0.246, 0, 0.633, 0.53 ]
+					},
+					{
+						"time": 0.7333,
+						"angle": -57.45,
+						"curve": [ 0.38, 0.53, 0.744, 1 ]
+					},
+					{ "time": 0.8666, "angle": -112.59 },
+					{ "time": 0.9333, "angle": -102.17 },
+					{ "time": 1.0333, "angle": -108.61 },
+					{ "time": 1.1333, "angle": -112.59 },
+					{ "time": 1.3333, "angle": -22.61 }
+				],
+				"translate": [
+					{ "time": 0, "x": 6.08, "y": 7.15 },
+					{ "time": 0.2, "x": 7.23, "y": -13.13, "curve": "stepped" },
+					{ "time": 0.7333, "x": 7.23, "y": -13.13 },
+					{ "time": 1.3333, "x": 6.08, "y": 7.15 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"front_bracer": {
+				"rotate": [
+					{ "time": 0, "angle": 66.46 },
+					{ "time": 0.2, "angle": 42.39 },
+					{ "time": 0.4333, "angle": 26.06 },
+					{ "time": 0.7333, "angle": 13.28 },
+					{ "time": 0.8666, "angle": -28.64 },
+					{ "time": 0.9333, "angle": -22.31 },
+					{ "time": 1.0333, "angle": -35.39 },
+					{ "time": 1.1333, "angle": -28.64 },
+					{ "time": 1.3333, "angle": 66.46 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"front_fist": {
+				"rotate": [
+					{ "time": 0, "angle": -28.43 },
+					{ "time": 0.4333, "angle": -45.6 },
+					{ "time": 0.7333, "angle": -53.66 },
+					{ "time": 0.8666, "angle": 7.55 },
+					{ "time": 0.9333, "angle": 31.15 },
+					{ "time": 1.0333, "angle": -32.58 },
+					{ "time": 1.1333, "angle": 7.55 },
+					{ "time": 1.3333, "angle": -28.43 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"rear_upper_arm": {
+				"rotate": [
+					{ "time": 0, "angle": 39.68 },
+					{ "time": 0.2, "angle": 276.57 },
+					{ "time": 0.3, "angle": 17.73 },
+					{ "time": 0.4333, "angle": 83.38 },
+					{
+						"time": 0.6,
+						"angle": -4.71,
+						"curve": [ 0.246, 0, 0.633, 0.53 ]
+					},
+					{
+						"time": 0.7333,
+						"angle": -69.63,
+						"curve": [ 0.342, 0.36, 0.68, 0.71 ]
+					},
+					{
+						"time": 0.7666,
+						"angle": 321.47,
+						"curve": [ 0.333, 0.33, 0.667, 0.66 ]
+					},
+					{
+						"time": 0.8,
+						"angle": 33.7,
+						"curve": [ 0.358, 0.64, 0.693, 1 ]
+					},
+					{ "time": 0.8666, "angle": 34.56 },
+					{ "time": 1.0333, "angle": 71.96 },
+					{ "time": 1.1333, "angle": 34.56 },
+					{ "time": 1.3333, "angle": 39.68 }
+				],
+				"translate": [
+					{ "time": 0, "x": -3.1, "y": -4.86 },
+					{ "time": 0.2, "x": 23.33, "y": 49.07 },
+					{ "time": 0.4333, "x": 20.78, "y": 40.21 },
+					{ "time": 1.3333, "x": -3.1, "y": -4.86 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"rear_bracer": {
+				"rotate": [
+					{ "time": 0, "angle": 29.66 },
+					{ "time": 0.2, "angle": 45.06 },
+					{ "time": 0.4333, "angle": -4.34 },
+					{ "time": 0.7666, "angle": 61.68 },
+					{ "time": 0.8, "angle": 82.59 },
+					{ "time": 0.8666, "angle": 80.06 },
+					{ "time": 1.0333, "angle": 57.56 },
+					{ "time": 1.1333, "angle": 80.06 },
+					{ "time": 1.3333, "angle": 29.66 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"neck": {
+				"rotate": [
+					{ "time": 0, "angle": 24.9 },
+					{ "time": 0.2, "angle": 16.31 },
+					{ "time": 0.4333, "angle": 7.44 },
+					{ "time": 0.7333, "angle": -20.35 },
+					{ "time": 0.8333, "angle": -0.69, "curve": "stepped" },
+					{ "time": 1.1333, "angle": -0.69 },
+					{ "time": 1.3333, "angle": 24.9 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"head": {
+				"rotate": [
+					{ "time": 0, "angle": 24.92 },
+					{ "time": 0.2, "angle": 10.36 },
+					{ "time": 0.4333, "angle": 28.65 },
+					{ "time": 0.7333, "angle": -2.65 },
+					{ "time": 0.8333, "angle": -28.94, "curve": "stepped" },
+					{ "time": 1.1333, "angle": -28.94 },
+					{ "time": 1.3333, "angle": 24.92 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"hip": {
+				"rotate": [
+					{ "time": 0, "angle": 0 }
+				],
+				"translate": [
+					{
+						"time": 0,
+						"x": -34.51,
+						"y": -78.62,
+						"curve": [ 0.232, 1, 0.75, 1 ]
+					},
+					{
+						"time": 0.2,
+						"x": -34.51,
+						"y": 182.5,
+						"curve": [ 0.232, 0.48, 0.598, 0.79 ]
+					},
+					{
+						"time": 0.7666,
+						"x": -34.51,
+						"y": 596.22,
+						"curve": [ 0.329, 0.17, 0.66, 0.21 ]
+					},
+					{ "time": 1.1333, "x": -34.51, "y": 2.49 },
+					{ "time": 1.3333, "x": -34.51, "y": -78.62 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"front_shin": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -90.62,
+						"curve": [ 0.416, 0.54, 0.743, 1 ]
+					},
+					{
+						"time": 0.2,
+						"angle": -10.52,
+						"curve": [ 0.644, 0, 0.75, 1 ]
+					},
+					{ "time": 0.4333, "angle": -127.72 },
+					{ "time": 0.7333, "angle": -19.91 },
+					{ "time": 0.8333, "angle": -5.16 },
+					{ "time": 0.9333, "angle": -35.06 },
+					{ "time": 1.0333, "angle": -43.97 },
+					{ "time": 1.1333, "angle": -5.16 },
+					{ "time": 1.3333, "angle": -90.62 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"front_foot": {
+				"rotate": [
+					{ "time": 0, "angle": -0.79 },
+					{ "time": 0.0333, "angle": 16.27 },
+					{ "time": 0.0666, "angle": 23.52 },
+					{ "time": 0.1, "angle": 21.02 },
+					{ "time": 0.1333, "angle": 10.92 },
+					{ "time": 0.2, "angle": -38.45 },
+					{ "time": 0.4333, "angle": 6.62 },
+					{ "time": 0.7333, "angle": -11.51 },
+					{ "time": 1.0333, "angle": -22.91 },
+					{ "time": 1.3333, "angle": -0.79 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"rear_foot": {
+				"rotate": [
+					{ "time": 0, "angle": -12.77 },
+					{ "time": 0.2, "angle": 17.05 },
+					{ "time": 0.4333, "angle": 19.45 },
+					{ "time": 0.7333, "angle": 2.67 },
+					{ "time": 1.0333, "angle": -28.49 },
+					{ "time": 1.3333, "angle": -12.77 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			},
+			"gun": {
+				"rotate": [
+					{ "time": 0, "angle": 6.18 },
+					{ "time": 0.2, "angle": 30.81 },
+					{ "time": 0.4333, "angle": 13.25 },
+					{ "time": 0.7333, "angle": 14.98 },
+					{ "time": 0.7666, "angle": 25.64 },
+					{ "time": 0.8, "angle": 20.62 },
+					{ "time": 0.8666, "angle": 64.52 },
+					{ "time": 1.0333, "angle": 8.59 },
+					{ "time": 1.1333, "angle": 64.52 },
+					{ "time": 1.3333, "angle": 6.18 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 }
+				]
+			}
+		}
+	},
+	"run": {
+		"slots": {
+			"front_fist": {
+				"attachment": [
+					{ "time": 0, "name": "front_fist_closed" }
+				]
+			},
+			"mouth": {
+				"attachment": [
+					{ "time": 0, "name": "mouth_grind" }
+				]
+			},
+			"torso": {
+				"attachment": [
+					{ "time": 0, "name": "torso" }
+				]
+			}
+		},
+		"bones": {
+			"front_thigh": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 42.05,
+						"curve": [ 0.195, 0.86, 0.75, 1 ]
+					},
+					{ "time": 0.0666, "angle": 46.07 },
+					{ "time": 0.1333, "angle": -20.28 },
+					{ "time": 0.2, "angle": -27.23 },
+					{ "time": 0.2666, "angle": -47.16 },
+					{ "time": 0.3333, "angle": -39.79 },
+					{ "time": 0.4, "angle": -25.86 },
+					{ "time": 0.4666, "angle": 14.35 },
+					{ "time": 0.5333, "angle": 55.62 },
+					{ "time": 0.6, "angle": 69.65 },
+					{ "time": 0.6666, "angle": 86.4 },
+					{ "time": 0.7333, "angle": 65.87 },
+					{ "time": 0.8, "angle": 42.05 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 },
+					{ "time": 0.0333, "x": -5.79, "y": 11.15 },
+					{ "time": 0.0666, "x": -5.13, "y": 11.55 },
+					{ "time": 0.1333, "x": -7.7, "y": 8.98 },
+					{ "time": 0.5333, "x": -1.26, "y": 3.83 },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"torso": {
+				"rotate": [
+					{ "time": 0, "angle": -39.7 },
+					{ "time": 0.2, "angle": -57.29 },
+					{ "time": 0.4, "angle": -39.7 },
+					{ "time": 0.6, "angle": -57.29 },
+					{ "time": 0.8, "angle": -39.7 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.4, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"rear_thigh": {
+				"rotate": [
+					{ "time": 0, "angle": -56.59 },
+					{ "time": 0.0666, "angle": -21.57 },
+					{ "time": 0.1333, "angle": 27.95 },
+					{ "time": 0.2, "angle": 42.42 },
+					{ "time": 0.2666, "angle": 62.37 },
+					{ "time": 0.3333, "angle": 45.42 },
+					{ "time": 0.4, "angle": 15.67 },
+					{ "time": 0.4666, "angle": 28.22 },
+					{ "time": 0.5333, "angle": -38.62 },
+					{ "time": 0.6, "angle": -53.26 },
+					{ "time": 0.6666, "angle": -79.31 },
+					{ "time": 0.7333, "angle": -86.47 },
+					{ "time": 0.8, "angle": -56.59 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 },
+					{ "time": 0.4, "x": -6.76, "y": -3.86 },
+					{ "time": 0.4333, "x": -15.85, "y": 7.28 },
+					{ "time": 0.4666, "x": -13.04, "y": 4.04 },
+					{ "time": 0.5, "x": -10.24, "y": 7.11 },
+					{ "time": 0.5333, "x": -9.01, "y": -5.15 },
+					{ "time": 0.6666, "x": -23.18, "y": -2.57 },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"rear_shin": {
+				"rotate": [
+					{ "time": 0, "angle": -74 },
+					{ "time": 0.0666, "angle": -83.38 },
+					{ "time": 0.1333, "angle": -106.69 },
+					{ "time": 0.2, "angle": -66.01 },
+					{ "time": 0.2666, "angle": -55.22 },
+					{ "time": 0.3333, "angle": -24.8 },
+					{
+						"time": 0.4,
+						"angle": 18.44,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 0.4666, "angle": -56.65 },
+					{
+						"time": 0.5333,
+						"angle": -11.94,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 0.6666, "angle": -41.26 },
+					{ "time": 0.7333, "angle": -43.6 },
+					{ "time": 0.8, "angle": -74 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"front_upper_arm": {
+				"rotate": [
+					{ "time": 0, "angle": -89.36 },
+					{ "time": 0.0666, "angle": -95.67 },
+					{ "time": 0.1333, "angle": -22 },
+					{ "time": 0.2, "angle": -316.04 },
+					{ "time": 0.2666, "angle": -274.94 },
+					{ "time": 0.3333, "angle": -273.74 },
+					{ "time": 0.4, "angle": -272.09 },
+					{ "time": 0.4666, "angle": -264.89 },
+					{ "time": 0.5333, "angle": -320.09 },
+					{ "time": 0.6, "angle": -50.83 },
+					{ "time": 0.6666, "angle": -81.72 },
+					{ "time": 0.7333, "angle": -83.92 },
+					{ "time": 0.8, "angle": -89.36 }
+				],
+				"translate": [
+					{ "time": 0, "x": 6.24, "y": 10.05 },
+					{ "time": 0.2666, "x": 4.95, "y": -13.13 },
+					{ "time": 0.6, "x": -2.43, "y": 1.94 },
+					{ "time": 0.8, "x": 6.24, "y": 10.05 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"front_bracer": {
+				"rotate": [
+					{ "time": 0, "angle": 33.43 },
+					{ "time": 0.0666, "angle": 20.53 },
+					{ "time": 0.1333, "angle": 15.26 },
+					{ "time": 0.2, "angle": 19.28 },
+					{ "time": 0.2666, "angle": 22.62 },
+					{ "time": 0.3333, "angle": 37.29 },
+					{ "time": 0.4, "angle": 41.53 },
+					{ "time": 0.4666, "angle": 31.73 },
+					{ "time": 0.5333, "angle": 67.45 },
+					{ "time": 0.6666, "angle": 39.77 },
+					{ "time": 0.7333, "angle": 30.95 },
+					{ "time": 0.8, "angle": 33.43 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"front_fist": {
+				"rotate": [
+					{ "time": 0, "angle": -19.75 },
+					{ "time": 0.0666, "angle": -37.11 },
+					{ "time": 0.1333, "angle": -50.79 },
+					{ "time": 0.2666, "angle": -12.69 },
+					{ "time": 0.3333, "angle": 3.01 },
+					{ "time": 0.4333, "angle": 12.05 },
+					{ "time": 0.5333, "angle": 13.25 },
+					{ "time": 0.8, "angle": -19.75 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"rear_upper_arm": {
+				"rotate": [
+					{ "time": 0, "angle": 68.68 },
+					{ "time": 0.0666, "angle": 73.89 },
+					{ "time": 0.1333, "angle": -9.64 },
+					{ "time": 0.2, "angle": 284.27 },
+					{ "time": 0.2666, "angle": 283.29 },
+					{ "time": 0.3333, "angle": 278.28 },
+					{ "time": 0.4, "angle": 271.02 },
+					{ "time": 0.4666, "angle": 263.2 },
+					{ "time": 0.5333, "angle": 314.25 },
+					{ "time": 0.6, "angle": 16.83 },
+					{ "time": 0.6666, "angle": 70.35 },
+					{ "time": 0.7333, "angle": 73.53 },
+					{ "time": 0.8, "angle": 68.68 }
+				],
+				"translate": [
+					{ "time": 0, "x": -2.57, "y": -8.89 },
+					{ "time": 0.1333, "x": -4.68, "y": 7.2 },
+					{ "time": 0.2, "x": 21.73, "y": 51.17 },
+					{ "time": 0.6, "x": 4.33, "y": 2.05 },
+					{ "time": 0.8, "x": -2.57, "y": -8.89 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"rear_bracer": {
+				"rotate": [
+					{ "time": 0, "angle": 31.04 },
+					{ "time": 0.0666, "angle": 28.28 },
+					{ "time": 0.1333, "angle": 49.36 },
+					{ "time": 0.2, "angle": 59.37 },
+					{ "time": 0.2666, "angle": 8.56 },
+					{ "time": 0.3333, "angle": 9.38 },
+					{ "time": 0.4, "angle": 11.51 },
+					{ "time": 0.4666, "angle": 7.22 },
+					{ "time": 0.5333, "angle": -18.44 },
+					{ "time": 0.6, "angle": 11.44 },
+					{ "time": 0.6666, "angle": 9.99 },
+					{ "time": 0.7333, "angle": 8.28 },
+					{ "time": 0.8, "angle": 31.04 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"neck": {
+				"rotate": [
+					{ "time": 0, "angle": 11.03 },
+					{ "time": 0.2, "angle": 13.58 },
+					{ "time": 0.4, "angle": 11.03 },
+					{ "time": 0.6, "angle": 13.58 },
+					{ "time": 0.8, "angle": 11.03 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.4, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"head": {
+				"rotate": [
+					{ "time": 0, "angle": 11.03 },
+					{ "time": 0.1, "angle": 12.34 },
+					{ "time": 0.2, "angle": 25.55 },
+					{ "time": 0.4, "angle": 11.03 },
+					{ "time": 0.5, "angle": 12.34 },
+					{ "time": 0.6, "angle": 25.55 },
+					{ "time": 0.8, "angle": 11.03 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.4, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"hip": {
+				"rotate": [
+					{ "time": 0, "angle": 0, "curve": "stepped" },
+					{ "time": 0.8, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 0, "x": -62.47, "y": -23.1 },
+					{
+						"time": 0.0666,
+						"x": -62.47,
+						"y": -38.51,
+						"curve": [ 0.244, 0.04, 0.75, 1 ]
+					},
+					{
+						"time": 0.2666,
+						"x": -62.47,
+						"y": 22.28,
+						"curve": [ 0.17, 0.52, 0.75, 1 ]
+					},
+					{ "time": 0.4, "x": -62.47, "y": -23.1 },
+					{ "time": 0.4333, "x": -62.47, "y": -24.59 },
+					{
+						"time": 0.4666,
+						"x": -62.47,
+						"y": -43.29,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 0.6666, "x": -62.47, "y": 22.28 },
+					{ "time": 0.8, "x": -62.47, "y": -23.1 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"front_shin": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": 0,
+						"curve": [ 0.481, 0.01, 0.75, 1 ]
+					},
+					{ "time": 0.0666, "angle": -64.42 },
+					{
+						"time": 0.1333,
+						"angle": -20.59,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 0.2666, "angle": -62.51 },
+					{ "time": 0.3333, "angle": -79.74 },
+					{ "time": 0.4, "angle": -78.28 },
+					{
+						"time": 0.4666,
+						"angle": -118.96,
+						"curve": [ 0.93, 0, 0.952, 0.95 ]
+					},
+					{ "time": 0.6, "angle": -88.95 },
+					{ "time": 0.6666, "angle": -79.09 },
+					{ "time": 0.7333, "angle": -47.77 },
+					{ "time": 0.8, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"front_foot": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{
+						"time": 0.0333,
+						"angle": -21.13,
+						"curve": [ 0.121, 0.23, 0.75, 1 ]
+					},
+					{ "time": 0.0666, "angle": 17.64 },
+					{ "time": 0.1, "angle": 29.92 },
+					{ "time": 0.1333, "angle": 16.44 },
+					{ "time": 0.2, "angle": -29.22 },
+					{ "time": 0.2666, "angle": -1.61 },
+					{ "time": 0.3333, "angle": -10.22 },
+					{ "time": 0.4666, "angle": -15.99 },
+					{ "time": 0.6, "angle": 9.03 },
+					{ "time": 0.7333, "angle": 17.32 },
+					{ "time": 0.8, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"rear_foot": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.0666, "angle": -12.04 },
+					{ "time": 0.1333, "angle": -0.87 },
+					{ "time": 0.2, "angle": 25.81 },
+					{ "time": 0.2666, "angle": 4.71 },
+					{
+						"time": 0.4,
+						"angle": 18.09,
+						"curve": [ 0.281, 0.73, 0.75, 1 ]
+					},
+					{ "time": 0.4333, "angle": -1.7 },
+					{ "time": 0.4666, "angle": 27.12 },
+					{ "time": 0.5, "angle": 38.83 },
+					{ "time": 0.5333, "angle": 30.76 },
+					{ "time": 0.5666, "angle": -20.49 },
+					{ "time": 0.6, "angle": -30.8 },
+					{ "time": 0.6666, "angle": -1.31 },
+					{ "time": 0.8, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"gun": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.1333, "angle": 24.72 },
+					{ "time": 0.5, "angle": -11.87 },
+					{ "time": 0.8, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			}
+		},
+		"events": [
+			{ "time": 0, "name": "footstep" },
+			{ "time": 0.4, "name": "footstep", "int": 1 }
+		]
+	},
+	"shoot": {
+		"slots": {
+			"front_fist": {
+				"attachment": [
+					{ "time": 0.1333, "name": "front_fist_closed" },
+					{ "time": 0.4, "name": "front_fist_open" }
+				]
+			},
+			"mouth": {
+				"attachment": [
+					{ "time": 0.1333, "name": "mouth_grind" }
+				]
+			},
+			"muzzle": {
+				"color": [
+					{
+						"time": 0.1333,
+						"color": "ffffff00",
+						"curve": [ 0.118, 0.99, 0.75, 1 ]
+					},
+					{
+						"time": 0.1666,
+						"color": "ffffffff",
+						"curve": [ 0.821, 0, 0.909, 0.89 ]
+					},
+					{ "time": 0.2666, "color": "ffffff00" }
+				],
+				"attachment": [
+					{ "time": 0.1333, "name": "muzzle" },
+					{ "time": 0.2666, "name": null }
+				]
+			}
+		},
+		"bones": {
+			"front_fist": {
+				"scale": [
+					{ "time": 0.1333, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.4, "x": 1, "y": 1 }
+				]
+			},
+			"gunTip": {
+				"translate": [
+					{ "time": 0.1333, "x": 0, "y": 0 },
+					{ "time": 0.2, "x": 20.93, "y": 1.57 }
+				],
+				"scale": [
+					{ "time": 0.1333, "x": 1, "y": 1 },
+					{ "time": 0.2, "x": 1.247, "y": 1.516 }
+				]
+			},
+			"gun": {
+				"rotate": [
+					{ "time": 0, "angle": 1.9 }
+				],
+				"translate": [
+					{
+						"time": 0,
+						"x": 7.95,
+						"y": 5.84,
+						"curve": [ 0, 0.3, 0.678, 1 ]
+					},
+					{ "time": 0.3, "x": -9.3, "y": -1.41 },
+					{ "time": 0.4, "x": 0, "y": 0 }
+				]
+			},
+			"rear_bracer": {
+				"rotate": [
+					{ "time": 0, "angle": -30.47 }
+				],
+				"translate": [
+					{
+						"time": 0,
+						"x": 0,
+						"y": 0,
+						"curve": [ 0, 0.3, 0.678, 1 ]
+					},
+					{ "time": 0.3, "x": -5.99, "y": -3.71 },
+					{ "time": 0.4, "x": 0, "y": 0 }
+				]
+			},
+			"rear_upper_arm": {
+				"rotate": [
+					{ "time": 0, "angle": 62.3 }
+				],
+				"translate": [
+					{
+						"time": 0,
+						"x": 0,
+						"y": 0,
+						"curve": [ 0, 0.3, 0.678, 1 ]
+					},
+					{ "time": 0.3, "x": 2.81, "y": 11.41 },
+					{ "time": 0.4, "x": 0, "y": 0 }
+				]
+			}
+		}
+	},
+	"test": {
+		"slots": {
+			"front_foot": {
+				"color": [
+					{ "time": 0.6666, "color": "ffffffff" },
+					{ "time": 1.3333, "color": "ff0700ff" }
+				]
+			},
+			"gun": {
+				"color": [
+					{ "time": 0, "color": "ffffffff", "curve": "stepped" },
+					{ "time": 0.6666, "color": "ffffffff" },
+					{ "time": 1.3333, "color": "32ff00ff" }
+				]
+			},
+			"rear_foot": {
+				"color": [
+					{ "time": 0.6666, "color": "ffffffff" },
+					{ "time": 1.3333, "color": "ff0700ff" }
+				]
+			}
+		},
+		"bones": {
+			"head": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.3333, "angle": -20.72 },
+					{ "time": 0.6666, "angle": -32.41 },
+					{ "time": 1, "angle": -5.3 },
+					{ "time": 1.3333, "angle": 24.96 },
+					{ "time": 1.6666, "angle": 15.61 },
+					{ "time": 2, "angle": 0 }
+				],
+				"translate": [
+					{
+						"time": 0,
+						"x": 0,
+						"y": 0,
+						"curve": [ 0.172, 0.37, 0.574, 0.73 ]
+					},
+					{
+						"time": 0.1666,
+						"x": 144.19,
+						"y": -77.59,
+						"curve": [ 0.372, 0.61, 0.765, 1 ]
+					},
+					{
+						"time": 0.3333,
+						"x": 217.61,
+						"y": -192.63,
+						"curve": [ 0.282, 0, 0.624, 0.31 ]
+					},
+					{
+						"time": 0.5,
+						"x": 181.21,
+						"y": -365.66,
+						"curve": [ 0.313, 0.21, 0.654, 0.54 ]
+					},
+					{
+						"time": 0.6666,
+						"x": 20.09,
+						"y": -500.4,
+						"curve": [ 0.147, 0.27, 0.75, 1 ]
+					},
+					{ "time": 0.8333, "x": -194.24, "y": -341.84 },
+					{ "time": 1, "x": -307.93, "y": -114 },
+					{
+						"time": 1.1666,
+						"x": -330.38,
+						"y": 121.42,
+						"curve": [ 0.25, 0, 0.764, 0.48 ]
+					},
+					{
+						"time": 1.3333,
+						"x": -240.42,
+						"y": 335.66,
+						"curve": [ 0.229, 0.37, 0.58, 0.73 ]
+					},
+					{
+						"time": 1.5,
+						"x": -56.12,
+						"y": 288.06,
+						"curve": [ 0.296, 0.6, 0.641, 1 ]
+					},
+					{
+						"time": 1.6666,
+						"x": 87.63,
+						"y": 191.33,
+						"curve": [ 0.238, 0, 0.626, 0.39 ]
+					},
+					{
+						"time": 1.8333,
+						"x": 60.62,
+						"y": 95.14,
+						"curve": [ 0.41, 0.26, 0.803, 0.62 ]
+					},
+					{ "time": 2, "x": 0, "y": 0 }
+				]
+			}
+		},
+		"drawOrder": [
+			{
+				"time": 0.6666,
+				"offsets": [
+					{ "slot": "head", "offset": -9 },
+					{ "slot": "eye", "offset": -9 },
+					{ "slot": "mouth", "offset": -12 },
+					{ "slot": "goggles", "offset": -12 }
+				]
+			},
+			{ "time": 1.3333 }
+		],
+		"events": [
+			{ "time": 0, "name": "headPop", "int": 0, "float": 0, "string": "pop.wav" },
+			{ "time": 1, "name": "headBehind", "int": 7, "float": 8, "string": "animate" },
+			{ "time": 2, "name": "headAttach", "int": 0, "float": 0, "string": "attach.wav" }
+		]
+	},
+	"walk": {
+		"slots": {
+			"front_fist": {
+				"attachment": [
+					{ "time": 0, "name": "front_fist_closed" }
+				]
+			},
+			"mouth": {
+				"attachment": [
+					{ "time": 0, "name": "mouth_smile" }
+				]
+			},
+			"torso": {
+				"attachment": [
+					{ "time": 0, "name": "torso" }
+				]
+			}
+		},
+		"bones": {
+			"front_thigh": {
+				"rotate": [
+					{ "time": 0, "angle": 15.79 },
+					{ "time": 0.1, "angle": 27.39 },
+					{ "time": 0.2, "angle": -7.94 },
+					{ "time": 0.3, "angle": -16.94 },
+					{ "time": 0.4, "angle": -28.62 },
+					{ "time": 0.5, "angle": -19.3 },
+					{ "time": 0.6, "angle": -3.08 },
+					{ "time": 0.6999, "angle": 29.51 },
+					{ "time": 0.8, "angle": 15.79 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 },
+					{ "time": 0.4, "x": -1.18, "y": 0.54 },
+					{ "time": 0.5, "x": 0.11, "y": 0.41 },
+					{ "time": 0.6, "x": 9.48, "y": 0.27 },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.4, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"front_shin": {
+				"rotate": [
+					{ "time": 0, "angle": 5.12 },
+					{ "time": 0.1, "angle": -20.87 },
+					{ "time": 0.2, "angle": 13.37 },
+					{ "time": 0.3, "angle": 15.98 },
+					{ "time": 0.4, "angle": 5.94 },
+					{ "time": 0.5, "angle": -26.76 },
+					{ "time": 0.6999, "angle": -55.44 },
+					{ "time": 0.8, "angle": 5.12 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"rear_thigh": {
+				"rotate": [
+					{ "time": 0, "angle": -34.38 },
+					{ "time": 0.1, "angle": -30.32 },
+					{ "time": 0.2, "angle": -37.22 },
+					{ "time": 0.3, "angle": 20.73 },
+					{ "time": 0.4, "angle": 8.69 },
+					{ "time": 0.5, "angle": 12.16 },
+					{ "time": 0.6, "angle": -24.62 },
+					{ "time": 0.6999, "angle": -27.26 },
+					{ "time": 0.8, "angle": -34.38 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0 },
+					{ "time": 0.4, "x": 4.08, "y": -9.53 },
+					{ "time": 0.5, "x": 0, "y": 0 },
+					{ "time": 0.6999, "x": -21.14, "y": -9.6 },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"rear_shin": {
+				"rotate": [
+					{ "time": 0, "angle": 14.26 },
+					{ "time": 0.1, "angle": -17.3 },
+					{ "time": 0.2, "angle": -12.67 },
+					{ "time": 0.3, "angle": -58.89 },
+					{ "time": 0.4, "angle": 15.95 },
+					{ "time": 0.5, "angle": -9 },
+					{ "time": 0.6, "angle": 26.06 },
+					{ "time": 0.6999, "angle": 21.85 },
+					{ "time": 0.8, "angle": 14.26 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1 },
+					{ "time": 0.1, "x": 0.951, "y": 1 },
+					{ "time": 0.5, "x": 0.975, "y": 1 },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"rear_foot": {
+				"rotate": [
+					{ "time": 0, "angle": 10.13 },
+					{ "time": 0.1, "angle": 12.27 },
+					{ "time": 0.2, "angle": -2.94 },
+					{ "time": 0.3, "angle": 6.29 },
+					{ "time": 0.4, "angle": 13.45 },
+					{ "time": 0.5, "angle": -3.57 },
+					{ "time": 0.6, "angle": -0.97 },
+					{ "time": 0.6999, "angle": 2.97 },
+					{ "time": 0.8, "angle": 10.13 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"front_upper_arm": {
+				"rotate": [
+					{ "time": 0, "angle": -23.74 },
+					{ "time": 0.4, "angle": -320.57 },
+					{ "time": 0.8, "angle": -23.74 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"rear_upper_arm": {
+				"rotate": [
+					{ "time": 0, "angle": 11.62 },
+					{ "time": 0.1, "angle": 19.36 },
+					{ "time": 0.4, "angle": 345.26 },
+					{ "time": 0.5, "angle": 343.44 },
+					{ "time": 0.8, "angle": 11.62 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"torso": {
+				"rotate": [
+					{ "time": 0, "angle": -12.11 },
+					{ "time": 0.1666, "angle": -17.16 },
+					{ "time": 0.4, "angle": -12.11 },
+					{ "time": 0.5666, "angle": -15.81 },
+					{ "time": 0.8, "angle": -12.11 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"neck": {
+				"rotate": [
+					{ "time": 0, "angle": 1.41 },
+					{ "time": 0.2333, "angle": -3.04 },
+					{ "time": 0.4, "angle": 1.41 },
+					{ "time": 0.6333, "angle": -3.04 },
+					{ "time": 0.8, "angle": 1.41 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.4, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"head": {
+				"rotate": [
+					{ "time": 0, "angle": 6.97 },
+					{ "time": 0.1666, "angle": 8.02 },
+					{ "time": 0.2666, "angle": 12.65 },
+					{ "time": 0.4, "angle": 6.97 },
+					{ "time": 0.5666, "angle": 8.02 },
+					{ "time": 0.6666, "angle": 12.65 },
+					{ "time": 0.8, "angle": 6.97 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.4, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"hip": {
+				"rotate": [
+					{ "time": 0, "angle": 0, "curve": "stepped" },
+					{ "time": 0.8, "angle": 0 }
+				],
+				"translate": [
+					{
+						"time": 0,
+						"x": -23.93,
+						"y": 3.22,
+						"curve": [ 0.518, 0.03, 0.807, 0.61 ]
+					},
+					{
+						"time": 0.1,
+						"x": -23.93,
+						"y": -9.24,
+						"curve": [ 0.135, 0.33, 0.601, 0.99 ]
+					},
+					{
+						"time": 0.2,
+						"x": -23.93,
+						"y": 4.35,
+						"curve": [ 0.204, 0.68, 0.75, 1 ]
+					},
+					{
+						"time": 0.3,
+						"x": -23.93,
+						"y": 2.38,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.4,
+						"x": -23.93,
+						"y": -2.5,
+						"curve": [ 0.692, 0.01, 0.75, 1 ]
+					},
+					{
+						"time": 0.5,
+						"x": -23.93,
+						"y": -10.32,
+						"curve": [ 0.235, 0.77, 0.75, 1 ]
+					},
+					{
+						"time": 0.6,
+						"x": -23.93,
+						"y": 4.35,
+						"curve": [ 0.287, 0.37, 0.718, 0.76 ]
+					},
+					{
+						"time": 0.6999,
+						"x": -23.93,
+						"y": 10.34,
+						"curve": [ 0.615, 0, 0.75, 1 ]
+					},
+					{ "time": 0.8, "x": -23.93, "y": 3.22 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"front_bracer": {
+				"rotate": [
+					{ "time": 0, "angle": 0 },
+					{ "time": 0.4, "angle": 20.59 },
+					{ "time": 0.8, "angle": 0 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"front_foot": {
+				"rotate": [
+					{ "time": 0, "angle": 12.49 },
+					{ "time": 0.1, "angle": -8.34 },
+					{ "time": 0.2, "angle": -6.17 },
+					{ "time": 0.3, "angle": -0.75 },
+					{ "time": 0.3333, "angle": 3.89 },
+					{ "time": 0.4, "angle": 10.22 },
+					{ "time": 0.5, "angle": 11.44 },
+					{ "time": 0.6, "angle": -0.33 },
+					{ "time": 0.6999, "angle": 0.15 },
+					{ "time": 0.8, "angle": 12.49 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"rear_bracer": {
+				"rotate": [
+					{ "time": 0, "angle": 3.58 },
+					{ "time": 0.1, "angle": 5.51 },
+					{ "time": 0.4, "angle": -22.77 },
+					{ "time": 0.5, "angle": -9.65 },
+					{ "time": 0.8, "angle": 3.58 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"front_fist": {
+				"rotate": [
+					{ "time": 0, "angle": -15.22 },
+					{ "time": 0.1, "angle": -51.4 },
+					{ "time": 0.4, "angle": -39.4 },
+					{ "time": 0.5, "angle": 19.26 },
+					{ "time": 0.8, "angle": -15.22 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			},
+			"gun": {
+				"rotate": [
+					{
+						"time": 0,
+						"angle": -24.06,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.1,
+						"angle": -10.94,
+						"curve": [ 0.381, 0.54, 0.742, 1 ]
+					},
+					{
+						"time": 0.4,
+						"angle": 25.34,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{
+						"time": 0.6666,
+						"angle": -27.47,
+						"curve": [ 0.25, 0, 0.75, 1 ]
+					},
+					{ "time": 0.8, "angle": -24.06 }
+				],
+				"translate": [
+					{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
+					{ "time": 0.8, "x": 0, "y": 0 }
+				],
+				"scale": [
+					{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
+					{ "time": 0.8, "x": 1, "y": 1 }
+				]
+			}
+		}
+	}
+}
+}

二进制
spine-ue4/Content/SpineBoy/spineboy.png


二进制
spine-ue4/Content/SpineBoy/spineboy.skel


二进制
spine-ue4/Content/SpineBoy/spineboy.uasset


+ 27 - 0
spine-ue4/LICENSE

@@ -0,0 +1,27 @@
+Spine Runtimes Software License v2.5
+
+Copyright (c) 2013-2016, Esoteric Software
+All rights reserved.
+
+You are granted a perpetual, non-exclusive, non-sublicensable, and
+non-transferable license to use, install, execute, and perform the Spine
+Runtimes software and derivative works solely for personal or internal
+use. Without the written permission of Esoteric Software (see Section 2 of
+the Spine Software License Agreement), you may not (a) modify, translate,
+adapt, or develop new applications using the Spine Runtimes or otherwise
+create derivative works or improvements of the Spine Runtimes or (b) remove,
+delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+or other intellectual property or proprietary rights notices on or in the
+Software, including any copy thereof. Redistributions in binary or source
+form must include this license and terms.
+
+THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.

二进制
spine-ue4/Plugins/SpinePlugin/Resources/Icon128.png


+ 111 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineAtlasImportFactory.cpp

@@ -0,0 +1,111 @@
+#include "SpineEditorPluginPrivatePCH.h"
+
+#include "SpineAtlasAsset.h"
+#include "AssetRegistryModule.h"
+#include "AssetToolsModule.h"
+#include "PackageTools.h"
+#include "Developer/DesktopPlatform/Public/IDesktopPlatform.h"
+#include "Developer/DesktopPlatform/Public/DesktopPlatformModule.h"
+#include "spine/spine.h"
+#include <string>
+#include <string.h>
+#include <stdlib.h>
+
+#define LOCTEXT_NAMESPACE "Spine"
+
+USpineAtlasAssetFactory::USpineAtlasAssetFactory (const FObjectInitializer& objectInitializer): Super(objectInitializer) {
+    bCreateNew = false;
+    bEditAfterNew = true;
+    bEditorImport = true;
+    SupportedClass = USpineAtlasAsset::StaticClass();
+    
+    Formats.Add(TEXT("atlas;Spine atlas file"));
+}
+
+FText USpineAtlasAssetFactory::GetToolTip () const {
+    return LOCTEXT("SpineAtlasAssetFactory", "Animations exported from Spine");
+}
+
+bool USpineAtlasAssetFactory::FactoryCanImport (const FString& filename) {
+    return true;
+}
+
+UObject* USpineAtlasAssetFactory::FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) {
+    FString rawString;
+    if (!FFileHelper::LoadFileToString(rawString, *Filename)) {
+        return nullptr;
+    }
+    const FString longPackagePath = FPackageName::GetLongPackagePath(InParent->GetOutermost()->GetPathName());
+    FString CurrentSourcePath;
+    FString FilenameNoExtension;
+    FString UnusedExtension;
+    FPaths::Split(UFactory::GetCurrentFilename(), CurrentSourcePath, FilenameNoExtension, UnusedExtension);
+    FString name(InName.ToString());
+    name.Append("-atlas");
+    USpineAtlasAsset* asset = NewObject<USpineAtlasAsset>(InParent, InClass, FName(*name), Flags);
+    asset->SetRawData(rawString);
+    asset->SetAtlasFileName(FName(*Filename));
+    LoadAtlas(asset, CurrentSourcePath, longPackagePath);
+    return asset;
+}
+
+bool USpineAtlasAssetFactory::CanReimport(UObject* Obj, TArray<FString>& OutFilenames) {
+    USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj);
+    if (!asset) return false;
+    FString filename = asset->GetAtlasFileName().ToString();
+    if (!filename.IsEmpty())
+        OutFilenames.Add(filename);
+    return true;
+}
+
+void USpineAtlasAssetFactory::SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) {
+    USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj);
+    if (asset && ensure(NewReimportPaths.Num() == 1))
+        asset->SetAtlasFileName(FName(*NewReimportPaths[0]));
+}
+
+EReimportResult::Type USpineAtlasAssetFactory::Reimport(UObject* Obj) {
+    USpineAtlasAsset* asset = Cast<USpineAtlasAsset>(Obj);
+    FString rawString;
+    if (!FFileHelper::LoadFileToString(rawString, *asset->GetAtlasFileName().ToString())) return EReimportResult::Failed;
+    asset->SetRawData(rawString);
+    const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
+    FString CurrentSourcePath;
+    FString FilenameNoExtension;
+    FString UnusedExtension;
+    FPaths::Split(UFactory::GetCurrentFilename(), CurrentSourcePath, FilenameNoExtension, UnusedExtension);
+    LoadAtlas(asset, CurrentSourcePath, longPackagePath);
+    if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty();
+    else Obj->MarkPackageDirty();
+    return EReimportResult::Succeeded;
+}
+
+UTexture2D* resolveTexture (USpineAtlasAsset* asset, const FString& pageFileName, const FString& targetSubPath) {
+    FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
+    
+    TArray<FString> fileNames;
+    fileNames.Add(pageFileName);
+    
+    //@TODO: Avoid the first compression, since we're going to recompress
+    TArray<UObject*> importedAsset = AssetToolsModule.Get().ImportAssets(fileNames, targetSubPath);
+    UTexture2D* texture = (importedAsset.Num() > 0) ? Cast<UTexture2D>(importedAsset[0]) : nullptr;
+    
+    return texture;
+}
+
+void USpineAtlasAssetFactory::LoadAtlas(USpineAtlasAsset* asset, const FString& currentSourcePath, const FString& longPackagePath) {
+    spAtlas* atlas = asset->GetAtlas(true);
+    asset->atlasPages.Empty();
+    
+    const FString targetTexturePath = longPackagePath / TEXT("Textures");
+    
+    spAtlasPage* page = atlas->pages;
+    while (page) {
+        const FString sourceTextureFilename = FPaths::Combine(*currentSourcePath, UTF8_TO_TCHAR(page->name));
+        UTexture2D* texture = resolveTexture(asset, sourceTextureFilename, targetTexturePath);
+        page = page->next;
+        asset->atlasPages.Add(texture);
+    }
+}
+
+#undef LOCTEXT_NAMESPACE

+ 31 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineEditorPlugin.cpp

@@ -0,0 +1,31 @@
+// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
+
+#include "SpineEditorPluginPrivatePCH.h"
+#include "spine/spine.h"
+
+
+class FSpineEditorPlugin : public ISpineEditorPlugin
+{
+	/** IModuleInterface implementation */
+	virtual void StartupModule() override;
+	virtual void ShutdownModule() override;
+};
+
+IMPLEMENT_MODULE( FSpineEditorPlugin, ISpineEditorPlugin )
+
+
+
+void FSpineEditorPlugin::StartupModule()
+{
+	// This code will execute after your module is loaded into memory (but after global variables are initialized, of course.)
+}
+
+
+void FSpineEditorPlugin::ShutdownModule()
+{
+	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
+	// we call this function before unloading the module.
+}
+
+
+

+ 4 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineEditorPluginPrivatePCH.h

@@ -0,0 +1,4 @@
+#include "SpineEditorPlugin.h"
+#include "SpinePlugin.h"
+#include "SpineAtlasImportFactory.h"
+#include "SpineSkeletonImportFactory.h"

+ 83 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Private/SpineSkeletonImportFactory.cpp

@@ -0,0 +1,83 @@
+#include "SpineEditorPluginPrivatePCH.h"
+
+#include "SpineSkeletonDataAsset.h"
+#include "AssetRegistryModule.h"
+#include "AssetToolsModule.h"
+#include "PackageTools.h"
+#include "Developer/DesktopPlatform/Public/IDesktopPlatform.h"
+#include "Developer/DesktopPlatform/Public/DesktopPlatformModule.h"
+#include "spine/spine.h"
+#include <string>
+#include <string.h>
+#include <stdlib.h>
+
+#define LOCTEXT_NAMESPACE "Spine"
+
+USpineSkeletonAssetFactory::USpineSkeletonAssetFactory (const FObjectInitializer& objectInitializer): Super(objectInitializer) {
+    bCreateNew = false;
+    bEditAfterNew = true;
+    bEditorImport = true;
+    SupportedClass = USpineSkeletonDataAsset::StaticClass();
+    
+    Formats.Add(TEXT("json;Spine skeleton file"));
+    Formats.Add(TEXT("skel;Spine skeleton file"));
+}
+
+FText USpineSkeletonAssetFactory::GetToolTip () const {
+    return LOCTEXT("USpineSkeletonAssetFactory", "Animations exported from Spine");
+}
+
+bool USpineSkeletonAssetFactory::FactoryCanImport (const FString& filename) {
+    return true;
+}
+
+void LoadAtlas (const FString& filename, const FString& targetPath) {
+    FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
+    
+    FString skelFile = filename.Replace(TEXT(".skel"), TEXT(".atlas")).Replace(TEXT(".json"), TEXT(".atlas"));
+    if (!FPaths::FileExists(skelFile)) return;
+    
+    TArray<FString> fileNames;
+    fileNames.Add(skelFile);
+    TArray<UObject*> importedAssets = AssetToolsModule.Get().ImportAssets(fileNames, targetPath);
+}
+
+UObject* USpineSkeletonAssetFactory::FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) {
+    FString name(InName.ToString());
+    name.Append("-data");
+    USpineSkeletonDataAsset* asset = NewObject<USpineSkeletonDataAsset>(InParent, InClass, FName(*name), Flags);
+    if (!FFileHelper::LoadFileToArray(asset->GetRawData(), *Filename, 0)) {
+        return nullptr;
+    }
+    asset->SetSkeletonDataFileName(FName(*Filename));
+    const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
+    LoadAtlas(Filename, longPackagePath);
+    return asset;
+}
+
+bool USpineSkeletonAssetFactory::CanReimport(UObject* Obj, TArray<FString>& OutFilenames) {
+    USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
+    if (!asset) return false;
+    FString filename = asset->GetSkeletonDataFileName().ToString();
+    if (!filename.IsEmpty())
+        OutFilenames.Add(filename);
+    return true;
+}
+
+void USpineSkeletonAssetFactory::SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) {
+    USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
+    if (asset && ensure(NewReimportPaths.Num() == 1))
+        asset->SetSkeletonDataFileName(FName(*NewReimportPaths[0]));
+}
+
+EReimportResult::Type USpineSkeletonAssetFactory::Reimport(UObject* Obj) {
+    USpineSkeletonDataAsset* asset = Cast<USpineSkeletonDataAsset>(Obj);
+    FString rawString;
+    if (!FFileHelper::LoadFileToArray(asset->GetRawData(), *asset->GetSkeletonDataFileName().ToString(), 0)) return EReimportResult::Failed;
+    const FString longPackagePath = FPackageName::GetLongPackagePath(asset->GetOutermost()->GetPathName());
+    LoadAtlas(*asset->GetSkeletonDataFileName().ToString(), longPackagePath);
+    if (Obj->GetOuter()) Obj->GetOuter()->MarkPackageDirty();
+    else Obj->MarkPackageDirty();
+    return EReimportResult::Succeeded;
+}
+#undef LOCTEXT_NAMESPACE

+ 22 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Public/SpineAtlasImportFactory.h

@@ -0,0 +1,22 @@
+
+#pragma once
+
+#include "UnrealEd.h"
+#include "SpineAtlasAsset.h"
+#include "SpineAtlasImportFactory.generated.h"
+
+UCLASS()
+class USpineAtlasAssetFactory : public UFactory, public FReimportHandler
+{
+	GENERATED_UCLASS_BODY()
+
+	virtual FText GetToolTip() const override;
+	virtual bool FactoryCanImport(const FString& Filename) override;
+    virtual UObject* FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) override;
+    
+    virtual bool CanReimport(UObject* Obj, TArray<FString>& OutFilenames) override;
+    virtual void SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) override;
+    virtual EReimportResult::Type Reimport(UObject* Obj) override;
+
+    void LoadAtlas(USpineAtlasAsset* asset, const FString& currentSourcePath, const FString& longPackagePath);
+};

+ 17 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Public/SpineEditorPlugin.h

@@ -0,0 +1,17 @@
+
+#pragma once
+
+#include "ModuleManager.h"
+
+class ISpineEditorPlugin : public IModuleInterface {
+
+public:
+	static inline ISpineEditorPlugin& Get() {
+		return FModuleManager::LoadModuleChecked< ISpineEditorPlugin >( "SpineEditorPlugin" );
+	}
+
+	static inline bool IsAvailable() {
+		return FModuleManager::Get().IsModuleLoaded( "SpineEditorPlugin" );
+	}
+};
+

+ 20 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/Public/SpineSkeletonImportFactory.h

@@ -0,0 +1,20 @@
+
+#pragma once
+
+#include "UnrealEd.h"
+#include "SpineAtlasAsset.h"
+#include "SpineSkeletonImportFactory.generated.h"
+
+UCLASS()
+class USpineSkeletonAssetFactory : public UFactory, public FReimportHandler
+{
+	GENERATED_UCLASS_BODY()
+
+	virtual FText GetToolTip() const override;
+	virtual bool FactoryCanImport(const FString& Filename) override;
+    virtual UObject* FactoryCreateFile (UClass * InClass, UObject * InParent, FName InName, EObjectFlags Flags, const FString & Filename, const TCHAR* Parms, FFeedbackContext * Warn, bool& bOutOperationCanceled) override;
+    
+    virtual bool CanReimport(UObject* Obj, TArray<FString>& OutFilenames) override;
+    virtual void SetReimportPaths(UObject* Obj, const TArray<FString>& NewReimportPaths) override;
+    virtual EReimportResult::Type Reimport(UObject* Obj) override;
+};

+ 32 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpineEditorPlugin/SpineEditorPlugin.Build.cs

@@ -0,0 +1,32 @@
+// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
+
+namespace UnrealBuildTool.Rules
+{
+	public class SpineEditorPlugin : ModuleRules
+	{
+		public SpineEditorPlugin(TargetInfo Target)
+		{
+			PublicIncludePaths.AddRange(new string[] { "SpineEditorPlugin/Public" });
+            
+            PrivateIncludePaths.AddRange(new string[] { "SpineEditorPlugin/Private" });
+            
+            PublicDependencyModuleNames.AddRange(new string[] {
+                "Core",
+                "CoreUObject",
+                "Engine",
+                "UnrealEd",
+                "SpinePlugin"
+            });
+            
+            PublicIncludePathModuleNames.AddRange(new string[] {
+               "AssetTools",
+               "AssetRegistry"
+            });
+            
+            DynamicallyLoadedModuleNames.AddRange(new string[] {
+               "AssetTools",
+               "AssetRegistry"
+            });
+		}
+	}
+}

+ 82 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineAtlasAsset.cpp

@@ -0,0 +1,82 @@
+#include "SpinePluginPrivatePCH.h"
+#include "spine/spine.h"
+#include <string.h>
+#include <string>
+#include <stdlib.h>
+
+FString USpineAtlasAsset::GetRawData () const {
+    return rawData;
+}
+
+FName USpineAtlasAsset::GetAtlasFileName () const {
+#if WITH_EDITORONLY_DATA
+    TArray<FString> files;
+    if (importData) importData->ExtractFilenames(files);
+    if (files.Num() > 0) return FName(*files[0]);
+    else return atlasFileName;
+#else
+    return atlasFileName;
+#endif
+}
+
+#if WITH_EDITORONLY_DATA
+
+void USpineAtlasAsset::SetRawData (const FString &_rawData) {
+    this->rawData = _rawData;
+}
+
+void USpineAtlasAsset::SetAtlasFileName (const FName &_atlasFileName) {
+    importData->UpdateFilenameOnly(_atlasFileName.ToString());
+    TArray<FString> files;
+    importData->ExtractFilenames(files);
+    if (files.Num() > 0) atlasFileName = FName(*files[0]);
+}
+
+void USpineAtlasAsset::PostInitProperties () {
+    if (!HasAnyFlags(RF_ClassDefaultObject)) importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
+    Super::PostInitProperties();
+}
+
+void USpineAtlasAsset::GetAssetRegistryTags (TArray<FAssetRegistryTag>& OutTags) const {
+    if (importData) {
+        OutTags.Add(FAssetRegistryTag(SourceFileTagName(), importData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) );
+    }
+    
+    Super::GetAssetRegistryTags(OutTags);
+}
+
+void USpineAtlasAsset::Serialize (FArchive& Ar) {
+    Super::Serialize(Ar);
+    if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !importData)
+        importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
+}
+
+void USpineAtlasAsset::BeginDestroy () {
+    if (atlas) {
+        spAtlas_dispose(atlas);
+        atlas = nullptr;
+    }
+    Super::BeginDestroy();
+}
+
+spAtlas* USpineAtlasAsset::GetAtlas (bool forceReload) {
+    if (!atlas || forceReload) {
+        if (atlas) {
+            spAtlas_dispose(atlas);
+            atlas = nullptr;
+        }
+		std::string t = TCHAR_TO_UTF8(*rawData);
+        atlas = spAtlas_create(t.c_str(), strlen(t.c_str()), "", nullptr);
+        spAtlasPage* page = atlas->pages;
+        int i = 0;
+        while (page) {
+            int num = atlasPages.Num();
+            if (atlasPages.Num() > 0 && atlasPages.Num() > i)
+                page->rendererObject = atlasPages[i++];
+            page = page->next;
+        }        
+    }
+    return this->atlas;
+}
+
+#endif

+ 42 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpinePlugin.cpp

@@ -0,0 +1,42 @@
+// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
+
+#include "SpinePluginPrivatePCH.h"
+#include "spine/spine.h"
+
+
+class FSpinePlugin : public SpinePlugin {
+	/** IModuleInterface implementation */
+	virtual void StartupModule() override;
+	virtual void ShutdownModule() override;
+};
+
+IMPLEMENT_MODULE( FSpinePlugin, SpinePlugin )
+
+
+
+void FSpinePlugin::StartupModule() {
+	// This code will execute after your module is loaded into memory (but after global variables are initialized, of course.)
+    printf("This is a test");
+}
+
+
+void FSpinePlugin::ShutdownModule() {
+	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
+	// we call this function before unloading the module.
+}
+
+extern "C" {
+    void _spAtlasPage_createTexture (spAtlasPage* self, const char* path) {
+        
+    }
+    void _spAtlasPage_disposeTexture (spAtlasPage* self) {
+        
+    }
+    
+    char* _spUtil_readFile (const char* path, int* length) {
+        return 0;
+    }
+}
+
+
+

+ 10 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpinePluginPrivatePCH.h

@@ -0,0 +1,10 @@
+// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
+
+#include "SpinePlugin.h"
+
+// You should place include statements to your module's private header files here.  You only need to
+// add includes for headers that are used in most of your module's source files though.
+#include "SpineSkeletonDataAsset.h"
+#include "SpineAtlasAsset.h"
+#include "SpineSkeletonComponent.h"
+#include "SpineSkeletonRendererComponent.h"

+ 65 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp

@@ -0,0 +1,65 @@
+// iFll out your copyright notice in the Description page of Project Settings.
+
+#include "SpinePluginPrivatePCH.h"
+
+// Sets default values for this component's properties
+USpineSkeletonComponent::USpineSkeletonComponent()
+{
+	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
+	// off to improve performance if you don't need them.
+	bWantsBeginPlay = true;
+    PrimaryComponentTick.bCanEverTick = true;
+	bTickInEditor = true;
+	bAutoActivate = true;
+}
+
+void USpineSkeletonComponent::BeginPlay() {
+	Super::BeginPlay();
+}
+
+void USpineSkeletonComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) {
+	Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
+	
+	if (lastAtlas != atlas || lastData != skeletonData) {
+		DisposeState();
+
+		if (atlas && skeletonData) {
+			spSkeletonData* data = skeletonData->GetSkeletonData(atlas->GetAtlas(true), true);
+			skeleton = spSkeleton_create(data);
+			stateData = spAnimationStateData_create(data);
+			state = spAnimationState_create(stateData);
+			spAnimationState_setAnimationByName(state, 0, "walk", true);
+		}
+
+		lastAtlas = atlas;
+		lastData = skeletonData;
+	}
+
+	if (state) {
+		spAnimationState_update(state, DeltaTime);
+		spAnimationState_apply(state, skeleton);
+		spSkeleton_updateWorldTransform(skeleton);
+	}
+}
+
+void USpineSkeletonComponent::DisposeState() {
+	if (stateData) {
+		spAnimationStateData_dispose(stateData);
+		stateData = nullptr;
+	}
+
+	if (state) {
+		spAnimationState_dispose(state);
+		state = nullptr;
+	}
+
+	if (skeleton) {
+		spSkeleton_dispose(skeleton);
+		skeleton = nullptr;
+	}
+}
+
+void USpineSkeletonComponent::BeginDestroy() {
+	DisposeState();
+	Super::BeginDestroy();
+}

+ 79 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonDataAsset.cpp

@@ -0,0 +1,79 @@
+#include "SpinePluginPrivatePCH.h"
+#include "spine/spine.h"
+#include <string.h>
+#include <string>
+#include <stdlib.h>
+
+FName USpineSkeletonDataAsset::GetSkeletonDataFileName () const {
+#if WITH_EDITORONLY_DATA
+    TArray<FString> files;
+    if (importData) importData->ExtractFilenames(files);
+    if (files.Num() > 0) return FName(*files[0]);
+    else return skeletonDataFileName;
+#else
+    return skeletonDataFileName;
+#endif
+}
+
+TArray<uint8>& USpineSkeletonDataAsset::GetRawData () {
+    return this->rawData;
+}
+
+#if WITH_EDITORONLY_DATA
+
+void USpineSkeletonDataAsset::SetSkeletonDataFileName (const FName &_skeletonDataFileName) {
+    importData->UpdateFilenameOnly(_skeletonDataFileName.ToString());
+    TArray<FString> files;
+    importData->ExtractFilenames(files);
+    if (files.Num() > 0) this->skeletonDataFileName = FName(*files[0]);
+}
+
+void USpineSkeletonDataAsset::PostInitProperties () {
+    if (!HasAnyFlags(RF_ClassDefaultObject)) importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
+    Super::PostInitProperties();
+}
+
+void USpineSkeletonDataAsset::GetAssetRegistryTags (TArray<FAssetRegistryTag>& OutTags) const {
+    if (importData) {
+        OutTags.Add(FAssetRegistryTag(SourceFileTagName(), importData->GetSourceData().ToJson(), FAssetRegistryTag::TT_Hidden) );
+    }
+    
+    Super::GetAssetRegistryTags(OutTags);
+}
+
+void USpineSkeletonDataAsset::Serialize (FArchive& Ar) {
+    Super::Serialize(Ar);
+    if (Ar.IsLoading() && Ar.UE4Ver() < VER_UE4_ASSET_IMPORT_DATA_AS_JSON && !importData)
+        importData = NewObject<UAssetImportData>(this, TEXT("AssetImportData"));
+}
+
+void USpineSkeletonDataAsset::BeginDestroy () {
+    if (this->skeletonData) {
+        spSkeletonData_dispose(this->skeletonData);
+        this->skeletonData = nullptr;
+    }
+    Super::BeginDestroy();
+}
+
+spSkeletonData* USpineSkeletonDataAsset::GetSkeletonData (spAtlas* atlas, bool forceReload) {
+    if (!skeletonData || forceReload) {
+        if (skeletonData) {
+            spSkeletonData_dispose(skeletonData);
+            skeletonData = nullptr;
+        }
+        int dataLen = rawData.Num();
+        if (skeletonDataFileName.GetPlainNameString().Contains(TEXT(".json"))) {
+            spSkeletonJson* json = spSkeletonJson_create(atlas);
+            this->skeletonData = spSkeletonJson_readSkeletonData(json, (const char*)rawData.GetData());
+            spSkeletonJson_dispose(json);
+        } else {
+            spSkeletonBinary* binary = spSkeletonBinary_create(atlas);
+            this->skeletonData = spSkeletonBinary_readSkeletonData(binary, (const unsigned char*)rawData.GetData(), (int)rawData.Num());
+            spSkeletonBinary_dispose(binary);
+        }
+        lastAtlas = atlas;
+    }
+    return this->skeletonData;
+}
+
+#endif

+ 118 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonRendererComponent.cpp

@@ -0,0 +1,118 @@
+#include "SpinePluginPrivatePCH.h"
+#include "Engine.h"
+#include "spine/spine.h"
+#include <stdlib.h>
+
+USpineSkeletonRendererComponent::USpineSkeletonRendererComponent(const FObjectInitializer& ObjectInitializer)
+{
+	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
+	// off to improve performance if you don't need them.	
+	bWantsBeginPlay = true;
+	PrimaryComponentTick.bCanEverTick = true;
+	bTickInEditor = true;
+	bAutoActivate = true;	
+}
+
+// Called when the game starts
+void USpineSkeletonRendererComponent::BeginPlay()
+{
+	Super::BeginPlay();
+}
+
+// Called every frame
+void USpineSkeletonRendererComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction )
+{
+	Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
+
+	UClass* skeletonClass = USpineSkeletonComponent::StaticClass();
+	AActor* owner = GetOwner();
+	if (owner) {
+		USpineSkeletonComponent* skeleton = Cast<USpineSkeletonComponent>(owner->GetComponentByClass(skeletonClass));
+		if (skeleton && skeleton->skeleton) {
+			spSkeleton_updateWorldTransform(skeleton->skeleton);			
+			UpdateMesh(skeleton->skeleton);			
+		}
+	}		
+}
+
+void USpineSkeletonRendererComponent::UpdateMesh(spSkeleton* skeleton) {	
+	TArray<FVector> vertices;
+	TArray<int32> indices;
+	TArray<FVector2D> uvs;
+	TArray<FColor> colors;		
+
+	int worldVerticesLength = 1000;
+	float* worldVertices = (float*)malloc((2 + 2 + 5) * worldVerticesLength);
+	int idx = 0;
+	int meshSection = 0;
+
+	ClearAllMeshSections();
+
+	for (int i = 0; i < skeleton->slotsCount; ++i) {
+		spSlot* slot = skeleton->drawOrder[i];
+		spAttachment* attachment = slot->attachment;
+		if (!attachment) continue;						
+		
+		if (attachment->type == SP_ATTACHMENT_REGION) {
+			spRegionAttachment* regionAttachment = (spRegionAttachment*)attachment;			
+			spRegionAttachment_computeWorldVertices(regionAttachment, slot->bone, worldVertices);
+
+			uint8 r = static_cast<uint8>(skeleton->r * slot->r * 255);
+			uint8 g = static_cast<uint8>(skeleton->g * slot->g * 255);
+			uint8 b = static_cast<uint8>(skeleton->b * slot->b * 255);
+			uint8 a = static_cast<uint8>(skeleton->a * slot->a * 255);
+			
+			colors.Add(FColor(r, g, b, a));
+			vertices.Add(FVector(worldVertices[0], 0, worldVertices[1]));
+			uvs.Add(FVector2D(regionAttachment->uvs[0], regionAttachment->uvs[1]));
+
+			colors.Add(FColor(r, g, b, a));
+			vertices.Add(FVector(worldVertices[2], 0, worldVertices[3]));
+			uvs.Add(FVector2D(regionAttachment->uvs[2], regionAttachment->uvs[3]));
+
+			colors.Add(FColor(r, g, b, a));
+			vertices.Add(FVector(worldVertices[4], 0, worldVertices[5]));
+			uvs.Add(FVector2D(regionAttachment->uvs[4], regionAttachment->uvs[5]));
+
+			colors.Add(FColor(r, g, b, a));
+			vertices.Add(FVector(worldVertices[6], 0, worldVertices[7]));
+			uvs.Add(FVector2D(regionAttachment->uvs[6], regionAttachment->uvs[7]));
+
+			indices.Add(idx + 0);
+			indices.Add(idx + 1);
+			indices.Add(idx + 2);
+			indices.Add(idx + 0);
+			indices.Add(idx + 2);
+			indices.Add(idx + 3);
+			idx += 4;			
+		}
+		/*else if (attachment->type == ATTACHMENT_MESH) {
+			MeshAttachment* mesh = (MeshAttachment*)attachment;
+			if (mesh->super.worldVerticesLength > SPINE_MESH_VERTEX_COUNT_MAX) continue;
+			texture = (Texture*)((AtlasRegion*)mesh->rendererObject)->page->rendererObject;
+			MeshAttachment_computeWorldVertices(mesh, slot, worldVertices);
+
+			Uint8 r = static_cast<Uint8>(skeleton->r * slot->r * 255);
+			Uint8 g = static_cast<Uint8>(skeleton->g * slot->g * 255);
+			Uint8 b = static_cast<Uint8>(skeleton->b * slot->b * 255);
+			Uint8 a = static_cast<Uint8>(skeleton->a * slot->a * 255);
+			vertex.color.r = r;
+			vertex.color.g = g;
+			vertex.color.b = b;
+			vertex.color.a = a;
+
+			Vector2u size = texture->getSize();
+			for (int i = 0; i < mesh->trianglesCount; ++i) {
+				int index = mesh->triangles[i] << 1;
+				vertex.position.x = worldVertices[index];
+				vertex.position.y = worldVertices[index + 1];
+				vertex.texCoords.x = mesh->uvs[index] * size.x;
+				vertex.texCoords.y = mesh->uvs[index + 1] * size.y;
+				vertexArray->append(vertex);
+			}
+		}*/
+	}
+
+	CreateMeshSection(0, vertices, indices, TArray<FVector>(), uvs, colors, TArray<FProcMeshTangent>(), false);
+	free(worldVertices);
+}

+ 45 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineAtlasAsset.h

@@ -0,0 +1,45 @@
+#pragma once
+
+#include "Engine.h"
+#include "spine/spine.h"
+#include "SpineAtlasAsset.generated.h"
+
+UCLASS( ClassGroup=(Spine) )
+class SPINEPLUGIN_API USpineAtlasAsset : public UObject {
+    GENERATED_BODY()
+    
+public:
+    spAtlas* GetAtlas (bool forceReload = false);
+    
+    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
+    TArray<UTexture2D*> atlasPages;
+    
+    FString GetRawData () const;
+    FName GetAtlasFileName () const;
+    
+    virtual void BeginDestroy () override;
+    
+protected:
+    spAtlas* atlas = nullptr;
+    
+    UPROPERTY()
+    FString rawData;
+    
+    UPROPERTY()
+    FName atlasFileName;
+    
+#if WITH_EDITORONLY_DATA
+
+public:
+    void SetRawData (const FString &rawData);
+    void SetAtlasFileName (const FName &atlasFileName);
+    
+protected:
+    UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings)
+    class UAssetImportData* importData;
+    
+    virtual void PostInitProperties ( ) override;
+    virtual void GetAssetRegistryTags(TArray<FAssetRegistryTag>& OutTags) const override;
+    virtual void Serialize (FArchive& Ar) override;
+#endif
+};

+ 38 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpinePlugin.h

@@ -0,0 +1,38 @@
+// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "ModuleManager.h"
+
+
+/**
+ * The public interface to this module.  In most cases, this interface is only public to sibling modules
+ * within this plugin.
+ */
+class SPINEPLUGIN_API SpinePlugin : public IModuleInterface
+{
+
+public:
+
+	/**
+	 * Singleton-like access to this module's interface.  This is just for convenience!
+	 * Beware of calling this during the shutdown phase, though.  Your module might have been unloaded already.
+	 *
+	 * @return Returns singleton instance, loading the module on demand if needed
+	 */
+	static inline SpinePlugin& Get()
+	{
+		return FModuleManager::LoadModuleChecked< SpinePlugin >( "SpinePlugin" );
+	}
+
+	/**
+	 * Checks to see if this module is loaded and ready.  It is only valid to call Get() if IsAvailable() returns true.
+	 *
+	 * @return True if the module is loaded and ready to use
+	 */
+	static inline bool IsAvailable()
+	{
+		return FModuleManager::Get().IsModuleLoaded( "SpinePlugin" );
+	}
+};
+

+ 38 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonComponent.h

@@ -0,0 +1,38 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "Components/ActorComponent.h"
+#include "SpineSkeletonComponent.generated.h"
+
+class USpineAtlasAsset;
+UCLASS( ClassGroup=(Spine), meta=(BlueprintSpawnableComponent) )
+class SPINEPLUGIN_API USpineSkeletonComponent : public UActorComponent
+{
+	GENERATED_BODY()
+
+public:
+    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
+    USpineAtlasAsset* atlas;
+    
+    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spine)
+    USpineSkeletonDataAsset* skeletonData;
+
+	spAnimationStateData* stateData;
+	spAnimationState* state;
+	spSkeleton* skeleton;
+    	
+	USpineSkeletonComponent();
+	
+	virtual void BeginPlay() override;
+		
+	virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;	
+
+	virtual void BeginDestroy () override;	
+
+protected:
+	void DisposeState();	
+
+	USpineAtlasAsset* lastAtlas = nullptr;
+	USpineSkeletonDataAsset* lastData = nullptr;
+};

+ 41 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonDataAsset.h

@@ -0,0 +1,41 @@
+#pragma once
+
+#include "Engine.h"
+#include "spine/spine.h"
+#include "SpineSkeletonDataAsset.generated.h"
+
+UCLASS( ClassGroup=(Spine) )
+class SPINEPLUGIN_API USpineSkeletonDataAsset : public UObject {
+    GENERATED_BODY()
+    
+public:
+    spSkeletonData* GetSkeletonData(spAtlas* atlas, bool forceReload = false);
+    
+    FName GetSkeletonDataFileName () const;
+    TArray<uint8>& GetRawData ();
+    
+    virtual void BeginDestroy () override;
+    
+protected:
+    UPROPERTY()
+    TArray<uint8> rawData;
+    
+    spAtlas* lastAtlas = nullptr;
+    spSkeletonData* skeletonData = nullptr;
+    
+    UPROPERTY()
+    FName skeletonDataFileName;
+    
+#if WITH_EDITORONLY_DATA
+public:
+    void SetSkeletonDataFileName (const FName &skeletonDataFileName);    
+    
+protected:
+    UPROPERTY(VisibleAnywhere, Instanced, Category=ImportSettings)
+    class UAssetImportData* importData;
+    
+    virtual void PostInitProperties ( ) override;
+    virtual void GetAssetRegistryTags(TArray<FAssetRegistryTag>& OutTags) const override;
+    virtual void Serialize (FArchive& Ar) override;
+#endif
+};

+ 27 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonRendererComponent.h

@@ -0,0 +1,27 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "Components/ActorComponent.h"
+#include "ProceduralMeshComponent.h"
+#include "SpineSkeletonComponent.h"
+#include "SpineSkeletonRendererComponent.generated.h"
+
+
+UCLASS( ClassGroup=(Spine), meta=(BlueprintSpawnableComponent) )
+class SPINEPLUGIN_API USpineSkeletonRendererComponent : public UProceduralMeshComponent
+{
+	GENERATED_BODY()
+
+public:	
+	USpineSkeletonRendererComponent (const FObjectInitializer& ObjectInitializer);
+	
+	virtual void BeginPlay () override;
+		
+	virtual void TickComponent (float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;	
+
+protected:
+	void UpdateMesh (spSkeleton* skeleton);
+
+	bool updated;
+};

+ 16 - 0
spine-ue4/Plugins/SpinePlugin/Source/SpinePlugin/SpinePlugin.Build.cs

@@ -0,0 +1,16 @@
+// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
+
+namespace UnrealBuildTool.Rules
+{
+	public class SpinePlugin : ModuleRules
+	{
+		public SpinePlugin(TargetInfo Target)
+		{
+			PublicIncludePaths.AddRange(new string[] { "SpinePlugin/Public", "SpinePlugin/Public/spine-c/include" });
+            PrivateIncludePaths.AddRange(new string[] { "SpinePlugin/Private", "SpinePlugin/Public/spine-c/include" });
+            PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "ProceduralMeshComponent" });
+			PrivateDependencyModuleNames.AddRange(new string[] { "RHI", "RenderCore", "ShaderCore" });
+            OptimizeCode = CodeOptimization.Never;
+		}
+	}
+}

+ 29 - 0
spine-ue4/Plugins/SpinePlugin/SpinePlugin.uplugin

@@ -0,0 +1,29 @@
+{
+	"FileVersion" : 3,
+	"Version" : 1,
+	"VersionName" : "1.0",
+	"FriendlyName" : "Spine Plugin",
+	"Description" : "A plugin to load and render Spine animations in Unreal Engine",
+	"Category" : "2D",
+	"CreatedBy" : "Esoteric Software",
+	"CreatedByURL" : "http://esotericsoftware.com",
+	"DocsURL" : "",
+	"MarketplaceURL" : "",
+	"SupportURL" : "",
+	"EnabledByDefault" : false,
+	"CanContainContent" : false,
+	"IsBetaVersion" : false,
+	"Installed" : false,
+	"Modules" :
+	[
+		{
+			"Name" : "SpinePlugin",
+			"Type" : "Runtime",
+			"LoadingPhase" : "PreDefault"
+		},
+		{
+			"Name" : "SpineEditorPlugin",
+			"Type" : "Editor"
+		}
+	]
+}

+ 29 - 0
spine-ue4/README.md

@@ -0,0 +1,29 @@
+# spine-ue4
+The spine-ue4 runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [Unreal Engine 4](https://www.unrealengine.com/). spine-ue4 is based on [spine-c](https://github.com/EsotericSoftware/spine-runtimes/tree/master/spine-c).
+
+## Licensing
+
+This Spine Runtime may only be used for personal or internal use, typically to evaluate Spine before purchasing. If you would like to incorporate a Spine Runtime into your applications, distribute software containing a Spine Runtime, or modify a Spine Runtime, then you will need a valid [Spine license](https://esotericsoftware.com/spine-purchase). Please see the [Spine Runtimes Software License](https://github.com/EsotericSoftware/spine-runtimes/blob/master/LICENSE) for detailed information.
+
+The Spine Runtimes are developed with the intent to be used with data exported from Spine. By purchasing Spine, `Section 2` of the [Spine Software License](https://esotericsoftware.com/files/license.txt) grants the right to create and distribute derivative works of the Spine Runtimes.
+
+## Spine version
+
+spine-ue4 works with data exported from Spine 3.4.02.
+
+spine-ue4 supports all Spine features.
+
+## Usage
+1. Create a new Unreal Engine project. See the [Unreal Engine documentation](https://docs.unrealengine.com/latest/INT/) or have a look at the example in this repository.
+2. Download the Spine Runtimes source using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it [as a zip](https://github.com/EsotericSoftware/spine-runtimes/archive/master.zip)
+3. Copy the `Plugins` folder from this directory to your new project's root directory.
+4. Copy the `spine-c` folder from this repositories root directory to your project's `Plugins/SpinePlugin/Sources/SpinePlugin/Public/` directory.
+5. Open the Unreal Project in the Unreal Editor
+
+See the [Spine Runtimes documentation](http://esotericsoftware.com/spine-documentation#runtimesTitle) on how to use the APIs or check out the Spine UE4 example.
+
+## Example
+The Spine UE4 example works on all platforms supported by Unreal Engine.
+
+1. Copy the `spine-c` folder from this repositories root directory to your `Plugins/SpinePlugin/Sources/SpinePlugin/Public/` directory.
+2. Open the SpineUE4.uproject file with Unreal Editor

+ 25 - 0
spine-ue4/Source/SpineUE4.Target.cs

@@ -0,0 +1,25 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+using UnrealBuildTool;
+using System.Collections.Generic;
+
+public class SpineUE4Target : TargetRules
+{
+	public SpineUE4Target(TargetInfo Target)
+	{
+		Type = TargetType.Game;		
+	}
+
+	//
+	// TargetRules interface.
+	//
+
+	public override void SetupBinaries(
+		TargetInfo Target,
+		ref List<UEBuildBinaryConfiguration> OutBuildBinaryConfigurations,
+		ref List<string> OutExtraModuleNames
+		)
+	{
+		OutExtraModuleNames.AddRange( new string[] { "SpineUE4" } );		
+	}
+}

+ 21 - 0
spine-ue4/Source/SpineUE4/SpineUE4.Build.cs

@@ -0,0 +1,21 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+using UnrealBuildTool;
+
+public class SpineUE4 : ModuleRules
+{
+	public SpineUE4(TargetInfo Target)
+	{
+		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ProceduralMeshComponent" });
+
+		PrivateDependencyModuleNames.AddRange(new string[] {  });
+
+		// Uncomment if you are using Slate UI
+		// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
+		
+		// Uncomment if you are using online features
+		// PrivateDependencyModuleNames.Add("OnlineSubsystem");
+
+		// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
+	}
+}

+ 5 - 0
spine-ue4/Source/SpineUE4/SpineUE4.cpp

@@ -0,0 +1,5 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#include "SpineUE4.h"
+
+IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, SpineUE4, "SpineUE4" );

+ 6 - 0
spine-ue4/Source/SpineUE4/SpineUE4.h

@@ -0,0 +1,6 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "Engine.h"
+

+ 8 - 0
spine-ue4/Source/SpineUE4/SpineUE4GameMode.cpp

@@ -0,0 +1,8 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#include "SpineUE4.h"
+#include "SpineUE4GameMode.h"
+
+
+
+

+ 19 - 0
spine-ue4/Source/SpineUE4/SpineUE4GameMode.h

@@ -0,0 +1,19 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "GameFramework/GameMode.h"
+#include "SpineUE4GameMode.generated.h"
+
+/**
+ * 
+ */
+UCLASS()
+class SPINEUE4_API ASpineUE4GameMode : public AGameMode
+{
+	GENERATED_BODY()
+	
+	
+	
+	
+};

+ 25 - 0
spine-ue4/Source/SpineUE4Editor.Target.cs

@@ -0,0 +1,25 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+using UnrealBuildTool;
+using System.Collections.Generic;
+
+public class SpineUE4EditorTarget : TargetRules
+{
+	public SpineUE4EditorTarget(TargetInfo Target)
+	{
+		Type = TargetType.Editor;
+	}
+
+	//
+	// TargetRules interface.
+	//
+
+	public override void SetupBinaries(
+		TargetInfo Target,
+		ref List<UEBuildBinaryConfiguration> OutBuildBinaryConfigurations,
+		ref List<string> OutExtraModuleNames
+		)
+	{
+		OutExtraModuleNames.AddRange( new string[] { "SpineUE4" } );
+	}
+}

+ 16 - 0
spine-ue4/SpineUE4.uproject

@@ -0,0 +1,16 @@
+{
+	"FileVersion": 3,
+	"EngineAssociation": "4.13",
+	"Category": "",
+	"Description": "",
+	"Modules": [
+		{
+			"Name": "SpineUE4",
+			"Type": "Runtime",
+			"LoadingPhase": "Default",
+			"AdditionalDependencies": [
+				"Engine"
+			]
+		}
+	]
+}