diff --git a/spine-unity/Assets/Gizmos.meta b/spine-unity/Assets/Gizmos.meta new file mode 100644 index 000000000..a7b083b0c --- /dev/null +++ b/spine-unity/Assets/Gizmos.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: a260a1ff5965c2c4f88aea3e7d433965 +folderAsset: yes +DefaultImporter: + userData: diff --git a/spine-unity/Assets/Gizmos/SkeletonDataAsset Icon.png b/spine-unity/Assets/Gizmos/SkeletonDataAsset Icon.png new file mode 100644 index 000000000..7fd5473c1 Binary files /dev/null and b/spine-unity/Assets/Gizmos/SkeletonDataAsset Icon.png differ diff --git a/spine-unity/Assets/Gizmos/SkeletonDataAsset Icon.png.meta b/spine-unity/Assets/Gizmos/SkeletonDataAsset Icon.png.meta new file mode 100644 index 000000000..22239ca4b --- /dev/null +++ b/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: diff --git a/spine-unity/Assets/examples/dragon/dragon Atlas.asset b/spine-unity/Assets/examples/dragon/dragon Atlas.asset index 27089ff33..c1580f19d 100644 Binary files a/spine-unity/Assets/examples/dragon/dragon Atlas.asset and b/spine-unity/Assets/examples/dragon/dragon Atlas.asset differ diff --git a/spine-unity/Assets/examples/dragon/dragon SkeletonData.asset b/spine-unity/Assets/examples/dragon/dragon SkeletonData.asset index 548b0eda8..62d9a6b2c 100644 Binary files a/spine-unity/Assets/examples/dragon/dragon SkeletonData.asset and b/spine-unity/Assets/examples/dragon/dragon SkeletonData.asset differ diff --git a/spine-unity/Assets/examples/dragon/dragon.mat b/spine-unity/Assets/examples/dragon/dragon.mat index 57cb7c9ed..ce5ee6ef9 100644 Binary files a/spine-unity/Assets/examples/dragon/dragon.mat and b/spine-unity/Assets/examples/dragon/dragon.mat differ diff --git a/spine-unity/Assets/examples/dragon/dragon.unity b/spine-unity/Assets/examples/dragon/dragon.unity index 4982d0bd6..a3aa8af56 100644 Binary files a/spine-unity/Assets/examples/dragon/dragon.unity and b/spine-unity/Assets/examples/dragon/dragon.unity differ diff --git a/spine-unity/Assets/examples/dragon/dragon2.mat b/spine-unity/Assets/examples/dragon/dragon2.mat index e4431d44b..a42775b0b 100644 Binary files a/spine-unity/Assets/examples/dragon/dragon2.mat and b/spine-unity/Assets/examples/dragon/dragon2.mat differ diff --git a/spine-unity/Assets/examples/goblins/goblins Atlas.asset b/spine-unity/Assets/examples/goblins/goblins Atlas.asset index db873455e..416e4a631 100644 Binary files a/spine-unity/Assets/examples/goblins/goblins Atlas.asset and b/spine-unity/Assets/examples/goblins/goblins Atlas.asset differ diff --git a/spine-unity/Assets/examples/goblins/goblins Material.mat b/spine-unity/Assets/examples/goblins/goblins Material.mat index 84dfab0dc..9f7ddc82c 100644 Binary files a/spine-unity/Assets/examples/goblins/goblins Material.mat and b/spine-unity/Assets/examples/goblins/goblins Material.mat differ diff --git a/spine-unity/Assets/examples/goblins/goblins SkeletonData.asset b/spine-unity/Assets/examples/goblins/goblins SkeletonData.asset index 70a2a47c1..80c991288 100644 Binary files a/spine-unity/Assets/examples/goblins/goblins SkeletonData.asset and b/spine-unity/Assets/examples/goblins/goblins SkeletonData.asset differ diff --git a/spine-unity/Assets/examples/goblins/goblins.unity b/spine-unity/Assets/examples/goblins/goblins.unity index 5005ac399..b101c0972 100644 Binary files a/spine-unity/Assets/examples/goblins/goblins.unity and b/spine-unity/Assets/examples/goblins/goblins.unity differ diff --git a/spine-unity/Assets/examples/spineboy/SpineboyController.cs b/spine-unity/Assets/examples/spineboy/SpineboyController.cs new file mode 100644 index 000000000..be43009d9 --- /dev/null +++ b/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(); + } + + + 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; + } + + } + } +} diff --git a/spine-unity/Assets/examples/spineboy/SpineboyController.cs.meta b/spine-unity/Assets/examples/spineboy/SpineboyController.cs.meta new file mode 100644 index 000000000..1007cc854 --- /dev/null +++ b/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: diff --git a/spine-unity/Assets/examples/spineboy/data/spineboy.png.meta b/spine-unity/Assets/examples/spineboy/data/spineboy.png.meta index bd8a1a9d4..d53415a90 100644 --- a/spine-unity/Assets/examples/spineboy/data/spineboy.png.meta +++ b/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 diff --git a/spine-unity/Assets/examples/spineboy/spineboy Atlas.asset b/spine-unity/Assets/examples/spineboy/spineboy Atlas.asset index 50ce09a7a..1de336f9a 100644 Binary files a/spine-unity/Assets/examples/spineboy/spineboy Atlas.asset and b/spine-unity/Assets/examples/spineboy/spineboy Atlas.asset differ diff --git a/spine-unity/Assets/examples/spineboy/spineboy SkeletonData.asset b/spine-unity/Assets/examples/spineboy/spineboy SkeletonData.asset index 99d592451..4ea17f6a8 100644 Binary files a/spine-unity/Assets/examples/spineboy/spineboy SkeletonData.asset and b/spine-unity/Assets/examples/spineboy/spineboy SkeletonData.asset differ diff --git a/spine-unity/Assets/examples/spineboy/spineboy.mat b/spine-unity/Assets/examples/spineboy/spineboy.mat index fca128b10..94f333eea 100644 Binary files a/spine-unity/Assets/examples/spineboy/spineboy.mat and b/spine-unity/Assets/examples/spineboy/spineboy.mat differ diff --git a/spine-unity/Assets/examples/spineboy/spineboy.unity b/spine-unity/Assets/examples/spineboy/spineboy.unity index b50bffdac..3cad27a1d 100644 Binary files a/spine-unity/Assets/examples/spineboy/spineboy.unity and b/spine-unity/Assets/examples/spineboy/spineboy.unity differ diff --git a/spine-unity/Assets/examples/spineboy/spineboy_movement.unity b/spine-unity/Assets/examples/spineboy/spineboy_movement.unity new file mode 100644 index 000000000..0491aee5f --- /dev/null +++ b/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 diff --git a/spine-unity/Assets/examples/spineboy/spineboy_movement.unity.meta b/spine-unity/Assets/examples/spineboy/spineboy_movement.unity.meta new file mode 100644 index 000000000..9784bb952 --- /dev/null +++ b/spine-unity/Assets/examples/spineboy/spineboy_movement.unity.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: ce8726553213c1d4d99db0a795765d85 +DefaultImporter: + userData: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI.meta b/spine-unity/Assets/spine-unity/Editor/GUI.meta new file mode 100644 index 000000000..d730a5573 --- /dev/null +++ b/spine-unity/Assets/spine-unity/Editor/GUI.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: bfaea6b7e7f52bc46b8d1c3cb5e9eaa1 +folderAsset: yes +DefaultImporter: + userData: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png new file mode 100644 index 000000000..f44d38e90 Binary files /dev/null and b/spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png differ diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-animation.png.meta new file mode 100644 index 000000000..f8ac9f868 --- /dev/null +++ b/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: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png new file mode 100644 index 000000000..610754689 Binary files /dev/null and b/spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png differ diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-animationRoot.png.meta new file mode 100644 index 000000000..1b4c1e24f --- /dev/null +++ b/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: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png new file mode 100644 index 000000000..4547f254c Binary files /dev/null and b/spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png differ diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-event.png.meta new file mode 100644 index 000000000..71c672b9c --- /dev/null +++ b/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: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png new file mode 100644 index 000000000..b5d5adf28 Binary files /dev/null and b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png differ diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skeleton.png.meta new file mode 100644 index 000000000..2b8ef8c4f --- /dev/null +++ b/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: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png new file mode 100644 index 000000000..289871e41 Binary files /dev/null and b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png differ diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-skinsRoot.png.meta new file mode 100644 index 000000000..ab536e515 --- /dev/null +++ b/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: diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png b/spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png new file mode 100644 index 000000000..7fd5473c1 Binary files /dev/null and b/spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png differ diff --git a/spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png.meta b/spine-unity/Assets/spine-unity/Editor/GUI/icon-spine.png.meta new file mode 100644 index 000000000..e620c9210 --- /dev/null +++ b/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: diff --git a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs b/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs index 932df4c38..8ae3fa966 100644 --- a/spine-unity/Assets/spine-unity/Editor/SkeletonDataAssetInspector.cs +++ b/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 m_animEvents = new List(); + List m_animEventFrames = new List(); + 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(); + 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; + } +} \ No newline at end of file diff --git a/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs b/spine-unity/Assets/spine-unity/Editor/SpineEditorUtilities.cs new file mode 100644 index 000000000..eb887cda9 --- /dev/null +++ b/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 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(); + + EditorApplication.hierarchyWindowChanged += HierarchyWindowChanged; + EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemOnGUI; + + HierarchyWindowChanged(); + } + + static void HierarchyWindowChanged(){ + skeletonRendererInstanceIDs.Clear(); + + SkeletonRenderer[] arr = Object.FindObjectsOfType(); + + 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.atlasFile = atlasText; + + + + + string[] atlasLines = atlasText.text.Split('\n'); + List pageFiles = new List(); + 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(); + 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(); + 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; + } + + +} diff --git a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs b/spine-unity/Assets/spine-unity/SkeletonRenderer.cs index fc7fff4f6..dd8eea25b 100644 --- a/spine-unity/Assets/spine-unity/SkeletonRenderer.cs +++ b/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); diff --git a/spine-unity/Assets/spine-unity/SpineUnity_Readme.pdf b/spine-unity/Assets/spine-unity/SpineUnity_Readme.pdf new file mode 100644 index 000000000..266629c6e Binary files /dev/null and b/spine-unity/Assets/spine-unity/SpineUnity_Readme.pdf differ