Bläddra i källkod

SpineUnity Import process enhancements
scaled down examples to match standard Unity practices
added spineboy movement example

Fenrisul 11 år sedan
förälder
incheckning
7f700eeb93
38 ändrade filer med 1573 tillägg och 5 borttagningar
  1. 5 0
      spine-unity/Assets/Gizmos.meta
  2. BIN
      spine-unity/Assets/Gizmos/SkeletonDataAsset Icon.png
  3. 46 0
      spine-unity/Assets/Gizmos/SkeletonDataAsset Icon.png.meta
  4. BIN
      spine-unity/Assets/examples/dragon/dragon Atlas.asset
  5. BIN
      spine-unity/Assets/examples/dragon/dragon SkeletonData.asset
  6. BIN
      spine-unity/Assets/examples/dragon/dragon.mat
  7. BIN
      spine-unity/Assets/examples/dragon/dragon.unity
  8. BIN
      spine-unity/Assets/examples/dragon/dragon2.mat
  9. BIN
      spine-unity/Assets/examples/goblins/goblins Atlas.asset
  10. BIN
      spine-unity/Assets/examples/goblins/goblins Material.mat
  11. BIN
      spine-unity/Assets/examples/goblins/goblins SkeletonData.asset
  12. BIN
      spine-unity/Assets/examples/goblins/goblins.unity
  13. 86 0
      spine-unity/Assets/examples/spineboy/SpineboyController.cs
  14. 8 0
      spine-unity/Assets/examples/spineboy/SpineboyController.cs.meta
  15. 1 0
      spine-unity/Assets/examples/spineboy/data/spineboy.png.meta
  16. BIN
      spine-unity/Assets/examples/spineboy/spineboy Atlas.asset
  17. BIN
      spine-unity/Assets/examples/spineboy/spineboy SkeletonData.asset
  18. BIN
      spine-unity/Assets/examples/spineboy/spineboy.mat
  19. BIN
      spine-unity/Assets/examples/spineboy/spineboy.unity
  20. 355 0
      spine-unity/Assets/examples/spineboy/spineboy_movement.unity
  21. 4 0
      spine-unity/Assets/examples/spineboy/spineboy_movement.unity.meta
  22. 5 0
      spine-unity/Assets/spine-unity/Editor/GUI.meta
  23. BIN
      spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png
  24. 46 0
      spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png.meta
  25. BIN
      spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png
  26. 46 0
      spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png.meta
  27. BIN
      spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png
  28. 46 0
      spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png.meta
  29. BIN
      spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png
  30. 46 0
      spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png.meta
  31. BIN
      spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png
  32. 46 0
      spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png.meta
  33. BIN
      spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png
  34. 46 0
      spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png.meta
  35. 493 4
      spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs
  36. 290 0
      spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs
  37. 4 1
      spine-unity/Assets/spine-unity/SkeletonRenderer.cs
  38. BIN
      spine-unity/Assets/spine-unity/SpineUnity_Readme.pdf

+ 5 - 0
spine-unity/Assets/Gizmos.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: a260a1ff5965c2c4f88aea3e7d433965
+folderAsset: yes
+DefaultImporter:
+  userData: 

BIN
spine-unity/Assets/Gizmos/SkeletonDataAsset Icon.png


+ 46 - 0
spine-unity/Assets/Gizmos/SkeletonDataAsset Icon.png.meta

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

BIN
spine-unity/Assets/examples/dragon/dragon Atlas.asset


BIN
spine-unity/Assets/examples/dragon/dragon SkeletonData.asset


BIN
spine-unity/Assets/examples/dragon/dragon.mat


BIN
spine-unity/Assets/examples/dragon/dragon.unity


BIN
spine-unity/Assets/examples/dragon/dragon2.mat


BIN
spine-unity/Assets/examples/goblins/goblins Atlas.asset


BIN
spine-unity/Assets/examples/goblins/goblins Material.mat


BIN
spine-unity/Assets/examples/goblins/goblins SkeletonData.asset


BIN
spine-unity/Assets/examples/goblins/goblins.unity


+ 86 - 0
spine-unity/Assets/examples/spineboy/SpineboyController.cs

@@ -0,0 +1,86 @@
+using UnityEngine;
+using System.Collections;
+
+[RequireComponent(typeof(SkeletonAnimation), typeof(Rigidbody2D))]
+public class SpineboyController : MonoBehaviour {
+
+	SkeletonAnimation skeletonAnimation;
+
+	public string idleAnimation = "idle";
+	public string walkAnimation = "walk";
+	public string runAnimation = "run";
+	public string hitAnimation = "hit";
+	public string deathAnimation = "death";
+
+	public float walkVelocity = 1;
+	public float runVelocity = 3;
+	public int hp = 10;
+
+	string currentAnimation = "";
+
+	bool hit = false;
+	bool dead = false;
+
+	void Start () {
+		skeletonAnimation = GetComponent<SkeletonAnimation>();
+	}
+
+
+	void Update(){
+		if(!dead){
+			float x = Input.GetAxis("Horizontal");
+			float absX = Mathf.Abs(x);
+
+			if(!hit){
+				if(x > 0)
+					skeletonAnimation.skeleton.FlipX = false;
+				else if(x < 0)
+					skeletonAnimation.skeleton.FlipX = true;
+
+				if(absX > 0.7f){
+					SetAnimation(runAnimation, true);
+					rigidbody2D.velocity = new Vector2( runVelocity * Mathf.Sign(x), rigidbody2D.velocity.y);
+				}
+				else if(absX > 0){
+					SetAnimation(walkAnimation, true);
+					rigidbody2D.velocity = new Vector2( walkVelocity * Mathf.Sign(x), rigidbody2D.velocity.y);
+				}
+				else{
+					SetAnimation(idleAnimation, true);
+					rigidbody2D.velocity = new Vector2( 0, rigidbody2D.velocity.y);
+				}
+			}
+			else{
+				if(skeletonAnimation.state.GetCurrent(0).Animation.Name != hitAnimation)
+					hit = false;
+			}
+		}
+	}
+
+
+	void SetAnimation(string anim, bool loop){
+		if(currentAnimation != anim){
+			skeletonAnimation.state.SetAnimation(0, anim, loop);
+			currentAnimation = anim;
+		}
+	}
+
+	void OnMouseUp(){
+
+		if(hp > 0){
+			hp--;
+
+			if(hp == 0){
+				SetAnimation(deathAnimation, false);
+				dead = true;
+			}
+			else{
+				skeletonAnimation.state.SetAnimation(0, hitAnimation, false);
+				skeletonAnimation.state.AddAnimation(0, currentAnimation, true, 0);
+				rigidbody2D.velocity = new Vector2( 0, rigidbody2D.velocity.y);
+				hit = true;
+			}
+
+		}
+	}
+}

+ 8 - 0
spine-unity/Assets/examples/spineboy/SpineboyController.cs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ef0903d879ea9ca49a1fd44d707beb9d
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 

+ 1 - 0
spine-unity/Assets/examples/spineboy/data/spineboy.png.meta

@@ -35,6 +35,7 @@ TextureImporter:
   spriteMeshType: 1
   alignment: 0
   spritePivot: {x: .5, y: .5}
+  spriteBorder: {x: 0, y: 0, z: 0, w: 0}
   spritePixelsToUnits: 100
   alphaIsTransparency: 0
   textureType: -1

BIN
spine-unity/Assets/examples/spineboy/spineboy Atlas.asset


BIN
spine-unity/Assets/examples/spineboy/spineboy SkeletonData.asset


BIN
spine-unity/Assets/examples/spineboy/spineboy.mat


BIN
spine-unity/Assets/examples/spineboy/spineboy.unity


+ 355 - 0
spine-unity/Assets/examples/spineboy/spineboy_movement.unity

@@ -0,0 +1,355 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+SceneSettings:
+  m_ObjectHideFlags: 0
+  m_PVSData: 
+  m_PVSObjectsArray: []
+  m_PVSPortalsArray: []
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: .25
+    backfaceThreshold: 100
+--- !u!104 &2
+RenderSettings:
+  m_Fog: 0
+  m_FogColor: {r: .5, g: .5, b: .5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: .00999999978
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientLight: {r: .200000003, g: .200000003, b: .200000003, a: 1}
+  m_SkyboxMaterial: {fileID: 0}
+  m_HaloStrength: .5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 0}
+  m_ObjectHideFlags: 0
+--- !u!127 &3
+LevelGameManager:
+  m_ObjectHideFlags: 0
+--- !u!157 &4
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  m_LightProbes: {fileID: 0}
+  m_Lightmaps: []
+  m_LightmapsMode: 1
+  m_BakedColorSpace: 0
+  m_UseDualLightmapsInForward: 0
+  m_LightmapEditorSettings:
+    m_Resolution: 50
+    m_LastUsedResolution: 0
+    m_TextureWidth: 1024
+    m_TextureHeight: 1024
+    m_BounceBoost: 1
+    m_BounceIntensity: 1
+    m_SkyLightColor: {r: .860000014, g: .930000007, b: 1, a: 1}
+    m_SkyLightIntensity: 0
+    m_Quality: 0
+    m_Bounces: 1
+    m_FinalGatherRays: 1000
+    m_FinalGatherContrastThreshold: .0500000007
+    m_FinalGatherGradientThreshold: 0
+    m_FinalGatherInterpolationPoints: 15
+    m_AOAmount: 0
+    m_AOMaxDistance: .100000001
+    m_AOContrast: 1
+    m_LODSurfaceMappingDistance: 1
+    m_Padding: 0
+    m_TextureCompression: 0
+    m_LockAtlas: 0
+--- !u!196 &5
+NavMeshSettings:
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    agentRadius: .5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: .400000006
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    accuratePlacement: 0
+    minRegionArea: 2
+    widthInaccuracy: 16.666666
+    heightInaccuracy: 10
+  m_NavMesh: {fileID: 0}
+--- !u!1 &103710462
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 4
+  m_Component:
+  - 4: {fileID: 103710467}
+  - 20: {fileID: 103710466}
+  - 92: {fileID: 103710465}
+  - 124: {fileID: 103710464}
+  - 81: {fileID: 103710463}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &103710463
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 103710462}
+  m_Enabled: 1
+--- !u!124 &103710464
+Behaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 103710462}
+  m_Enabled: 1
+--- !u!92 &103710465
+Behaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 103710462}
+  m_Enabled: 1
+--- !u!20 &103710466
+Camera:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 103710462}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: .192156866, g: .301960796, b: .474509805, a: .0196078438}
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: .300000012
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_HDR: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: .0219999999
+--- !u!4 &103710467
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 103710462}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+--- !u!1 &498745350
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 4
+  m_Component:
+  - 4: {fileID: 498745355}
+  - 33: {fileID: 498745354}
+  - 23: {fileID: 498745353}
+  - 114: {fileID: 498745352}
+  - 114: {fileID: 498745351}
+  - 50: {fileID: 498745357}
+  - 61: {fileID: 498745356}
+  m_Layer: 0
+  m_Name: Spineboy
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &498745351
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 498745350}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: ef0903d879ea9ca49a1fd44d707beb9d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  idleAnimation: idle
+  walkAnimation: walk
+  runAnimation: run
+  hitAnimation: hit
+  deathAnimation: death
+  walkVelocity: 2.5
+  runVelocity: 10
+  hp: 10
+--- !u!114 &498745352
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 498745350}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d247ba06193faa74d9335f5481b2b56c, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  skeletonDataAsset: {fileID: 11400000, guid: d04edfd5d421496409ca795016a48045, type: 2}
+  initialSkinName: default
+  calculateNormals: 0
+  calculateTangents: 0
+  zSpacing: 0
+  renderMeshes: 1
+  immutableTriangles: 0
+  logErrors: 0
+  timeScale: 1
+  loop: 1
+  _animationName: idle
+--- !u!23 &498745353
+Renderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 498745350}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_LightmapIndex: 255
+  m_LightmapTilingOffset: {x: 1, y: 1, z: 0, w: 0}
+  m_Materials:
+  - {fileID: 0}
+  m_SubsetIndices: 
+  m_StaticBatchRoot: {fileID: 0}
+  m_UseLightProbes: 0
+  m_LightProbeAnchor: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+--- !u!33 &498745354
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 498745350}
+  m_Mesh: {fileID: 0}
+--- !u!4 &498745355
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 498745350}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: .229821205, z: 0}
+  m_LocalScale: {x: .28331995, y: .28331995, z: .28331995}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 1
+--- !u!61 &498745356
+BoxCollider2D:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 498745350}
+  m_Enabled: 1
+  m_Material: {fileID: 0}
+  m_IsTrigger: 0
+  m_Size: {x: 3.12331629, y: 6.97735691}
+  m_Center: {x: .0340548158, y: 3.36076927}
+--- !u!50 &498745357
+Rigidbody2D:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 498745350}
+  m_Mass: 1
+  m_LinearDrag: 0
+  m_AngularDrag: .0500000007
+  m_GravityScale: 1
+  m_FixedAngle: 0
+  m_IsKinematic: 0
+  m_Interpolate: 0
+  m_SleepingMode: 1
+  m_CollisionDetection: 0
+--- !u!1 &1415830073
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 4
+  m_Component:
+  - 4: {fileID: 1415830077}
+  - 33: {fileID: 1415830076}
+  - 23: {fileID: 1415830075}
+  - 61: {fileID: 1415830074}
+  m_Layer: 0
+  m_Name: Ground
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!61 &1415830074
+BoxCollider2D:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1415830073}
+  m_Enabled: 1
+  m_Material: {fileID: 0}
+  m_IsTrigger: 0
+  m_Size: {x: 1, y: 1}
+  m_Center: {x: 0, y: 0}
+--- !u!23 &1415830075
+Renderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1415830073}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_LightmapIndex: 255
+  m_LightmapTilingOffset: {x: 1, y: 1, z: 0, w: 0}
+  m_Materials:
+  - {fileID: 10302, guid: 0000000000000000f000000000000000, type: 0}
+  m_SubsetIndices: 
+  m_StaticBatchRoot: {fileID: 0}
+  m_UseLightProbes: 0
+  m_LightProbeAnchor: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_SortingLayerID: 0
+  m_SortingOrder: 0
+--- !u!33 &1415830076
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1415830073}
+  m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1415830077
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1415830073}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: .132730573, y: -.602417529, z: 0}
+  m_LocalScale: {x: 29.7312527, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 2

+ 4 - 0
spine-unity/Assets/examples/spineboy/spineboy_movement.unity.meta

@@ -0,0 +1,4 @@
+fileFormatVersion: 2
+guid: ce8726553213c1d4d99db0a795765d85
+DefaultImporter:
+  userData: 

+ 5 - 0
spine-unity/Assets/spine-unity/Editor/GUI.meta

@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: bfaea6b7e7f52bc46b8d1c3cb5e9eaa1
+folderAsset: yes
+DefaultImporter:
+  userData: 

BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png


+ 46 - 0
spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png.meta

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

BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png


+ 46 - 0
spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png.meta

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

BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png


+ 46 - 0
spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png.meta

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

BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png


+ 46 - 0
spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png.meta

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

BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png


+ 46 - 0
spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png.meta

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

BIN
spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png


+ 46 - 0
spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png.meta

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

+ 493 - 4
spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs

@@ -29,7 +29,9 @@
  *****************************************************************************/
 
 using System;
+using System.Collections.Generic;
 using UnityEditor;
+using UnityEditor.AnimatedValues;
 using UnityEngine;
 using Spine;
 
@@ -37,6 +39,11 @@ using Spine;
 public class SkeletonDataAssetInspector : Editor {
 	private SerializedProperty atlasAsset, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix;
 	private bool showAnimationStateData = true;
+	private AnimBool m_showAnimationList = new AnimBool(true);
+
+	private bool m_initialized = false;
+	private SkeletonDataAsset m_skeletonDataAsset;
+	private string m_skeletonDataAssetGUID;
 
 	void OnEnable () {
 		atlasAsset = serializedObject.FindProperty("atlasAsset");
@@ -46,23 +53,44 @@ public class SkeletonDataAssetInspector : Editor {
 		toAnimation = serializedObject.FindProperty("toAnimation");
 		duration = serializedObject.FindProperty("duration");
 		defaultMix = serializedObject.FindProperty("defaultMix");
-	}
 
+		m_skeletonDataAsset = (SkeletonDataAsset)target;
+		m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath(m_skeletonDataAsset) );
+
+		EditorApplication.update += Update;
+	}
+	
+	void OnDestroy(){
+		m_initialized = false;
+		EditorApplication.update -= Update;
+		this.DestroyPreviewInstances();
+		if (this.m_previewUtility != null)
+		{
+			this.m_previewUtility.Cleanup();
+			this.m_previewUtility = null;
+		}
+	}
+	
 	override public void OnInspectorGUI () {
 		serializedObject.Update();
 		SkeletonDataAsset asset = (SkeletonDataAsset)target;
 
+		EditorGUI.BeginChangeCheck();
 		EditorGUILayout.PropertyField(atlasAsset);
 		EditorGUILayout.PropertyField(skeletonJSON);
 		EditorGUILayout.PropertyField(scale);
-		
+		if(EditorGUI.EndChangeCheck()){
+			m_previewUtility.Cleanup();
+			m_previewUtility = null;
+		}
+
 		SkeletonData skeletonData = asset.GetSkeletonData(asset.atlasAsset == null || asset.skeletonJSON == null);
 		if (skeletonData != null) {
 			showAnimationStateData = EditorGUILayout.Foldout(showAnimationStateData, "Animation State Data");
 			if (showAnimationStateData) {
 				EditorGUILayout.PropertyField(defaultMix);
 
-				// Animation names.
+				// Animation names
 				String[] animations = new String[skeletonData.Animations.Count];
 				for (int i = 0; i < animations.Length; i++)
 					animations[i] = skeletonData.Animations[i].Name;
@@ -92,6 +120,43 @@ public class SkeletonDataAssetInspector : Editor {
 				EditorGUILayout.Space();
 				EditorGUILayout.EndHorizontal();
 			}
+
+			if(GUILayout.Button(new GUIContent("Setup Pose", SpineEditorUtilities.Icons.skeleton),  GUILayout.Width(105), GUILayout.Height(18))){
+				StopAnimation();
+				m_skeletonAnimation.skeleton.SetToSetupPose();
+				m_requireRefresh = true;
+			}
+
+			m_showAnimationList.target = EditorGUILayout.Foldout(m_showAnimationList.target, new GUIContent("Animations", SpineEditorUtilities.Icons.animationRoot));
+
+			if(EditorGUILayout.BeginFadeGroup(m_showAnimationList.faded)){
+
+				EditorGUILayout.LabelField("Name", "Duration");
+				foreach(Spine.Animation a in skeletonData.Animations){
+					GUILayout.BeginHorizontal();
+
+					if(m_skeletonAnimation != null && m_skeletonAnimation.state != null){
+						if(m_skeletonAnimation.state.GetCurrent(0) != null && m_skeletonAnimation.state.GetCurrent(0).Animation == a){
+							GUI.contentColor = Color.black;
+							if(GUILayout.Button("\u25BA", GUILayout.Width(24))){
+								StopAnimation();
+							}
+							GUI.contentColor = Color.white;
+						}
+						else{
+							if(GUILayout.Button("\u25BA", GUILayout.Width(24))){
+								PlayAnimation(a.Name, true);
+							}
+						}
+					}
+					else{
+						GUILayout.Label("?", GUILayout.Width(24));
+					}
+					EditorGUILayout.LabelField(new GUIContent(a.Name, SpineEditorUtilities.Icons.animation), new GUIContent(a.Duration.ToString("f3") + "s" +  ("(" + (Mathf.RoundToInt(a.Duration * 30)) + ")").PadLeft(12, ' ')));
+					GUILayout.EndHorizontal();
+				}
+			}
+			EditorGUILayout.EndFadeGroup();
 		}
 		
 		if (!Application.isPlaying) {
@@ -102,4 +167,428 @@ public class SkeletonDataAssetInspector : Editor {
 			}
 		}
 	}
-}
+	
+	//preview window stuff
+	private PreviewRenderUtility m_previewUtility;
+	private GameObject m_previewInstance;
+	private Vector2 previewDir;
+	private SkeletonAnimation m_skeletonAnimation;
+	private SkeletonData m_skeletonData;
+
+	private static int sliderHash = "Slider".GetHashCode();
+	private float m_lastTime;
+	private bool m_playing;
+	private bool m_requireRefresh;
+
+	private Color m_originColor = new Color(0.3f,0.3f,0.3f, 1);
+
+	private void StopAnimation(){
+		m_skeletonAnimation.state.ClearTrack(0);
+		m_playing = false;
+	}
+
+
+	List<Spine.Event> m_animEvents = new List<Spine.Event>();
+	List<float> m_animEventFrames = new List<float>();
+	private void PlayAnimation(string animName, bool loop){
+		m_animEvents.Clear();
+		m_animEventFrames.Clear();
+
+		m_skeletonAnimation.state.SetAnimation(0, animName, loop);
+
+		Spine.Animation a = m_skeletonAnimation.state.GetCurrent(0).Animation;
+		foreach(Timeline t in a.Timelines){
+			if(t.GetType() == typeof(EventTimeline)){
+				EventTimeline et = (EventTimeline)t;
+
+				for(int i = 0; i < et.Events.Length; i++){
+					m_animEvents.Add(et.Events[i]);
+					m_animEventFrames.Add(et.Frames[i]);
+				}
+
+			}
+		}
+
+		m_playing = true;
+	}
+	
+	private void InitPreview()
+	{
+		if (this.m_previewUtility == null)
+		{
+			this.m_lastTime = Time.realtimeSinceStartup;
+			this.m_previewUtility = new PreviewRenderUtility(true);
+			this.m_previewUtility.m_Camera.isOrthoGraphic = true;
+			this.m_previewUtility.m_Camera.orthographicSize = 1;
+			this.m_previewUtility.m_Camera.cullingMask = -2147483648;
+			this.CreatePreviewInstances();
+		}
+	}
+
+	private void CreatePreviewInstances()
+	{
+		this.DestroyPreviewInstances();
+		if (this.m_previewInstance == null)
+		{
+			string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", "");
+
+			m_previewInstance = SpineEditorUtilities.SpawnAnimatedSkeleton( (SkeletonDataAsset)target, skinName ).gameObject;
+			m_previewInstance.hideFlags = HideFlags.HideAndDontSave;
+			m_previewInstance.layer = 0x1f;
+
+
+			m_skeletonAnimation = m_previewInstance.GetComponent<SkeletonAnimation>();
+			m_skeletonAnimation.initialSkinName = skinName;
+			m_skeletonAnimation.LateUpdate();
+
+			m_skeletonData = m_skeletonAnimation.skeletonDataAsset.GetSkeletonData(true);
+
+			m_previewInstance.renderer.enabled = false;
+
+			m_initialized = true;
+			AdjustCameraGoals(true);
+		}
+	}
+
+	private void DestroyPreviewInstances()
+	{
+		if (this.m_previewInstance != null)
+		{
+			DestroyImmediate(this.m_previewInstance);
+			m_previewInstance = null;
+		}
+		m_initialized = false;
+	}
+
+	public override bool HasPreviewGUI ()
+	{
+		return true;
+	}
+
+	Texture m_previewTex = new Texture();
+	public override void OnInteractivePreviewGUI(Rect r, GUIStyle background)
+	{
+		this.InitPreview();
+
+		if (UnityEngine.Event.current.type == EventType.Repaint)
+		{
+			if(m_requireRefresh){
+				this.m_previewUtility.BeginPreview(r, background);
+				this.DoRenderPreview(true);
+				this.m_previewTex = this.m_previewUtility.EndPreview();
+				m_requireRefresh = false;
+			}
+			if(this.m_previewTex != null)
+				GUI.DrawTexture(r, m_previewTex, ScaleMode.StretchToFill, false);
+		}
+
+		DrawSkinToolbar(r);
+		NormalizedTimeBar(r);
+		//TODO: implement panning
+//		this.previewDir = Drag2D(this.previewDir, r);
+		MouseScroll(r);
+	}
+
+	float m_orthoGoal = 1;
+	Vector3 m_posGoal = new Vector3(0,0,-10);
+	double m_adjustFrameEndTime = 0;
+	private void AdjustCameraGoals(bool calculateMixTime){
+		if(calculateMixTime){
+			if(m_skeletonAnimation.state.GetCurrent(0) != null){
+				m_adjustFrameEndTime = EditorApplication.timeSinceStartup + m_skeletonAnimation.state.GetCurrent(0).Mix;
+			}
+		}
+
+
+		GameObject go = this.m_previewInstance;
+		Bounds bounds = go.renderer.bounds;
+		m_orthoGoal = bounds.size.y;
+		
+		m_posGoal = bounds.center + new Vector3(0,0,-10);
+	}
+
+	private void AdjustCameraGoals(){
+		AdjustCameraGoals(false);
+	}
+
+	private void AdjustCamera(){
+		if(m_previewUtility == null)
+			return;
+
+
+		if(EditorApplication.timeSinceStartup < m_adjustFrameEndTime){
+			AdjustCameraGoals();
+		}
+
+		float orthoSet = Mathf.Lerp(this.m_previewUtility.m_Camera.orthographicSize, m_orthoGoal, 0.1f);
+
+		this.m_previewUtility.m_Camera.orthographicSize = orthoSet;
+
+		float dist = Vector3.Distance(m_previewUtility.m_Camera.transform.position, m_posGoal);
+		if(dist > 60f * ((SkeletonDataAsset)target).scale){
+			Vector3 pos = Vector3.Lerp(this.m_previewUtility.m_Camera.transform.position, m_posGoal, 0.1f);
+			pos.x = 0;
+			this.m_previewUtility.m_Camera.transform.position = pos;
+			this.m_previewUtility.m_Camera.transform.rotation = Quaternion.identity;
+			m_requireRefresh = true;
+		}
+	}
+
+	private void DoRenderPreview(bool drawHandles)
+	{
+		GameObject go = this.m_previewInstance;
+
+		if(m_requireRefresh){
+			go.renderer.enabled = true;
+
+			if(EditorApplication.isPlaying){
+				//do nothing
+			}
+			else{
+				m_skeletonAnimation.Update((Time.realtimeSinceStartup - m_lastTime));
+			}
+
+			m_lastTime = Time.realtimeSinceStartup;
+
+			if(!EditorApplication.isPlaying)
+				m_skeletonAnimation.LateUpdate();
+		
+			if(drawHandles){
+				Handles.SetCamera(m_previewUtility.m_Camera);
+				Handles.color = m_originColor;
+				
+				Handles.DrawLine(new Vector3(-1000 * m_skeletonDataAsset.scale,0,0), new Vector3(1000 * m_skeletonDataAsset.scale,0,0));
+				Handles.DrawLine(new Vector3(0,1000 * m_skeletonDataAsset.scale,0), new Vector3(0,-1000 * m_skeletonDataAsset.scale,0));
+			}
+			
+			this.m_previewUtility.m_Camera.Render();
+			go.renderer.enabled = false;
+		}
+
+
+	}
+
+	void Update(){
+		AdjustCamera();
+
+		if (m_playing) {
+			m_requireRefresh = true;
+			Repaint();
+		}
+		else if (m_requireRefresh) {
+			Repaint ();
+		}
+		else{
+			if(m_showAnimationList.isAnimating)
+				Repaint();
+		}
+	}
+
+	void DrawSkinToolbar(Rect r){
+		if(m_skeletonAnimation == null)
+			return;
+
+		if(m_skeletonAnimation.skeleton != null){
+			string label = (m_skeletonAnimation.skeleton != null && m_skeletonAnimation.skeleton.Skin != null) ? m_skeletonAnimation.skeleton.Skin.Name : "default";
+
+			Rect popRect = new Rect(r);
+			popRect.y += 32;
+			popRect.x += 4;
+			popRect.height = 24;
+			popRect.width = 40;
+			EditorGUI.DropShadowLabel(popRect, new GUIContent("Skin", SpineEditorUtilities.Icons.skinsRoot));
+
+			popRect.y += 11;
+			popRect.width = 150;
+			popRect.x += 44;
+
+			if(GUI.Button( popRect, label, EditorStyles.popup)){
+				SelectSkinContext();
+			}
+		}
+	}
+
+	void SelectSkinContext(){
+		GenericMenu menu = new GenericMenu();
+		
+		foreach(Skin s in m_skeletonData.Skins){
+			menu.AddItem( new GUIContent(s.Name), this.m_skeletonAnimation.skeleton.Skin == s, SetSkin, (object)s);
+		}
+
+		menu.ShowAsContext();
+	}
+	
+	void SetSkin(object o){
+		Skin skin = (Skin)o;
+
+		m_skeletonAnimation.initialSkinName = skin.Name;
+		m_skeletonAnimation.Reset();
+		m_requireRefresh = true;
+
+		EditorPrefs.SetString(m_skeletonDataAssetGUID + "_lastSkin", skin.Name);
+	}
+
+	void NormalizedTimeBar(Rect r){
+		Rect barRect = new Rect(r);
+		barRect.height = 32;
+		barRect.x += 4;
+		barRect.width -=4;
+
+		GUI.Box(barRect, "");
+
+		Rect lineRect = new Rect(barRect);
+		float width = lineRect.width;
+		TrackEntry t = m_skeletonAnimation.state.GetCurrent(0);
+
+		if(t != null){
+			int loopCount = (int)(t.Time / t.EndTime);
+			float currentTime = t.Time - (t.EndTime * loopCount);
+
+			float normalizedTime = currentTime / t.Animation.Duration;
+
+			lineRect.x = barRect.x + (width * normalizedTime) - 0.5f;
+			lineRect.width = 2;
+
+			GUI.color = Color.red;
+			GUI.DrawTexture(lineRect, EditorGUIUtility.whiteTexture);
+			GUI.color = Color.white;
+	
+			for(int i = 0; i < m_animEvents.Count; i++){
+				//TODO: Tooltip
+				//Spine.Event spev = animEvents[i];
+
+				float fr = m_animEventFrames[i];
+
+				Rect evRect = new Rect(barRect);
+				evRect.x = Mathf.Clamp(((fr / t.Animation.Duration) * width) - (SpineEditorUtilities.Icons._event.width/2), barRect.x, float.MaxValue);
+				evRect.width = SpineEditorUtilities.Icons._event.width;
+				evRect.height = SpineEditorUtilities.Icons._event.height;
+				evRect.y += SpineEditorUtilities.Icons._event.height;
+				GUI.DrawTexture(evRect, SpineEditorUtilities.Icons._event);
+
+
+				//TODO:  Tooltip
+				/*
+				UnityEngine.Event ev = UnityEngine.Event.current;
+				if(ev.isMouse){
+					if(evRect.Contains(ev.mousePosition)){
+						Rect tooltipRect = new Rect(evRect);
+						tooltipRect.width = 500;
+						tooltipRect.y -= 4;
+						tooltipRect.x += 4;
+						GUI.Label(tooltipRect, spev.Data.Name);
+					}
+				}
+				*/
+			}
+		}
+	}
+
+	void MouseScroll(Rect position){
+		UnityEngine.Event current = UnityEngine.Event.current;
+		int controlID = GUIUtility.GetControlID(sliderHash, FocusType.Passive);
+
+		switch(current.GetTypeForControl(controlID)){
+		case EventType.ScrollWheel:
+			if(position.Contains(current.mousePosition)){
+
+				m_orthoGoal += current.delta.y * ((SkeletonDataAsset)target).scale * 10;
+				GUIUtility.hotControl = controlID;
+				current.Use();
+			}
+			break;
+		}
+
+	}
+
+	//TODO:  Implement preview panning
+	/*
+	static Vector2 Drag2D(Vector2 scrollPosition, Rect position)
+	{
+		int controlID = GUIUtility.GetControlID(sliderHash, FocusType.Passive);
+		UnityEngine.Event current = UnityEngine.Event.current;
+		switch (current.GetTypeForControl(controlID))
+		{
+		case EventType.MouseDown:
+			if (position.Contains(current.mousePosition) && (position.width > 50f))
+			{
+				GUIUtility.hotControl = controlID;
+				current.Use();
+				EditorGUIUtility.SetWantsMouseJumping(1);
+			}
+			return scrollPosition;
+			
+		case EventType.MouseUp:
+			if (GUIUtility.hotControl == controlID)
+			{
+				GUIUtility.hotControl = 0;
+			}
+			EditorGUIUtility.SetWantsMouseJumping(0);
+			return scrollPosition;
+			
+		case EventType.MouseMove:
+			return scrollPosition;
+			
+		case EventType.MouseDrag:
+			if (GUIUtility.hotControl == controlID)
+			{
+				scrollPosition -= (Vector2) (((current.delta * (!current.shift ? ((float) 1) : ((float) 3))) / Mathf.Min(position.width, position.height)) * 140f);
+				scrollPosition.y = Mathf.Clamp(scrollPosition.y, -90f, 90f);
+				current.Use();
+				GUI.changed = true;
+			}
+			return scrollPosition;
+		}
+		return scrollPosition;
+	}
+	*/
+
+	public override GUIContent GetPreviewTitle ()
+	{
+		return new GUIContent ("Preview");
+	}
+
+	public override void OnPreviewSettings ()
+	{
+		if(!m_initialized){
+			GUILayout.HorizontalSlider(0,0,2, GUILayout.MaxWidth(64));
+		}
+		else{
+			float speed = GUILayout.HorizontalSlider( m_skeletonAnimation.timeScale, 0, 2, GUILayout.MaxWidth(64));
+
+			//snap to nearest 0.25
+			float y = speed / 0.25f;
+			int q = Mathf.RoundToInt(y);
+			speed = q * 0.25f;
+
+			m_skeletonAnimation.timeScale = speed;
+		}
+	}
+
+	//TODO:  Fix first-import error
+	//TODO:  Update preview without thumbnail
+	public override Texture2D RenderStaticPreview (string assetPath, UnityEngine.Object[] subAssets, int width, int height)
+	{
+		Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false);
+
+		this.InitPreview();
+
+		if(this.m_previewUtility.m_Camera == null)
+			return null;
+
+			m_requireRefresh = true;
+			this.DoRenderPreview(false);
+			AdjustCameraGoals(false);
+
+			this.m_previewUtility.m_Camera.orthographicSize = m_orthoGoal/2;
+			this.m_previewUtility.m_Camera.transform.position = m_posGoal;
+			this.m_previewUtility.BeginStaticPreview(new Rect(0,0,width,height));
+			this.DoRenderPreview(false);
+			Handles.SetCamera(this.m_previewUtility.m_Camera);
+			Handles.BeginGUI();
+			GUI.DrawTexture(new Rect(40,60,width,height), SpineEditorUtilities.Icons.spine, ScaleMode.StretchToFill);
+			Handles.EndGUI();
+			tex = this.m_previewUtility.EndStaticPreview();
+		return tex;
+	}
+}

+ 290 - 0
spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs

@@ -0,0 +1,290 @@
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Spine;
+
+[InitializeOnLoad]
+public static class SpineEditorUtilities {
+
+	public static class Icons{
+		public static Texture2D skeleton;
+		public static Texture2D nullBone;
+		public static Texture2D bone;
+		public static Texture2D boneNib;
+		public static Texture2D slot;
+		public static Texture2D skinPlaceholder;
+		public static Texture2D image;
+		public static Texture2D boundingBox;
+		public static Texture2D mesh;
+		public static Texture2D skin;
+		public static Texture2D skinsRoot;
+		public static Texture2D animation;
+		public static Texture2D animationRoot;
+		public static Texture2D spine;
+		public static Texture2D _event;
+
+		public static Mesh boneMesh{
+			get{
+				if(_boneMesh == null){
+					_boneMesh = new Mesh();
+					_boneMesh.vertices = new Vector3[4]{Vector3.zero, new Vector3(-0.1f,0.1f,0), Vector3.up, new Vector3(0.1f,0.1f,0)};
+					_boneMesh.uv = new Vector2[4];
+					_boneMesh.triangles = new int[6]{0,1,2,2,3,0};
+					_boneMesh.RecalculateBounds();
+					_boneMesh.RecalculateNormals();
+				}
+
+				return _boneMesh;
+			}
+		}
+		internal static Mesh _boneMesh;
+
+
+		public static Material boneMaterial{
+			get{
+				if(_boneMaterial == null){
+					_boneMaterial = new Material(Shader.Find("Spine/Bones"));
+					_boneMaterial.SetColor("_Color", new Color(0.4f, 0.4f, 0.4f, 0.25f));
+				}
+
+				return _boneMaterial;
+			}
+		}
+		internal static Material _boneMaterial;
+
+		public static void Initialize(){
+			skeleton = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skeleton.png");
+			nullBone = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-null.png");
+			bone = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-bone.png");
+			boneNib = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-boneNib.png");
+			slot = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-slot.png");
+			skinPlaceholder = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skinPlaceholder.png");
+			image = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-image.png");
+			boundingBox = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-boundingBox.png");
+			mesh = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-mesh.png");
+			skin = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skinPlaceholder.png");
+			skinsRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-skinsRoot.png");
+			animation = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-animation.png");
+			animationRoot = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-animationRoot.png");
+			spine = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-spine.png");
+			_event = (Texture2D)AssetDatabase.LoadMainAssetAtPath( SpineEditorUtilities.editorGUIPath + "/icon-event.png");
+		}
+
+	}
+
+
+
+	public static string editorPath = "";
+	public static string editorGUIPath = "";
+
+	static List<int> skeletonRendererInstanceIDs;
+
+	public static float defaultScale = 0.01f;
+	public static float defaultMix = 0.2f;
+	public static string defaultShader = "Spine/Skeleton";
+	
+	static SpineEditorUtilities(){
+		DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath);
+		FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories);
+		editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets"));
+		editorGUIPath = editorPath + "/GUI";	
+
+		Icons.Initialize();
+
+		skeletonRendererInstanceIDs = new List<int>();
+
+		EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged;
+		EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI;
+
+		HierarchyWindowChanged();
+	}
+
+	static void HierarchyWindowChanged(){
+		skeletonRendererInstanceIDs.Clear();
+
+		SkeletonRenderer[] arr = Object.FindObjectsOfType<SkeletonRenderer>();
+
+		foreach(SkeletonRenderer r in arr)
+			skeletonRendererInstanceIDs.Add(r.gameObject.GetInstanceID());
+	}
+
+	static void HierarchyWindowItemOnGUI(int instanceId, Rect selectionRect){
+		if(skeletonRendererInstanceIDs.Contains(instanceId)){
+			Rect r = new Rect (selectionRect); 
+			r.x = r.width - 15;
+			r.width = 15;
+
+			GUI.Label(r, Icons.spine);
+		}
+	}
+	
+	[MenuItem("Assets/Spine/Ingest")]
+	static void IngestSpineProject(){
+		TextAsset spineJson = null;
+		TextAsset atlasText = null;
+		
+		foreach(UnityEngine.Object o in Selection.objects){
+			if(o.GetType() != typeof(TextAsset))
+				continue;
+			
+			string fileName = Path.GetFileName(AssetDatabase.GetAssetPath(o));
+			
+			if(fileName.EndsWith(".json"))
+				spineJson = (TextAsset)o;
+			else if(fileName.EndsWith(".atlas.txt"))
+				atlasText = (TextAsset)o;
+		}
+		
+		if(spineJson == null){
+			EditorUtility.DisplayDialog("Error!", "Spine JSON file not found in selection!", "OK");
+			return;
+		}
+		
+		string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
+		string assetPath = Path.GetDirectoryName( AssetDatabase.GetAssetPath(spineJson));
+		
+		if(atlasText == null){
+			string atlasPath = assetPath + "/" + primaryName + ".atlas.txt";
+			atlasText = (TextAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(TextAsset));
+		}
+		
+		if(spineJson != null && atlasText != null){
+			
+			AssetPreview.GetMiniTypeThumbnail(typeof(bool));
+			
+			AtlasAsset atlasAsset = AtlasAsset.CreateInstance<AtlasAsset>();
+			atlasAsset.atlasFile = atlasText;
+
+
+
+			
+			string[] atlasLines = atlasText.text.Split('\n');
+			List<string> pageFiles = new List<string>();
+			for(int i = 0; i < atlasLines.Length-1; i++){
+				if(atlasLines[i].Length == 0)
+					pageFiles.Add(atlasLines[i+1]);
+			}
+
+			atlasAsset.materials = new Material[pageFiles.Count];
+
+			for(int i = 0; i < pageFiles.Count; i++){
+				string texturePath = assetPath + "/" + pageFiles[i];
+				Texture2D texture = (Texture2D)AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D));
+				
+				TextureImporter texImporter = (TextureImporter)TextureImporter.GetAtPath(texturePath);
+				texImporter.textureFormat = TextureImporterFormat.AutomaticTruecolor;
+				texImporter.mipmapEnabled = false;
+				EditorUtility.SetDirty(texImporter);
+				AssetDatabase.ImportAsset(texturePath);
+				AssetDatabase.SaveAssets();
+
+				string pageName = Path.GetFileNameWithoutExtension(pageFiles[i]);
+
+				//because this looks silly
+				if(pageName == primaryName && pageFiles.Count == 1)
+					pageName = "Material";
+
+				string materialPath = assetPath + "/" + primaryName + "_" + pageName + ".mat";
+
+				Material mat = new Material(Shader.Find(defaultShader));
+
+				mat.mainTexture = texture;
+				
+				AssetDatabase.CreateAsset(mat, materialPath);
+				AssetDatabase.SaveAssets();
+				
+				atlasAsset.materials[i] = mat;
+			}
+			
+			AssetDatabase.CreateAsset(atlasAsset, assetPath + "/" + primaryName + "_Atlas.asset");
+			AssetDatabase.SaveAssets();
+			
+			SkeletonDataAsset skelDataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset>();
+			skelDataAsset.atlasAsset = atlasAsset;
+			skelDataAsset.skeletonJSON = spineJson;
+			skelDataAsset.fromAnimation = new string[0];
+			skelDataAsset.toAnimation = new string[0];
+			skelDataAsset.duration = new float[0];
+			skelDataAsset.defaultMix = defaultMix;
+			skelDataAsset.scale = defaultScale;
+
+			AssetDatabase.CreateAsset(skelDataAsset, assetPath + "/" + primaryName + "_SkeletonData.asset");
+			AssetDatabase.SaveAssets();
+		}
+		else{
+			EditorUtility.DisplayDialog("Error!", "Atlas file not found in selection!", "OK");
+			return;
+		}
+	}
+
+	[MenuItem("Assets/Spine/Spawn")]
+	static void SpawnAnimatedSkeleton(){
+		Object[] arr = Selection.objects;
+
+		foreach(Object o in arr){
+
+			string guid = AssetDatabase.AssetPathToGUID( AssetDatabase.GetAssetPath( o ) );
+			string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
+
+			SpawnAnimatedSkeleton((SkeletonDataAsset)o, skinName);
+			SceneView.RepaintAll();
+		}
+	}
+
+	[MenuItem("Assets/Spine/Spawn", true)]
+	static bool ValidateSpawnAnimatedSkeleton(){
+		Object[] arr = Selection.objects;
+		
+		if(arr.Length == 0)
+			return false;
+		
+		foreach(Object o in arr){
+			if(o.GetType() != typeof(SkeletonDataAsset))
+				return false;
+		}
+		
+		return true;
+	}
+
+	public static SkeletonAnimation SpawnAnimatedSkeleton(SkeletonDataAsset skeletonDataAsset, string skinName){
+		return SpawnAnimatedSkeleton(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
+	}
+
+	public static SkeletonAnimation SpawnAnimatedSkeleton(SkeletonDataAsset skeletonDataAsset, Skin skin = null){
+		
+		GameObject go = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
+		SkeletonAnimation anim = go.GetComponent<SkeletonAnimation>();
+		anim.skeletonDataAsset = skeletonDataAsset;
+
+		bool requiresNormals = false;
+
+		foreach(Material m in anim.skeletonDataAsset.atlasAsset.materials){
+			if(m.shader.name.Contains("Lit")){
+				requiresNormals = true;
+				break;
+			}
+		}
+
+		anim.calculateNormals = requiresNormals;
+
+		if(skin == null)
+			skin = skeletonDataAsset.GetSkeletonData(true).DefaultSkin;
+
+		anim.Reset();
+		
+		anim.skeleton.SetSkin(skin);
+		anim.initialSkinName = skin.Name;
+		
+		anim.skeleton.Update(1);
+		anim.state.Update(1);
+		anim.state.Apply(anim.skeleton);
+		anim.skeleton.UpdateWorldTransform();
+
+		return anim;
+	}
+
+
+}

+ 4 - 1
spine-unity/Assets/spine-unity/SkeletonRenderer.cs

@@ -47,6 +47,7 @@ public class SkeletonRenderer : MonoBehaviour {
 	public bool calculateNormals, calculateTangents;
 	public float zSpacing;
 	public bool renderMeshes = true, immutableTriangles;
+	public bool logErrors = false;
 	
 	private MeshFilter meshFilter;
 	private Mesh mesh, mesh1, mesh2;
@@ -78,7 +79,9 @@ public class SkeletonRenderer : MonoBehaviour {
 
 		valid = false;
 		if (!skeletonDataAsset) {
-			Debug.LogError("Missing SkeletonData asset.", this);
+			if(logErrors)
+				Debug.LogError("Missing SkeletonData asset.", this);
+
 			return;
 		}
 		SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false);

BIN
spine-unity/Assets/spine-unity/SpineUnity_Readme.pdf