Merge pull request #362 from Fenrisul/master

SkeletonAnimator & Unity5 compatibility pass
This commit is contained in:
Fenrisul 2015-02-17 18:40:34 -08:00
commit 7c861591d4
85 changed files with 939 additions and 128 deletions

1
.gitignore vendored
View File

@ -38,6 +38,7 @@ spine-cocos2d-iphone/3/cocos2d/*
spine-csharp/bin spine-csharp/bin
spine-csharp/obj spine-csharp/obj
spine-csharp/src/*.cs.meta
spine-monogame/xamarinstudio-ios/src/bin spine-monogame/xamarinstudio-ios/src/bin
spine-monogame/xamarinstudio-ios/src/obj spine-monogame/xamarinstudio-ios/src/obj

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -50,7 +50,7 @@ public class DynamicSpineBone : MonoBehaviour {
lastPosition = speedReference.position; lastPosition = speedReference.position;
} }
void UpdateLocal(SkeletonAnimation animation) { void UpdateLocal(SkeletonRenderer renderer) {
Vector3 vec = useAcceleration ? acceleration : velocity; Vector3 vec = useAcceleration ? acceleration : velocity;
if (Mathf.Abs(vec.x) < returnThreshhold) if (Mathf.Abs(vec.x) < returnThreshhold)

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -44,7 +44,7 @@ public class Goblins : MonoBehaviour {
} }
// This is called after the animation is applied to the skeleton and can be used to adjust the bones dynamically. // This is called after the animation is applied to the skeleton and can be used to adjust the bones dynamically.
public void UpdateLocal (SkeletonAnimation skeletonAnimation) { public void UpdateLocal (SkeletonRenderer skeletonRenderer) {
headBone.Rotation += 15; headBone.Rotation += 15;
} }

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -68,13 +68,13 @@ public class SpineboyController : MonoBehaviour {
if (absX > 0.7f) { if (absX > 0.7f) {
SetAnimation(runAnimation, true); SetAnimation(runAnimation, true);
rigidbody2D.velocity = new Vector2(runVelocity * Mathf.Sign(x), rigidbody2D.velocity.y); GetComponent<Rigidbody2D>().velocity = new Vector2(runVelocity * Mathf.Sign(x), GetComponent<Rigidbody2D>().velocity.y);
} else if (absX > 0) { } else if (absX > 0) {
SetAnimation(walkAnimation, true); SetAnimation(walkAnimation, true);
rigidbody2D.velocity = new Vector2(walkVelocity * Mathf.Sign(x), rigidbody2D.velocity.y); GetComponent<Rigidbody2D>().velocity = new Vector2(walkVelocity * Mathf.Sign(x), GetComponent<Rigidbody2D>().velocity.y);
} else { } else {
SetAnimation(idleAnimation, true); SetAnimation(idleAnimation, true);
rigidbody2D.velocity = new Vector2(0, rigidbody2D.velocity.y); GetComponent<Rigidbody2D>().velocity = new Vector2(0, GetComponent<Rigidbody2D>().velocity.y);
} }
} else { } else {
if (skeletonAnimation.state.GetCurrent(0).Animation.Name != hitAnimation) if (skeletonAnimation.state.GetCurrent(0).Animation.Name != hitAnimation)
@ -101,7 +101,7 @@ public class SpineboyController : MonoBehaviour {
} else { } else {
skeletonAnimation.state.SetAnimation(0, hitAnimation, false); skeletonAnimation.state.SetAnimation(0, hitAnimation, false);
skeletonAnimation.state.AddAnimation(0, currentAnimation, true, 0); skeletonAnimation.state.AddAnimation(0, currentAnimation, true, 0);
rigidbody2D.velocity = new Vector2(0, rigidbody2D.velocity.y); GetComponent<Rigidbody2D>().velocity = new Vector2(0, GetComponent<Rigidbody2D>().velocity.y);
hit = true; hit = true;
} }

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -1 textureFormat: -1
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -1 textureFormat: -1
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: -1 wrapMode: -1
nPOTScale: 1 nPOTScale: 1
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -1 textureFormat: -1
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -1 textureFormat: -1
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -1 textureFormat: -1
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -20,6 +20,9 @@ TextureImporter:
isReadable: 0 isReadable: 0
grayScaleToAlpha: 0 grayScaleToAlpha: 0
generateCubemap: 0 generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 8
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0 seamlessCubemap: 0
textureFormat: -3 textureFormat: -3
maxTextureSize: 1024 maxTextureSize: 1024
@ -30,6 +33,7 @@ TextureImporter:
wrapMode: 1 wrapMode: 1
nPOTScale: 0 nPOTScale: 0
lightmap: 0 lightmap: 0
rGBM: 0
compressionQuality: 50 compressionQuality: 50
spriteMode: 0 spriteMode: 0
spriteExtrude: 1 spriteExtrude: 1
@ -45,3 +49,5 @@ TextureImporter:
sprites: [] sprites: []
spritePackingTag: spritePackingTag:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,71 @@
/******************************************************************************
* Spine Runtimes Software License
* Version 2.1
*
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable and
* non-transferable license to install, execute and perform the Spine Runtimes
* Software (the "Software") solely for internal use. Without the written
* permission of Esoteric Software (typically granted by licensing Spine), you
* may not (a) modify, translate, adapt or otherwise create derivative works,
* improvements of the Software or develop new applications using the Software
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
* trademark, patent or other intellectual property or proprietary rights
* notices on or in the Software, including any copy thereof. Redistributions
* in binary or source form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
/*****************************************************************************
* SkeletonAnimatorInspector created by Mitch Thompson
* Full irrevocable rights and permissions granted to Esoteric Software
*****************************************************************************/
using System;
using UnityEditor;
using UnityEngine;
using Spine;
[CustomEditor(typeof(SkeletonAnimator))]
public class SkeletonAnimatorInspector : SkeletonRendererInspector {
protected SerializedProperty layerMixModes;
protected bool isPrefab;
protected override void OnEnable () {
base.OnEnable();
layerMixModes = serializedObject.FindProperty("layerMixModes");
if (PrefabUtility.GetPrefabType(this.target) == PrefabType.Prefab)
isPrefab = true;
}
protected override void gui () {
base.gui();
EditorGUILayout.PropertyField(layerMixModes, true);
SkeletonAnimator component = (SkeletonAnimator)target;
if (!component.valid)
return;
EditorGUILayout.Space();
if (!isPrefab) {
if (component.GetComponent<SkeletonUtility>() == null) {
if (GUILayout.Button(new GUIContent("Add Skeleton Utility", SpineEditorUtilities.Icons.skeletonUtility), GUILayout.Height(30))) {
component.gameObject.AddComponent<SkeletonUtility>();
}
}
}
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6a9ca5213a3a4614c9a9f2e60909bc33
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -39,6 +39,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.IO;
using Spine; using Spine;
@ -88,20 +89,32 @@ public static class SkeletonBaker {
var skeletonData = skeletonDataAsset.GetSkeletonData(true); var skeletonData = skeletonDataAsset.GetSkeletonData(true);
bool hasAnimations = bakeAnimations && skeletonData.Animations.Count > 0; bool hasAnimations = bakeAnimations && skeletonData.Animations.Count > 0;
#if UNITY_5
UnityEditor.Animations.AnimatorController controller = null;
#else
UnityEditorInternal.AnimatorController controller = null; UnityEditorInternal.AnimatorController controller = null;
#endif
if (hasAnimations) { if (hasAnimations) {
string controllerPath = outputPath + "/" + skeletonDataAsset.skeletonJSON.name + " Controller.controller"; string controllerPath = outputPath + "/" + skeletonDataAsset.skeletonJSON.name + " Controller.controller";
bool newAnimContainer = false; bool newAnimContainer = false;
var runtimeController = AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController)); var runtimeController = AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController));
#if UNITY_5
if (runtimeController != null) {
controller = (UnityEditor.Animations.AnimatorController)runtimeController;
} else {
controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
newAnimContainer = true;
}
#else
if (runtimeController != null) { if (runtimeController != null) {
controller = (UnityEditorInternal.AnimatorController)runtimeController; controller = (UnityEditorInternal.AnimatorController)runtimeController;
} else { } else {
controller = UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath); controller = UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
newAnimContainer = true; newAnimContainer = true;
} }
#endif
Dictionary<string, AnimationClip> existingClipTable = new Dictionary<string, AnimationClip>(); Dictionary<string, AnimationClip> existingClipTable = new Dictionary<string, AnimationClip>();
List<string> unusedClipNames = new List<string>(); List<string> unusedClipNames = new List<string>();
@ -146,7 +159,12 @@ public static class SkeletonBaker {
unusedClipNames.Remove(clip.name); unusedClipNames.Remove(clip.name);
} else { } else {
AssetDatabase.AddObjectToAsset(clip, controller); AssetDatabase.AddObjectToAsset(clip, controller);
AnimatorController.AddAnimationClipToController(controller, clip); #if UNITY_5_0
controller.AddMotion(clip);
#else
UnityEditorInternal.AnimatorController.AddAnimationClipToController(controller, clip);
#endif
} }
} }
@ -172,7 +190,7 @@ public static class SkeletonBaker {
bool newPrefab = false; bool newPrefab = false;
string prefabPath = outputPath + "/" + skeletonDataAsset.skeletonJSON.name + " (" + skin.Name + ").prefab"; string prefabPath = outputPath + "/" + skeletonDataAsset.skeletonJSON.name + " (" + skin.Name + ").prefab";
Object prefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)); Object prefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));
if (prefab == null) { if (prefab == null) {
@ -307,8 +325,8 @@ public static class SkeletonBaker {
attachmentTransform.gameObject.AddComponent<MeshRenderer>(); attachmentTransform.gameObject.AddComponent<MeshRenderer>();
} }
attachmentTransform.renderer.sharedMaterial = material; attachmentTransform.GetComponent<Renderer>().sharedMaterial = material;
attachmentTransform.renderer.sortingOrder = i; attachmentTransform.GetComponent<Renderer>().sortingOrder = i;
if (attachmentName != slotData.AttachmentName) if (attachmentName != slotData.AttachmentName)
attachmentTransform.gameObject.SetActive(false); attachmentTransform.gameObject.SetActive(false);
@ -330,7 +348,7 @@ public static class SkeletonBaker {
animator.runtimeAnimatorController = (RuntimeAnimatorController)controller; animator.runtimeAnimatorController = (RuntimeAnimatorController)controller;
EditorGUIUtility.PingObject(controller); EditorGUIUtility.PingObject(controller);
} }
if (newPrefab) { if (newPrefab) {
PrefabUtility.ReplacePrefab(prefabRoot, prefab, ReplacePrefabOptions.ConnectToPrefab); PrefabUtility.ReplacePrefab(prefabRoot, prefab, ReplacePrefabOptions.ConnectToPrefab);
@ -353,6 +371,113 @@ public static class SkeletonBaker {
} }
public static void GenerateMecanimAnimationClips (SkeletonDataAsset skeletonDataAsset) {
var data = skeletonDataAsset.GetSkeletonData(true);
if (data == null) {
Debug.LogError("SkeletonData failed!", skeletonDataAsset);
return;
}
string dataPath = AssetDatabase.GetAssetPath(skeletonDataAsset);
string controllerPath = dataPath.Replace("_SkeletonData", "_Controller").Replace(".asset", ".controller");
#if UNITY_5
UnityEditor.Animations.AnimatorController controller;
if (skeletonDataAsset.controller != null) {
controller = (UnityEditor.Animations.AnimatorController)skeletonDataAsset.controller;
} else {
if (File.Exists(controllerPath)) {
if (EditorUtility.DisplayDialog("Controller Overwrite Warning", "Unknown Controller already exists at: " + controllerPath, "Update", "Overwrite")) {
controller = (UnityEditor.Animations.AnimatorController)AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController));
} else {
controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
}
} else {
controller = (UnityEditor.Animations.AnimatorController)UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
}
}
#else
UnityEditorInternal.AnimatorController controller;
if (skeletonDataAsset.controller != null) {
controller = (UnityEditorInternal.AnimatorController)skeletonDataAsset.controller;
} else {
if (File.Exists(controllerPath)) {
if (EditorUtility.DisplayDialog("Controller Overwrite Warning", "Unknown Controller already exists at: " + controllerPath, "Update", "Overwrite")) {
controller = (UnityEditorInternal.AnimatorController)AssetDatabase.LoadAssetAtPath(controllerPath, typeof(RuntimeAnimatorController));
} else {
controller = (UnityEditorInternal.AnimatorController)UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
}
} else {
controller = (UnityEditorInternal.AnimatorController)UnityEditorInternal.AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
}
}
#endif
skeletonDataAsset.controller = controller;
EditorUtility.SetDirty(skeletonDataAsset);
Object[] objs = AssetDatabase.LoadAllAssetsAtPath(controllerPath);
Dictionary<string, AnimationClip> clipTable = new Dictionary<string, AnimationClip>();
Dictionary<string, Spine.Animation> animTable = new Dictionary<string, Spine.Animation>();
foreach (var o in objs) {
if (o is AnimationClip) {
clipTable.Add(o.name, (AnimationClip)o);
}
}
foreach (var anim in data.Animations) {
string name = anim.Name;
animTable.Add(name, anim);
if (clipTable.ContainsKey(name) == false) {
//generate new dummy clip
AnimationClip newClip = new AnimationClip();
newClip.name = name;
#if UNITY_5
#else
AnimationUtility.SetAnimationType(newClip, ModelImporterAnimationType.Generic);
#endif
AssetDatabase.AddObjectToAsset(newClip, controller);
clipTable.Add(name, newClip);
}
AnimationClip clip = clipTable[name];
clip.SetCurve("", typeof(GameObject), "dummy", AnimationCurve.Linear(0, 0, anim.Duration, 0));
var settings = AnimationUtility.GetAnimationClipSettings(clip);
settings.stopTime = anim.Duration;
SetAnimationSettings(clip, settings);
AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]);
foreach (Timeline t in anim.Timelines) {
if (t is EventTimeline) {
ParseEventTimeline((EventTimeline)t, clip, SendMessageOptions.DontRequireReceiver);
}
}
EditorUtility.SetDirty(clip);
clipTable.Remove(name);
}
//clear no longer used animations
foreach (var clip in clipTable.Values) {
AnimationClip.DestroyImmediate(clip, true);
}
AssetDatabase.Refresh();
AssetDatabase.SaveAssets();
}
static Bone extractionBone; static Bone extractionBone;
static Slot extractionSlot; static Slot extractionSlot;
@ -648,15 +773,19 @@ public static class SkeletonBaker {
} }
static void SetAnimationSettings (AnimationClip clip, AnimationClipSettings settings) { static void SetAnimationSettings (AnimationClip clip, AnimationClipSettings settings) {
#if UNITY_5
AnimationUtility.SetAnimationClipSettings(clip, settings);
#else
MethodInfo methodInfo = typeof(AnimationUtility).GetMethod("SetAnimationClipSettings", BindingFlags.Static | BindingFlags.NonPublic); MethodInfo methodInfo = typeof(AnimationUtility).GetMethod("SetAnimationClipSettings", BindingFlags.Static | BindingFlags.NonPublic);
methodInfo.Invoke(null, new object[] { clip, settings }); methodInfo.Invoke(null, new object[] { clip, settings });
EditorUtility.SetDirty(clip); EditorUtility.SetDirty(clip);
#endif
} }
static AnimationClip ExtractAnimation (string name, SkeletonData skeletonData, Dictionary<int, List<string>> slotLookup, bool bakeIK, SendMessageOptions eventOptions, AnimationClip clip = null) { static AnimationClip ExtractAnimation (string name, SkeletonData skeletonData, Dictionary<int, List<string>> slotLookup, bool bakeIK, SendMessageOptions eventOptions, AnimationClip clip = null) {
var animation = skeletonData.FindAnimation(name); var animation = skeletonData.FindAnimation(name);
var timelines = animation.Timelines; var timelines = animation.Timelines;
if (clip == null) { if (clip == null) {
@ -666,7 +795,11 @@ public static class SkeletonBaker {
AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]); AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]);
} }
#if UNITY_5
#else
AnimationUtility.SetAnimationType(clip, ModelImporterAnimationType.Generic); AnimationUtility.SetAnimationType(clip, ModelImporterAnimationType.Generic);
#endif
clip.name = name; clip.name = name;
@ -709,7 +842,7 @@ public static class SkeletonBaker {
} else if (t is AttachmentTimeline) { } else if (t is AttachmentTimeline) {
ParseAttachmentTimeline(skeleton, (AttachmentTimeline)t, slotLookup, clip); ParseAttachmentTimeline(skeleton, (AttachmentTimeline)t, slotLookup, clip);
} else if (t is EventTimeline) { } else if (t is EventTimeline) {
ParseEventTimeline(skeleton, (EventTimeline)t, clip, eventOptions); ParseEventTimeline((EventTimeline)t, clip, eventOptions);
} }
} }
@ -741,7 +874,7 @@ public static class SkeletonBaker {
} }
} }
static void ParseEventTimeline (Skeleton skeleton, EventTimeline timeline, AnimationClip clip, SendMessageOptions eventOptions) { static void ParseEventTimeline (EventTimeline timeline, AnimationClip clip, SendMessageOptions eventOptions) {
float[] frames = timeline.Frames; float[] frames = timeline.Frames;
var events = timeline.Events; var events = timeline.Events;
@ -755,9 +888,9 @@ public static class SkeletonBaker {
ae.functionName = ev.Data.Name; ae.functionName = ev.Data.Name;
ae.messageOptions = eventOptions; ae.messageOptions = eventOptions;
if (ev.String != "") if (ev.String != "" && ev.String != null) {
ae.stringParameter = ev.String; ae.stringParameter = ev.String;
else { } else {
if (ev.Int == 0 && ev.Float == 0) { if (ev.Int == 0 && ev.Float == 0) {
//do nothing, raw function //do nothing, raw function
} else { } else {
@ -1259,7 +1392,7 @@ public static class SkeletonBaker {
listIndex++; listIndex++;
} else if (curveType == 1) { } else if (curveType == 1) {
//stepped //stepped
Keyframe pk = keys[pIndex]; Keyframe pk = keys[pIndex];
float time = frames[f]; float time = frames[f];

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -53,15 +53,16 @@ public class SkeletonDataAssetInspector : Editor {
static bool bakeIK = true; static bool bakeIK = true;
static SendMessageOptions bakeEventOptions = SendMessageOptions.DontRequireReceiver; static SendMessageOptions bakeEventOptions = SendMessageOptions.DontRequireReceiver;
private SerializedProperty atlasAssets, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix; private SerializedProperty atlasAssets, skeletonJSON, scale, fromAnimation, toAnimation, duration, defaultMix, controller;
private bool m_initialized = false; private bool m_initialized = false;
private SkeletonDataAsset m_skeletonDataAsset; private SkeletonDataAsset m_skeletonDataAsset;
private SkeletonData m_skeletonData; private SkeletonData m_skeletonData;
private string m_skeletonDataAssetGUID; private string m_skeletonDataAssetGUID;
private bool needToSerialize;
List<string> warnings = new List<string>(); List<string> warnings = new List<string>();
void OnEnable () { void OnEnable () {
SpineEditorUtilities.ConfirmInitialization(); SpineEditorUtilities.ConfirmInitialization();
@ -74,6 +75,7 @@ public class SkeletonDataAssetInspector : Editor {
toAnimation = serializedObject.FindProperty("toAnimation"); toAnimation = serializedObject.FindProperty("toAnimation");
duration = serializedObject.FindProperty("duration"); duration = serializedObject.FindProperty("duration");
defaultMix = serializedObject.FindProperty("defaultMix"); defaultMix = serializedObject.FindProperty("defaultMix");
controller = serializedObject.FindProperty("controller");
m_skeletonDataAsset = (SkeletonDataAsset)target; m_skeletonDataAsset = (SkeletonDataAsset)target;
m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset)); m_skeletonDataAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_skeletonDataAsset));
@ -103,7 +105,6 @@ public class SkeletonDataAssetInspector : Editor {
override public void OnInspectorGUI () { override public void OnInspectorGUI () {
serializedObject.Update(); serializedObject.Update();
SkeletonDataAsset asset = (SkeletonDataAsset)target;
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(atlasAssets, true); EditorGUILayout.PropertyField(atlasAssets, true);
@ -126,10 +127,12 @@ public class SkeletonDataAssetInspector : Editor {
if (m_skeletonData != null) { if (m_skeletonData != null) {
DrawMecanim();
DrawAnimationStateInfo(); DrawAnimationStateInfo();
DrawAnimationList(); DrawAnimationList();
DrawSlotList(); DrawSlotList();
DrawBaking(); DrawBaking();
} else { } else {
DrawReimportButton(); DrawReimportButton();
@ -138,22 +141,24 @@ public class SkeletonDataAssetInspector : Editor {
EditorGUILayout.LabelField(new GUIContent(str, SpineEditorUtilities.Icons.warning)); EditorGUILayout.LabelField(new GUIContent(str, SpineEditorUtilities.Icons.warning));
} }
if (!Application.isPlaying) { if(!Application.isPlaying)
if (serializedObject.ApplyModifiedProperties() || serializedObject.ApplyModifiedProperties();
(UnityEngine.Event.current.type == EventType.ValidateCommand && UnityEngine.Event.current.commandName == "UndoRedoPerformed") }
) {
asset.Reset(); void DrawMecanim () {
} EditorGUILayout.PropertyField(controller, new GUIContent("Controller", SpineEditorUtilities.Icons.controllerIcon));
if (controller.objectReferenceValue == null) {
if (GUILayout.Button(new GUIContent("Generate Mecanim Controller", SpineEditorUtilities.Icons.controllerIcon), GUILayout.Width(195), GUILayout.Height(20)))
SkeletonBaker.GenerateMecanimAnimationClips(m_skeletonDataAsset);
} }
} }
void DrawBaking () { void DrawBaking () {
bool pre = showBaking; bool pre = showBaking;
showBaking = EditorGUILayout.Foldout(showBaking, new GUIContent("Baking", SpineEditorUtilities.Icons.unityIcon)); showBaking = EditorGUILayout.Foldout(showBaking, new GUIContent("Baking", SpineEditorUtilities.Icons.unityIcon));
if (pre != showBaking) if (pre != showBaking)
EditorPrefs.SetBool("SkeletonDataAssetInspector_showBaking", showBaking); EditorPrefs.SetBool("SkeletonDataAssetInspector_showBaking", showBaking);
if (showBaking) { if (showBaking) {
EditorGUI.indentLevel++; EditorGUI.indentLevel++;
bakeAnimations = EditorGUILayout.Toggle("Bake Animations", bakeAnimations); bakeAnimations = EditorGUILayout.Toggle("Bake Animations", bakeAnimations);
@ -170,20 +175,19 @@ public class SkeletonDataAssetInspector : Editor {
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
{ {
if (GUILayout.Button(new GUIContent("Bake All Skins", SpineEditorUtilities.Icons.unityIcon), GUILayout.Height(32), GUILayout.Width(150))) if (GUILayout.Button(new GUIContent("Bake All Skins", SpineEditorUtilities.Icons.unityIcon), GUILayout.Height(32), GUILayout.Width(150)))
SkeletonBaker.BakeToPrefab(m_skeletonDataAsset, m_skeletonData.Skins, "", bakeAnimations, bakeIK, bakeEventOptions); SkeletonBaker.BakeToPrefab(m_skeletonDataAsset, m_skeletonData.Skins, "", bakeAnimations, bakeIK, bakeEventOptions);
string skinName = "<No Skin>"; string skinName = "<No Skin>";
if (m_skeletonAnimation != null && m_skeletonAnimation.skeleton != null) { if (m_skeletonAnimation != null && m_skeletonAnimation.skeleton != null) {
Skin bakeSkin = m_skeletonAnimation.skeleton.Skin; Skin bakeSkin = m_skeletonAnimation.skeleton.Skin;
if (bakeSkin == null){ if (bakeSkin == null) {
skinName = "Default"; skinName = "Default";
bakeSkin = m_skeletonData.Skins[0]; bakeSkin = m_skeletonData.Skins[0];
} } else
else
skinName = m_skeletonAnimation.skeleton.Skin.Name; skinName = m_skeletonAnimation.skeleton.Skin.Name;
bool oops = false; bool oops = false;
@ -209,18 +213,17 @@ public class SkeletonDataAssetInspector : Editor {
if(!oops) if (!oops)
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
EditorGUI.indentLevel--; EditorGUI.indentLevel--;
EditorGUI.indentLevel--; EditorGUI.indentLevel--;
} }
} }
void DrawReimportButton () { void DrawReimportButton () {
EditorGUI.BeginDisabledGroup(skeletonJSON.objectReferenceValue == null); EditorGUI.BeginDisabledGroup(skeletonJSON.objectReferenceValue == null);
@ -250,6 +253,7 @@ public class SkeletonDataAssetInspector : Editor {
if (!showAnimationStateData) if (!showAnimationStateData)
return; return;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(defaultMix); EditorGUILayout.PropertyField(defaultMix);
// Animation names // Animation names
@ -282,6 +286,13 @@ public class SkeletonDataAssetInspector : Editor {
EditorGUILayout.Space(); EditorGUILayout.Space();
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
if (EditorGUI.EndChangeCheck()) {
m_skeletonDataAsset.FillStateData();
EditorUtility.SetDirty(m_skeletonDataAsset);
serializedObject.ApplyModifiedProperties();
needToSerialize = true;
}
} }
void DrawAnimationList () { void DrawAnimationList () {
showAnimationList = EditorGUILayout.Foldout(showAnimationList, new GUIContent("Animations", SpineEditorUtilities.Icons.animationRoot)); showAnimationList = EditorGUILayout.Foldout(showAnimationList, new GUIContent("Animations", SpineEditorUtilities.Icons.animationRoot));
@ -517,7 +528,7 @@ public class SkeletonDataAssetInspector : Editor {
if (this.m_previewUtility == null) { if (this.m_previewUtility == null) {
this.m_lastTime = Time.realtimeSinceStartup; this.m_lastTime = Time.realtimeSinceStartup;
this.m_previewUtility = new PreviewRenderUtility(true); this.m_previewUtility = new PreviewRenderUtility(true);
this.m_previewUtility.m_Camera.isOrthoGraphic = true; this.m_previewUtility.m_Camera.orthographic = true;
this.m_previewUtility.m_Camera.orthographicSize = 1; this.m_previewUtility.m_Camera.orthographicSize = 1;
this.m_previewUtility.m_Camera.cullingMask = -2147483648; this.m_previewUtility.m_Camera.cullingMask = -2147483648;
this.m_previewUtility.m_Camera.nearClipPlane = 0.01f; this.m_previewUtility.m_Camera.nearClipPlane = 0.01f;
@ -532,7 +543,7 @@ public class SkeletonDataAssetInspector : Editor {
try { try {
string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", ""); string skinName = EditorPrefs.GetString(m_skeletonDataAssetGUID + "_lastSkin", "");
m_previewInstance = SpineEditorUtilities.SpawnAnimatedSkeleton((SkeletonDataAsset)target, skinName).gameObject; m_previewInstance = SpineEditorUtilities.InstantiateSkeletonAnimation((SkeletonDataAsset)target, skinName).gameObject;
m_previewInstance.hideFlags = HideFlags.HideAndDontSave; m_previewInstance.hideFlags = HideFlags.HideAndDontSave;
m_previewInstance.layer = 0x1f; m_previewInstance.layer = 0x1f;
@ -543,7 +554,7 @@ public class SkeletonDataAssetInspector : Editor {
m_skeletonData = m_skeletonAnimation.skeletonDataAsset.GetSkeletonData(true); m_skeletonData = m_skeletonAnimation.skeletonDataAsset.GetSkeletonData(true);
m_previewInstance.renderer.enabled = false; m_previewInstance.GetComponent<Renderer>().enabled = false;
m_initialized = true; m_initialized = true;
AdjustCameraGoals(true); AdjustCameraGoals(true);
@ -613,7 +624,7 @@ public class SkeletonDataAssetInspector : Editor {
GameObject go = this.m_previewInstance; GameObject go = this.m_previewInstance;
Bounds bounds = go.renderer.bounds; Bounds bounds = go.GetComponent<Renderer>().bounds;
m_orthoGoal = bounds.size.y; m_orthoGoal = bounds.size.y;
m_posGoal = bounds.center + new Vector3(0, 0, -10); m_posGoal = bounds.center + new Vector3(0, 0, -10);
@ -650,7 +661,7 @@ public class SkeletonDataAssetInspector : Editor {
GameObject go = this.m_previewInstance; GameObject go = this.m_previewInstance;
if (m_requireRefresh && go != null) { if (m_requireRefresh && go != null) {
go.renderer.enabled = true; go.GetComponent<Renderer>().enabled = true;
if (EditorApplication.isPlaying) { if (EditorApplication.isPlaying) {
//do nothing //do nothing
@ -672,7 +683,7 @@ public class SkeletonDataAssetInspector : Editor {
} }
this.m_previewUtility.m_Camera.Render(); this.m_previewUtility.m_Camera.Render();
go.renderer.enabled = false; go.GetComponent<Renderer>().enabled = false;
} }
@ -689,6 +700,11 @@ public class SkeletonDataAssetInspector : Editor {
} else { } else {
//only needed if using smooth menus //only needed if using smooth menus
} }
if (needToSerialize) {
needToSerialize = false;
serializedObject.ApplyModifiedProperties();
}
} }
void DrawSkinToolbar (Rect r) { void DrawSkinToolbar (Rect r) {

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -43,8 +43,6 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using Spine; using Spine;
using System.Security.Cryptography;
[InitializeOnLoad] [InitializeOnLoad]
public class SpineEditorUtilities : AssetPostprocessor { public class SpineEditorUtilities : AssetPostprocessor {
@ -73,6 +71,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
public static Texture2D hingeChain; public static Texture2D hingeChain;
public static Texture2D subMeshRenderer; public static Texture2D subMeshRenderer;
public static Texture2D unityIcon; public static Texture2D unityIcon;
public static Texture2D controllerIcon;
public static Mesh boneMesh { public static Mesh boneMesh {
get { get {
@ -115,7 +114,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
internal static Material _boneMaterial; internal static Material _boneMaterial;
public static void Initialize() { public static void Initialize () {
skeleton = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skeleton.png"); skeleton = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-skeleton.png");
nullBone = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-null.png"); nullBone = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-null.png");
bone = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-bone.png"); bone = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-bone.png");
@ -141,6 +140,8 @@ public class SpineEditorUtilities : AssetPostprocessor {
subMeshRenderer = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-subMeshRenderer.png"); subMeshRenderer = (Texture2D)AssetDatabase.LoadMainAssetAtPath(SpineEditorUtilities.editorGUIPath + "/icon-subMeshRenderer.png");
unityIcon = EditorGUIUtility.FindTexture("SceneAsset Icon"); unityIcon = EditorGUIUtility.FindTexture("SceneAsset Icon");
controllerIcon = EditorGUIUtility.FindTexture("AnimatorController Icon");
} }
} }
@ -153,11 +154,11 @@ public class SpineEditorUtilities : AssetPostprocessor {
public static string defaultShader = "Spine/Skeleton"; public static string defaultShader = "Spine/Skeleton";
public static bool initialized; public static bool initialized;
static SpineEditorUtilities() { static SpineEditorUtilities () {
Initialize(); Initialize();
} }
static void Initialize(){ static void Initialize () {
DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath); DirectoryInfo rootDir = new DirectoryInfo(Application.dataPath);
FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories); FileInfo[] files = rootDir.GetFiles("SpineEditorUtilities.cs", SearchOption.AllDirectories);
editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets")); editorPath = Path.GetDirectoryName(files[0].FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets"));
@ -174,13 +175,13 @@ public class SpineEditorUtilities : AssetPostprocessor {
HierarchyWindowChanged(); HierarchyWindowChanged();
initialized = true; initialized = true;
} }
public static void ConfirmInitialization(){ public static void ConfirmInitialization () {
if(!initialized || Icons.skeleton == null) if (!initialized || Icons.skeleton == null)
Initialize(); Initialize();
} }
static void HierarchyWindowChanged() { static void HierarchyWindowChanged () {
skeletonRendererTable.Clear(); skeletonRendererTable.Clear();
skeletonUtilityBoneTable.Clear(); skeletonUtilityBoneTable.Clear();
@ -194,7 +195,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b); skeletonUtilityBoneTable.Add(b.gameObject.GetInstanceID(), b);
} }
static void HierarchyWindowItemOnGUI(int instanceId, Rect selectionRect) { static void HierarchyWindowItemOnGUI (int instanceId, Rect selectionRect) {
if (skeletonRendererTable.ContainsKey(instanceId)) { if (skeletonRendererTable.ContainsKey(instanceId)) {
Rect r = new Rect(selectionRect); Rect r = new Rect(selectionRect);
r.x = r.width - 15; r.x = r.width - 15;
@ -225,13 +226,10 @@ public class SpineEditorUtilities : AssetPostprocessor {
} }
static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) { static void OnPostprocessAllAssets (string[] imported, string[] deleted, string[] moved, string[] movedFromAssetPaths) {
ImportSpineContent(imported, false); ImportSpineContent(imported, false);
} }
public static void ImportSpineContent(string[] imported, bool reimport = false) { public static void ImportSpineContent (string[] imported, bool reimport = false) {
MD5 md5 = MD5.Create();
List<string> atlasPaths = new List<string>(); List<string> atlasPaths = new List<string>();
List<string> imagePaths = new List<string>(); List<string> imagePaths = new List<string>();
List<string> skeletonPaths = new List<string>(); List<string> skeletonPaths = new List<string>();
@ -277,7 +275,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
ResetExistingSkeletonData(sp); ResetExistingSkeletonData(sp);
continue; continue;
} }
string dir = Path.GetDirectoryName(sp); string dir = Path.GetDirectoryName(sp);
@ -319,7 +317,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
Debug.Log("Skipped importing: " + Path.GetFileName(sp)); Debug.Log("Skipped importing: " + Path.GetFileName(sp));
resolved = true; resolved = true;
break; break;
case 2: case 2:
//abort //abort
@ -337,7 +335,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
//TODO: any post processing of images //TODO: any post processing of images
} }
static bool CheckForValidSkeletonData(string skeletonJSONPath) { static bool CheckForValidSkeletonData (string skeletonJSONPath) {
string dir = Path.GetDirectoryName(skeletonJSONPath); string dir = Path.GetDirectoryName(skeletonJSONPath);
TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset)); TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset));
@ -377,14 +375,30 @@ public class SpineEditorUtilities : AssetPostprocessor {
Selection.activeObject = null; Selection.activeObject = null;
skeletonDataAsset.Reset(); skeletonDataAsset.Reset();
}
string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skeletonDataAsset));
string lastHash = EditorPrefs.GetString(guid + "_hash");
if (lastHash != skeletonDataAsset.GetSkeletonData(true).Hash) {
//do any upkeep on synchronized assets
UpdateMecanimClips(skeletonDataAsset);
}
EditorPrefs.SetString(guid + "_hash", skeletonDataAsset.GetSkeletonData(true).Hash);
}
} }
} }
} }
static void UpdateMecanimClips (SkeletonDataAsset skeletonDataAsset) {
if (skeletonDataAsset.controller == null)
return;
static bool CheckForValidAtlas(string atlasPath) { SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset);
}
static bool CheckForValidAtlas (string atlasPath) {
string dir = Path.GetDirectoryName(atlasPath); string dir = Path.GetDirectoryName(atlasPath);
TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(TextAsset)); TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(TextAsset));
@ -405,7 +419,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
return false; return false;
} }
static List<AtlasAsset> MultiAtlasDialog(List<string> requiredPaths, string initialDirectory, string header = "") { static List<AtlasAsset> MultiAtlasDialog (List<string> requiredPaths, string initialDirectory, string header = "") {
List<AtlasAsset> atlasAssets = new List<AtlasAsset>(); List<AtlasAsset> atlasAssets = new List<AtlasAsset>();
@ -422,7 +436,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
sb.AppendLine("\t" + atlasAssets[i].name); sb.AppendLine("\t" + atlasAssets[i].name);
} }
sb.AppendLine(); sb.AppendLine();
sb.AppendLine("Missing Regions:"); sb.AppendLine("Missing Regions:");
List<string> missingRegions = new List<string>(requiredPaths); List<string> missingRegions = new List<string>(requiredPaths);
@ -447,7 +461,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
int result = EditorUtility.DisplayDialogComplex("Atlas Selection", sb.ToString(), "Select", "Finish", "Abort"); int result = EditorUtility.DisplayDialogComplex("Atlas Selection", sb.ToString(), "Select", "Finish", "Abort");
switch(result){ switch (result) {
case 0: case 0:
AtlasAsset selectedAtlasAsset = GetAtlasDialog(lastAtlasPath); AtlasAsset selectedAtlasAsset = GetAtlasDialog(lastAtlasPath);
if (selectedAtlasAsset != null) { if (selectedAtlasAsset != null) {
@ -476,12 +490,12 @@ public class SpineEditorUtilities : AssetPostprocessor {
} }
return atlasAssets; return atlasAssets;
} }
static AtlasAsset GetAtlasDialog(string dirPath) { static AtlasAsset GetAtlasDialog (string dirPath) {
string path = EditorUtility.OpenFilePanel("Select AtlasAsset...", dirPath, "asset"); string path = EditorUtility.OpenFilePanel("Select AtlasAsset...", dirPath, "asset");
if (path == "") if (path == "")
return null; return null;
@ -497,7 +511,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
return (AtlasAsset)obj; return (AtlasAsset)obj;
} }
public static List<string> GetRequiredAtlasRegions(string jsonPath) { public static List<string> GetRequiredAtlasRegions (string jsonPath) {
List<string> requiredPaths = new List<string>(); List<string> requiredPaths = new List<string>();
TextAsset spineJson = (TextAsset)AssetDatabase.LoadAssetAtPath(jsonPath, typeof(TextAsset)); TextAsset spineJson = (TextAsset)AssetDatabase.LoadAssetAtPath(jsonPath, typeof(TextAsset));
@ -523,7 +537,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
return requiredPaths; return requiredPaths;
} }
static AtlasAsset GetMatchingAtlas(List<string> requiredPaths, List<AtlasAsset> atlasAssets) { static AtlasAsset GetMatchingAtlas (List<string> requiredPaths, List<AtlasAsset> atlasAssets) {
AtlasAsset atlasAssetMatch = null; AtlasAsset atlasAssetMatch = null;
foreach (AtlasAsset a in atlasAssets) { foreach (AtlasAsset a in atlasAssets) {
@ -546,7 +560,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
return atlasAssetMatch; return atlasAssetMatch;
} }
static List<AtlasAsset> FindAtlasesAtPath(string path) { static List<AtlasAsset> FindAtlasesAtPath (string path) {
List<AtlasAsset> arr = new List<AtlasAsset>(); List<AtlasAsset> arr = new List<AtlasAsset>();
DirectoryInfo dir = new DirectoryInfo(path); DirectoryInfo dir = new DirectoryInfo(path);
@ -568,7 +582,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
return arr; return arr;
} }
public static bool IsSpineJSON(TextAsset asset) { public static bool IsSpineJSON (TextAsset asset) {
object obj = Json.Deserialize(new StringReader(asset.text)); object obj = Json.Deserialize(new StringReader(asset.text));
if (obj == null) { if (obj == null) {
Debug.LogError("Is not valid JSON"); Debug.LogError("Is not valid JSON");
@ -588,7 +602,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
return true; return true;
} }
static AtlasAsset IngestSpineAtlas(TextAsset atlasText) { static AtlasAsset IngestSpineAtlas (TextAsset atlasText) {
if (atlasText == null) { if (atlasText == null) {
Debug.LogWarning("Atlas source cannot be null!"); Debug.LogWarning("Atlas source cannot be null!");
return null; return null;
@ -666,7 +680,7 @@ public class SpineEditorUtilities : AssetPostprocessor {
return (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset)); return (AtlasAsset)AssetDatabase.LoadAssetAtPath(atlasPath, typeof(AtlasAsset));
} }
static SkeletonDataAsset IngestSpineProject(TextAsset spineJson, params AtlasAsset[] atlasAssets) { static SkeletonDataAsset IngestSpineProject (TextAsset spineJson, params AtlasAsset[] atlasAssets) {
string primaryName = Path.GetFileNameWithoutExtension(spineJson.name); string primaryName = Path.GetFileNameWithoutExtension(spineJson.name);
string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson)); string assetPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(spineJson));
string filePath = assetPath + "/" + primaryName + "_SkeletonData.asset"; string filePath = assetPath + "/" + primaryName + "_SkeletonData.asset";
@ -699,20 +713,20 @@ public class SpineEditorUtilities : AssetPostprocessor {
} }
} }
[MenuItem("Assets/Spine/Spawn")] [MenuItem("Assets/Spine/Instantiate (SkeletonAnimation)")]
static void SpawnAnimatedSkeleton() { static void InstantiateSkeletonAnimation () {
Object[] arr = Selection.objects; Object[] arr = Selection.objects;
foreach (Object o in arr) { foreach (Object o in arr) {
string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o)); string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o));
string skinName = EditorPrefs.GetString(guid + "_lastSkin", ""); string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
SpawnAnimatedSkeleton((SkeletonDataAsset)o, skinName); InstantiateSkeletonAnimation((SkeletonDataAsset)o, skinName);
SceneView.RepaintAll(); SceneView.RepaintAll();
} }
} }
[MenuItem("Assets/Spine/Spawn", true)] [MenuItem("Assets/Spine/Instantiate (SkeletonAnimation)", true)]
static bool ValidateSpawnAnimatedSkeleton() { static bool ValidateInstantiateSkeletonAnimation () {
Object[] arr = Selection.objects; Object[] arr = Selection.objects;
if (arr.Length == 0) if (arr.Length == 0)
@ -726,11 +740,11 @@ public class SpineEditorUtilities : AssetPostprocessor {
return true; return true;
} }
public static SkeletonAnimation SpawnAnimatedSkeleton(SkeletonDataAsset skeletonDataAsset, string skinName) { public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, string skinName) {
return SpawnAnimatedSkeleton(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName)); return InstantiateSkeletonAnimation(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
} }
public static SkeletonAnimation SpawnAnimatedSkeleton(SkeletonDataAsset skeletonDataAsset, Skin skin = null) { public static SkeletonAnimation InstantiateSkeletonAnimation (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
GameObject go = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation)); GameObject go = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(SkeletonAnimation));
SkeletonAnimation anim = go.GetComponent<SkeletonAnimation>(); SkeletonAnimation anim = go.GetComponent<SkeletonAnimation>();
anim.skeletonDataAsset = skeletonDataAsset; anim.skeletonDataAsset = skeletonDataAsset;
@ -746,18 +760,18 @@ public class SpineEditorUtilities : AssetPostprocessor {
} }
} }
anim.calculateNormals = requiresNormals; anim.calculateNormals = requiresNormals;
SkeletonData data = skeletonDataAsset.GetSkeletonData(true); SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
if (data == null) { if (data == null) {
for(int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++){ for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]); string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset)); skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
} }
data = skeletonDataAsset.GetSkeletonData(true); data = skeletonDataAsset.GetSkeletonData(true);
} }
@ -779,4 +793,89 @@ public class SpineEditorUtilities : AssetPostprocessor {
return anim; return anim;
} }
[MenuItem("Assets/Spine/Instantiate (Mecanim)")]
static void InstantiateSkeletonAnimator () {
Object[] arr = Selection.objects;
foreach (Object o in arr) {
string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(o));
string skinName = EditorPrefs.GetString(guid + "_lastSkin", "");
InstantiateSkeletonAnimator((SkeletonDataAsset)o, skinName);
SceneView.RepaintAll();
}
}
[MenuItem("Assets/Spine/Instantiate (SkeletonAnimation)", true)]
static bool ValidateInstantiateSkeletonAnimator () {
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 SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, string skinName) {
return InstantiateSkeletonAnimator(skeletonDataAsset, skeletonDataAsset.GetSkeletonData(true).FindSkin(skinName));
}
public static SkeletonAnimator InstantiateSkeletonAnimator (SkeletonDataAsset skeletonDataAsset, Skin skin = null) {
GameObject go = new GameObject(skeletonDataAsset.name.Replace("_SkeletonData", ""), typeof(MeshFilter), typeof(MeshRenderer), typeof(Animator), typeof(SkeletonAnimator));
if(skeletonDataAsset.controller == null){
SkeletonBaker.GenerateMecanimAnimationClips(skeletonDataAsset);
}
go.GetComponent<Animator>().runtimeAnimatorController = skeletonDataAsset.controller;
SkeletonAnimator anim = go.GetComponent<SkeletonAnimator>();
anim.skeletonDataAsset = skeletonDataAsset;
bool requiresNormals = false;
foreach (AtlasAsset atlasAsset in anim.skeletonDataAsset.atlasAssets) {
foreach (Material m in atlasAsset.materials) {
if (m.shader.name.Contains("Lit")) {
requiresNormals = true;
break;
}
}
}
anim.calculateNormals = requiresNormals;
SkeletonData data = skeletonDataAsset.GetSkeletonData(true);
if (data == null) {
for (int i = 0; i < skeletonDataAsset.atlasAssets.Length; i++) {
string reloadAtlasPath = AssetDatabase.GetAssetPath(skeletonDataAsset.atlasAssets[i]);
skeletonDataAsset.atlasAssets[i] = (AtlasAsset)AssetDatabase.LoadAssetAtPath(reloadAtlasPath, typeof(AtlasAsset));
}
data = skeletonDataAsset.GetSkeletonData(true);
}
if (skin == null)
skin = data.DefaultSkin;
if (skin == null)
skin = data.Skins[0];
anim.Reset();
anim.skeleton.SetSkin(skin);
anim.initialSkinName = skin.Name;
anim.skeleton.Update(1);
anim.skeleton.UpdateWorldTransform();
anim.LateUpdate();
return anim;
}
} }

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -3,3 +3,5 @@ guid: 66988de88a15abd4e8846c6805485f57
ShaderImporter: ShaderImporter:
defaultTextures: [] defaultTextures: []
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -2,3 +2,5 @@ fileFormatVersion: 2
guid: 43227e5adadc6f24bb4bf74b92a56fb4 guid: 43227e5adadc6f24bb4bf74b92a56fb4
NativeFormatImporter: NativeFormatImporter:
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -3,3 +3,5 @@ guid: 913475501bf19374c84390868a9d6d3d
ShaderImporter: ShaderImporter:
defaultTextures: [] defaultTextures: []
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -3,3 +3,5 @@ guid: 1e8a610c9e01c3648bac42585e5fc676
ShaderImporter: ShaderImporter:
defaultTextures: [] defaultTextures: []
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -3,3 +3,5 @@ guid: bd83c75f51f5e23498ae22ffcdfe92c3
ShaderImporter: ShaderImporter:
defaultTextures: [] defaultTextures: []
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -36,16 +36,32 @@ using Spine;
[ExecuteInEditMode] [ExecuteInEditMode]
[AddComponentMenu("Spine/SkeletonAnimation")] [AddComponentMenu("Spine/SkeletonAnimation")]
public class SkeletonAnimation : SkeletonRenderer { public class SkeletonAnimation : SkeletonRenderer, ISkeletonAnimation {
public float timeScale = 1; public float timeScale = 1;
public bool loop; public bool loop;
public Spine.AnimationState state; public Spine.AnimationState state;
public delegate void UpdateBonesDelegate (SkeletonAnimation skeleton);
public UpdateBonesDelegate UpdateLocal;
public UpdateBonesDelegate UpdateWorld; public event UpdateBonesDelegate UpdateLocal {
public UpdateBonesDelegate UpdateComplete; add { _UpdateLocal += value; }
remove { _UpdateLocal -= value; }
}
public event UpdateBonesDelegate UpdateWorld {
add { _UpdateWorld += value; }
remove { _UpdateWorld -= value; }
}
public event UpdateBonesDelegate UpdateComplete {
add { _UpdateComplete += value; }
remove { _UpdateComplete -= value; }
}
protected event UpdateBonesDelegate _UpdateLocal;
protected event UpdateBonesDelegate _UpdateWorld;
protected event UpdateBonesDelegate _UpdateComplete;
[SerializeField] [SerializeField]
private String private String
_animationName; _animationName;
@ -91,18 +107,18 @@ public class SkeletonAnimation : SkeletonRenderer {
state.Update(deltaTime); state.Update(deltaTime);
state.Apply(skeleton); state.Apply(skeleton);
if (UpdateLocal != null) if (_UpdateLocal != null)
UpdateLocal(this); _UpdateLocal(this);
skeleton.UpdateWorldTransform(); skeleton.UpdateWorldTransform();
if (UpdateWorld != null) { if (_UpdateWorld != null) {
UpdateWorld(this); _UpdateWorld(this);
skeleton.UpdateWorldTransform(); skeleton.UpdateWorldTransform();
} }
if (UpdateComplete != null) { if (_UpdateComplete != null) {
UpdateComplete(this); _UpdateComplete(this);
} }
} }
} }

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
public delegate void UpdateBonesDelegate (SkeletonRenderer skeletonRenderer);
public interface ISkeletonAnimation {
event UpdateBonesDelegate UpdateLocal;
event UpdateBonesDelegate UpdateWorld;
event UpdateBonesDelegate UpdateComplete;
void LateUpdate ();
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a7b480b941568134891f411137bfbf55
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,205 @@
/******************************************************************************
* Spine Runtimes Software License
* Version 2.1
*
* Copyright (c) 2013, Esoteric Software
* All rights reserved.
*
* You are granted a perpetual, non-exclusive, non-sublicensable and
* non-transferable license to install, execute and perform the Spine Runtimes
* Software (the "Software") solely for internal use. Without the written
* permission of Esoteric Software (typically granted by licensing Spine), you
* may not (a) modify, translate, adapt or otherwise create derivative works,
* improvements of the Software or develop new applications using the Software
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
* trademark, patent or other intellectual property or proprietary rights
* notices on or in the Software, including any copy thereof. Redistributions
* in binary or source form must include this license and terms.
*
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
/*****************************************************************************
* SkeletonAnimator created by Mitch Thompson
* Full irrevocable rights and permissions granted to Esoteric Software
*****************************************************************************/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Spine;
[RequireComponent(typeof(Animator))]
public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
public enum MixMode { AlwaysMix, MixNext, SpineStyle }
public MixMode[] layerMixModes = new MixMode[0];
public event UpdateBonesDelegate UpdateLocal {
add { _UpdateLocal += value; }
remove { _UpdateLocal -= value; }
}
public event UpdateBonesDelegate UpdateWorld {
add { _UpdateWorld += value; }
remove { _UpdateWorld -= value; }
}
public event UpdateBonesDelegate UpdateComplete {
add { _UpdateComplete += value; }
remove { _UpdateComplete -= value; }
}
protected event UpdateBonesDelegate _UpdateLocal;
protected event UpdateBonesDelegate _UpdateWorld;
protected event UpdateBonesDelegate _UpdateComplete;
Dictionary<string, Spine.Animation> animationTable = new Dictionary<string, Spine.Animation>();
Animator animator;
public override void Reset () {
base.Reset();
if (!valid)
return;
animationTable.Clear();
var data = skeletonDataAsset.GetSkeletonData(true);
foreach (var a in data.Animations) {
animationTable.Add(a.Name, a);
}
animator = GetComponent<Animator>();
}
void Update () {
if (!valid)
return;
if (layerMixModes.Length != animator.layerCount) {
System.Array.Resize<MixMode>(ref layerMixModes, animator.layerCount);
}
skeleton.Update(Time.deltaTime);
//apply
int layerCount = animator.layerCount;
float deltaTime = Time.deltaTime;
for (int i = 0; i < layerCount; i++) {
float layerWeight = animator.GetLayerWeight(i);
if (i == 0)
layerWeight = 1;
var stateInfo = animator.GetCurrentAnimatorStateInfo(i);
var nextStateInfo = animator.GetNextAnimatorStateInfo(i);
#if UNITY_5
var clipInfo = animator.GetCurrentAnimatorClipInfo(i);
var nextClipInfo = animator.GetNextAnimatorClipInfo(i);
#else
var clipInfo = animator.GetCurrentAnimationClipState(i);
var nextClipInfo = animator.GetNextAnimationClipState(i);
#endif
MixMode mode = layerMixModes[i];
if (mode == MixMode.AlwaysMix) {
//always use Mix instead of Applying the first non-zero weighted clip
foreach (var info in clipInfo) {
float weight = info.weight * layerWeight;
if (weight == 0)
continue;
float time = stateInfo.normalizedTime * info.clip.length;
animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight);
}
foreach (var info in nextClipInfo) {
float weight = info.weight * layerWeight;
if (weight == 0)
continue;
float time = nextStateInfo.normalizedTime * info.clip.length;
animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight);
}
} else if (mode >= MixMode.MixNext) {
//apply first non-zero weighted clip
int c = 0;
for (; c < clipInfo.Length; c++) {
var info = clipInfo[c];
float weight = info.weight * layerWeight;
if (weight == 0)
continue;
float time = stateInfo.normalizedTime * info.clip.length;
animationTable[info.clip.name].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null);
break;
}
//mix the rest
for (; c < clipInfo.Length; c++) {
var info = clipInfo[c];
float weight = info.weight * layerWeight;
if (weight == 0)
continue;
float time = stateInfo.normalizedTime * info.clip.length;
animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, stateInfo.loop, null, weight);
}
c = 0;
//apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights)
if (mode == MixMode.SpineStyle) {
for (; c < nextClipInfo.Length; c++) {
var info = nextClipInfo[c];
float weight = info.weight * layerWeight;
if (weight == 0)
continue;
float time = nextStateInfo.normalizedTime * info.clip.length;
animationTable[info.clip.name].Apply(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null);
break;
}
}
//mix the rest
for (; c < nextClipInfo.Length; c++) {
var info = nextClipInfo[c];
float weight = info.weight * layerWeight;
if (weight == 0)
continue;
float time = nextStateInfo.normalizedTime * info.clip.length;
animationTable[info.clip.name].Mix(skeleton, Mathf.Max(0, time - deltaTime), time, nextStateInfo.loop, null, weight);
}
}
}
if (_UpdateLocal != null)
_UpdateLocal(this);
skeleton.UpdateWorldTransform();
if (_UpdateWorld != null) {
_UpdateWorld(this);
skeleton.UpdateWorldTransform();
}
if (_UpdateComplete != null) {
_UpdateComplete(this);
}
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: f9db98c60740638449864eb028fbe7ad
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -42,6 +42,7 @@ public class SkeletonDataAsset : ScriptableObject {
public String[] toAnimation; public String[] toAnimation;
public float[] duration; public float[] duration;
public float defaultMix; public float defaultMix;
public RuntimeAnimatorController controller;
private SkeletonData skeletonData; private SkeletonData skeletonData;
private AnimationStateData stateData; private AnimationStateData stateData;
@ -86,9 +87,6 @@ public class SkeletonDataAsset : ScriptableObject {
} }
} }
if (skeletonData != null) if (skeletonData != null)
return skeletonData; return skeletonData;
@ -103,14 +101,21 @@ public class SkeletonDataAsset : ScriptableObject {
} }
stateData = new AnimationStateData(skeletonData); stateData = new AnimationStateData(skeletonData);
FillStateData();
return skeletonData;
}
public void FillStateData () {
if (stateData == null)
return;
stateData.DefaultMix = defaultMix; stateData.DefaultMix = defaultMix;
for (int i = 0, n = fromAnimation.Length; i < n; i++) { for (int i = 0, n = fromAnimation.Length; i < n; i++) {
if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0) if (fromAnimation[i].Length == 0 || toAnimation[i].Length == 0)
continue; continue;
stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]); stateData.SetMix(fromAnimation[i], toAnimation[i], duration[i]);
} }
return skeletonData;
} }
public AnimationStateData GetAnimationStateData() { public AnimationStateData GetAnimationStateData() {

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -76,8 +76,8 @@ public class SkeletonRenderer : MonoBehaviour {
public virtual void Reset () { public virtual void Reset () {
if (meshFilter != null) if (meshFilter != null)
meshFilter.sharedMesh = null; meshFilter.sharedMesh = null;
if (renderer != null) if (GetComponent<Renderer>() != null)
renderer.sharedMaterial = null; GetComponent<Renderer>().sharedMaterial = null;
if (mesh1 != null) { if (mesh1 != null) {
if (Application.isPlaying) if (Application.isPlaying)
@ -225,7 +225,7 @@ public class SkeletonRenderer : MonoBehaviour {
submeshMaterials.CopyTo(sharedMaterials); submeshMaterials.CopyTo(sharedMaterials);
else else
sharedMaterials = submeshMaterials.ToArray(); sharedMaterials = submeshMaterials.ToArray();
renderer.sharedMaterials = sharedMaterials; GetComponent<Renderer>().sharedMaterials = sharedMaterials;
// Ensure mesh data is the right size. // Ensure mesh data is the right size.
Vector3[] vertices = this.vertices; Vector3[] vertices = this.vertices;

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -246,7 +246,7 @@ public class SkeletonUtilityBoneInspector : Editor {
bool CanCreateHingeChain () { bool CanCreateHingeChain () {
if (utilityBone == null) if (utilityBone == null)
return false; return false;
if (utilityBone.rigidbody != null) if (utilityBone.GetComponent<Rigidbody>() != null)
return false; return false;
if (utilityBone.bone != null && utilityBone.bone.Children.Count == 0) if (utilityBone.bone != null && utilityBone.bone.Children.Count == 0)
return false; return false;
@ -266,7 +266,7 @@ public class SkeletonUtilityBoneInspector : Editor {
AttachRigidbody(utilBone); AttachRigidbody(utilBone);
} }
utilityBone.rigidbody.isKinematic = true; utilityBone.GetComponent<Rigidbody>().isKinematic = true;
foreach (var utilBone in utilBoneArr) { foreach (var utilBone in utilBoneArr) {
if (utilBone == utilityBone) if (utilBone == utilityBone)
@ -276,13 +276,13 @@ public class SkeletonUtilityBoneInspector : Editor {
HingeJoint joint = utilBone.gameObject.AddComponent<HingeJoint>(); HingeJoint joint = utilBone.gameObject.AddComponent<HingeJoint>();
joint.axis = Vector3.forward; joint.axis = Vector3.forward;
joint.connectedBody = utilBone.transform.parent.rigidbody; joint.connectedBody = utilBone.transform.parent.GetComponent<Rigidbody>();
joint.useLimits = true; joint.useLimits = true;
JointLimits limits = new JointLimits(); JointLimits limits = new JointLimits();
limits.min = -20; limits.min = -20;
limits.max = 20; limits.max = 20;
joint.limits = limits; joint.limits = limits;
utilBone.rigidbody.mass = utilBone.transform.parent.rigidbody.mass * 0.75f; utilBone.GetComponent<Rigidbody>().mass = utilBone.transform.parent.GetComponent<Rigidbody>().mass * 0.75f;
} }
} }

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -38,7 +38,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Spine; using Spine;
[RequireComponent(typeof(SkeletonAnimation))] [RequireComponent(typeof(ISkeletonAnimation))]
[ExecuteInEditMode] [ExecuteInEditMode]
public class SkeletonUtility : MonoBehaviour { public class SkeletonUtility : MonoBehaviour {
@ -80,7 +80,7 @@ public class SkeletonUtility : MonoBehaviour {
[HideInInspector] [HideInInspector]
public SkeletonRenderer skeletonRenderer; public SkeletonRenderer skeletonRenderer;
[HideInInspector] [HideInInspector]
public SkeletonAnimation skeletonAnimation; public ISkeletonAnimation skeletonAnimation;
[System.NonSerialized] [System.NonSerialized]
public List<SkeletonUtilityBone> utilityBones = new List<SkeletonUtilityBone>(); public List<SkeletonUtilityBone> utilityBones = new List<SkeletonUtilityBone>();
[System.NonSerialized] [System.NonSerialized]
@ -98,6 +98,8 @@ public class SkeletonUtility : MonoBehaviour {
if (skeletonAnimation == null) { if (skeletonAnimation == null) {
skeletonAnimation = GetComponent<SkeletonAnimation>(); skeletonAnimation = GetComponent<SkeletonAnimation>();
if (skeletonAnimation == null)
skeletonAnimation = GetComponent<SkeletonAnimator>();
} }
skeletonRenderer.OnReset -= HandleRendererReset; skeletonRenderer.OnReset -= HandleRendererReset;
@ -209,7 +211,7 @@ public class SkeletonUtility : MonoBehaviour {
} }
void UpdateLocal (SkeletonAnimation anim) { void UpdateLocal (SkeletonRenderer anim) {
if (needToReprocessBones) if (needToReprocessBones)
CollectBones(); CollectBones();
@ -224,14 +226,14 @@ public class SkeletonUtility : MonoBehaviour {
UpdateAllBones(); UpdateAllBones();
} }
void UpdateWorld (SkeletonAnimation anim) { void UpdateWorld (SkeletonRenderer anim) {
UpdateAllBones(); UpdateAllBones();
foreach (SkeletonUtilityConstraint c in utilityConstraints) foreach (SkeletonUtilityConstraint c in utilityConstraints)
c.DoUpdate(); c.DoUpdate();
} }
void UpdateComplete (SkeletonAnimation anim) { void UpdateComplete (SkeletonRenderer anim) {
UpdateAllBones(); UpdateAllBones();
} }
@ -336,11 +338,11 @@ public class SkeletonUtility : MonoBehaviour {
SkeletonUtilitySubmeshRenderer s = go.AddComponent<SkeletonUtilitySubmeshRenderer>(); SkeletonUtilitySubmeshRenderer s = go.AddComponent<SkeletonUtilitySubmeshRenderer>();
s.sortingOrder = i * 10; s.sortingOrder = i * 10;
s.submeshIndex = i; s.submeshIndex = i;
s.Initialize(renderer); s.Initialize(GetComponent<Renderer>());
s.Update(); s.Update();
} }
if (disablePrimaryRenderer) if (disablePrimaryRenderer)
renderer.enabled = false; GetComponent<Renderer>().enabled = false;
} }
} }

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -172,7 +172,7 @@ public class SkeletonUtilityBone : MonoBehaviour {
} }
if (scale) { if (scale) {
cachedTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, 1); cachedTransform.localScale = new Vector3(bone.scaleX, bone.scaleY, bone.worldFlipX ? -1 : 1);
nonUniformScaleWarning = (bone.scaleX != bone.scaleY); nonUniformScaleWarning = (bone.scaleX != bone.scaleY);
} }
@ -206,6 +206,7 @@ public class SkeletonUtilityBone : MonoBehaviour {
} }
bone.Rotation = angle; bone.Rotation = angle;
bone.RotationIK = angle;
} }
if (scale) { if (scale) {
@ -245,6 +246,7 @@ public class SkeletonUtilityBone : MonoBehaviour {
} }
bone.Rotation = angle; bone.Rotation = angle;
bone.RotationIK = angle;
} }
//TODO: Something about this //TODO: Something about this

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -57,7 +57,7 @@ public class SkeletonUtilityKinematicShadow : MonoBehaviour {
continue; continue;
foreach (var sb in shadowBones) { foreach (var sb in shadowBones) {
if (sb.rigidbody == null) if (sb.GetComponent<Rigidbody>() == null)
continue; continue;
if (sb.boneName == b.boneName) { if (sb.boneName == b.boneName) {
@ -72,8 +72,8 @@ public class SkeletonUtilityKinematicShadow : MonoBehaviour {
} }
void FixedUpdate () { void FixedUpdate () {
shadowRoot.rigidbody.MovePosition(transform.position); shadowRoot.GetComponent<Rigidbody>().MovePosition(transform.position);
shadowRoot.rigidbody.MoveRotation(transform.rotation); shadowRoot.GetComponent<Rigidbody>().MoveRotation(transform.rotation);
foreach (var pair in shadowTable) { foreach (var pair in shadowTable) {
pair.Value.localPosition = pair.Key.localPosition; pair.Value.localPosition = pair.Key.localPosition;

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -16,7 +16,7 @@ public class SkeletonUtilitySubmeshRenderer : MonoBehaviour {
MeshFilter parentFilter; MeshFilter parentFilter;
void Awake () { void Awake () {
cachedRenderer = renderer; cachedRenderer = GetComponent<Renderer>();
sharedMaterials = cachedRenderer.sharedMaterials; sharedMaterials = cachedRenderer.sharedMaterials;
filter = GetComponent<MeshFilter>(); filter = GetComponent<MeshFilter>();
@ -53,13 +53,13 @@ public class SkeletonUtilitySubmeshRenderer : MonoBehaviour {
} }
if (cachedRenderer == null) if (cachedRenderer == null)
cachedRenderer = renderer; cachedRenderer = GetComponent<Renderer>();
if (mesh == null || submeshIndex > mesh.subMeshCount - 1) { if (mesh == null || submeshIndex > mesh.subMeshCount - 1) {
cachedRenderer.enabled = false; cachedRenderer.enabled = false;
return; return;
} else { } else {
renderer.enabled = true; GetComponent<Renderer>().enabled = true;
} }
bool changed = false; bool changed = false;
@ -71,7 +71,7 @@ public class SkeletonUtilitySubmeshRenderer : MonoBehaviour {
for (int i = 0; i < renderer.sharedMaterials.Length; i++) { for (int i = 0; i < GetComponent<Renderer>().sharedMaterials.Length; i++) {
if (i == submeshIndex) if (i == submeshIndex)
continue; continue;

View File

@ -10,3 +10,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant:

View File

@ -6,3 +6,5 @@ MonoImporter:
executionOrder: 0 executionOrder: 0
icon: {instanceID: 0} icon: {instanceID: 0}
userData: userData:
assetBundleName:
assetBundleVariant: