Multiple atlas support, animation component was extracted from tk2dSpineSkeleton

This commit is contained in:
Andrey Viktorov 2013-06-13 19:40:43 +07:00
parent dc33e82c35
commit ba279725a8
22 changed files with 214 additions and 81 deletions

View File

@ -0,0 +1,42 @@
using UnityEngine;
using Spine;
// TODO: add events in animation component
[RequireComponent(typeof(tk2dSpineSkeleton))]
public class tk2dSpineAnimation : MonoBehaviour {
public string animationName;
public bool loop;
public float animationSpeed = 1;
public Spine.AnimationState state;
private tk2dSpineSkeleton spineSkeleton;
void Start () {
spineSkeleton = GetComponent<tk2dSpineSkeleton>();
state = new Spine.AnimationState(spineSkeleton.skeletonDataAsset.GetAnimationStateData());
}
void Update () {
UpdateAnimation();
}
private void UpdateAnimation() {
// Check if we need to stop current animation
if (state.Animation != null && animationName == null) {
state.ClearAnimation();
} else if (state.Animation == null || animationName != state.Animation.Name) {
// Check for different animation name or animation end
Spine.Animation animation = spineSkeleton.skeleton.Data.FindAnimation(animationName);
if (animation != null) state.SetAnimation(animation,loop);
}
state.Loop = loop;
// Update animation
spineSkeleton.skeleton.Update(Time.deltaTime * animationSpeed);
state.Update(Time.deltaTime * animationSpeed);
state.Apply(spineSkeleton.skeleton);
}
}

View File

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

View File

@ -14,19 +14,12 @@ public class tk2dSpineAttachmentLoader : AttachmentLoader {
public Attachment NewAttachment(Skin skin, AttachmentType type, String name) {
if (type != AttachmentType.region) throw new Exception("Unknown attachment type: " + type);
// Strip folder names.
int index = name.LastIndexOfAny(new char[] {'/', '\\'});
if (index != -1) name = name.Substring(index + 1);
tk2dSpriteDefinition attachmentParameters = null;
for (int i = 0; i < sprites.inst.spriteDefinitions.Length; ++i) {
tk2dSpriteDefinition def = sprites.inst.spriteDefinitions[i];
if (def.name == name) {
attachmentParameters = def;
break;
}
}
tk2dSpriteDefinition attachmentParameters = sprites.GetSpriteDefinition(name);
if (attachmentParameters == null) throw new Exception("Sprite not found in atlas: " + name + " (" + type + ")");
if (attachmentParameters.complexGeometry) throw new NotImplementedException("Complex geometry is not supported: " + name + " (" + type + ")");

View File

@ -1,9 +1,8 @@
using System.Collections.Generic;
using UnityEngine;
using Spine;
// TODO: multiple atlas support
// TODO: split skeleton and animation components
// TODO: add events in animation component
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter))]
@ -12,21 +11,20 @@ public class tk2dSpineSkeleton : MonoBehaviour, tk2dRuntime.ISpriteCollectionFor
public tk2dSpineSkeletonDataAsset skeletonDataAsset;
public Skeleton skeleton;
public string animationName;
public bool loop;
public float animationSpeed = 1;
public Spine.AnimationState state;
private Mesh mesh;
private Vector3[] vertices;
private Color[] colors;
private Vector2[] uvs;
private int[] triangles;
private int cachedQuadCount;
private float[] vertexPositions;
private List<Material> submeshMaterials = new List<Material>();
private List<int[]> submeshIndices = new List<int[]>();
void Awake() {
vertexPositions = new float[8];
submeshMaterials = new List<Material>();
submeshIndices = new List<int[]>();
}
void Start () {
@ -42,8 +40,8 @@ public class tk2dSpineSkeleton : MonoBehaviour, tk2dRuntime.ISpriteCollectionFor
if(skeleton == null || skeleton.Data != skeletonData) Initialize();
UpdateAnimation();
UpdateSkeleton();
skeleton.UpdateWorldTransform();
UpdateCache();
UpdateMesh();
}
@ -53,10 +51,9 @@ public class tk2dSpineSkeleton : MonoBehaviour, tk2dRuntime.ISpriteCollectionFor
DestroyImmediate(mesh);
mesh = null;
renderer.sharedMaterial = null;
renderer.sharedMaterials = null;
skeleton = null;
state = null;
}
private void Initialize() {
@ -65,7 +62,6 @@ public class tk2dSpineSkeleton : MonoBehaviour, tk2dRuntime.ISpriteCollectionFor
mesh.name = "tk2dSkeleton Mesh";
mesh.hideFlags = HideFlags.HideAndDontSave;
state = new Spine.AnimationState(skeletonDataAsset.GetAnimationStateData());
skeleton = new Skeleton(skeletonDataAsset.GetSkeletonData());
}
@ -105,14 +101,6 @@ public class tk2dSpineSkeleton : MonoBehaviour, tk2dRuntime.ISpriteCollectionFor
colors[vertexIndex + 2] = currentColor;
colors[vertexIndex + 3] = currentColor;
int index = quadIndex * 6;
triangles[index + 0] = vertexIndex;
triangles[index + 1] = vertexIndex + 2;
triangles[index + 2] = vertexIndex + 1;
triangles[index + 3] = vertexIndex + 2;
triangles[index + 4] = vertexIndex + 3;
triangles[index + 5] = vertexIndex + 1;
quadIndex++;
}
}
@ -122,7 +110,11 @@ public class tk2dSpineSkeleton : MonoBehaviour, tk2dRuntime.ISpriteCollectionFor
mesh.vertices = vertices;
mesh.colors = colors;
mesh.uv = uvs;
mesh.triangles = triangles;
mesh.subMeshCount = submeshIndices.Count;
for(int i = 0; i < mesh.subMeshCount; ++i) {
mesh.SetTriangles(submeshIndices[i],i);
}
if (skeletonDataAsset.normalGenerationMode != tk2dSpriteCollection.NormalGenerationMode.None) {
mesh.RecalculateNormals();
@ -136,7 +128,7 @@ public class tk2dSpineSkeleton : MonoBehaviour, tk2dRuntime.ISpriteCollectionFor
}
}
renderer.sharedMaterial = skeletonDataAsset.spritesData.inst.materials[0];
renderer.sharedMaterials = submeshMaterials.ToArray();
}
private void UpdateCache() {
@ -154,31 +146,52 @@ public class tk2dSpineSkeleton : MonoBehaviour, tk2dRuntime.ISpriteCollectionFor
vertices = new Vector3[quadCount * 4];
uvs = new Vector2[quadCount * 4];
colors = new Color[quadCount * 4];
triangles = new int[quadCount * 6];
UpdateSubmeshCache();
}
private void UpdateSkeleton() {
skeleton.Update(Time.deltaTime * animationSpeed);
skeleton.UpdateWorldTransform();
}
private void UpdateAnimation() {
// Check if we need to stop current animation
if (state.Animation != null && animationName == null) {
state.ClearAnimation();
} else if (state.Animation == null || animationName != state.Animation.Name) {
// Check for different animation name or animation end
Spine.Animation animation = skeleton.Data.FindAnimation(animationName);
if (animation != null) state.SetAnimation(animation,loop);
private void UpdateSubmeshCache() {
submeshIndices.Clear();
submeshMaterials.Clear();
Material oldMaterial = null;
List<int> currentSubmesh = new List<int>();
int quadIndex = 0;
int drawCount = skeleton.DrawOrder.Count;
for (int i = 0; i < drawCount; i++) {
Attachment attachment = skeleton.DrawOrder[i].Attachment;
Material currentMaterial = skeletonDataAsset.spritesData.GetSpriteDefinition(attachment.Name).material;
if(!(attachment is RegionAttachment)) continue;
if(oldMaterial == null) oldMaterial = currentMaterial;
if(oldMaterial != currentMaterial) {
submeshIndices.Add(currentSubmesh.ToArray());
submeshMaterials.Add(oldMaterial);
currentSubmesh.Clear();
}
int vertexIndex = quadIndex * 4;
currentSubmesh.Add(vertexIndex);
currentSubmesh.Add(vertexIndex + 2);
currentSubmesh.Add(vertexIndex + 1);
currentSubmesh.Add(vertexIndex + 2);
currentSubmesh.Add(vertexIndex + 3);
currentSubmesh.Add(vertexIndex + 1);
quadIndex++;
oldMaterial = currentMaterial;
}
state.Loop = loop;
// Update animation
state.Update(Time.deltaTime * animationSpeed);
state.Apply(skeleton);
submeshIndices.Add(currentSubmesh.ToArray());
submeshMaterials.Add(oldMaterial);
}
public bool UsesSpriteCollection(tk2dSpriteCollectionData spriteCollection) {
return skeletonDataAsset.spritesData == spriteCollection;
}
@ -187,6 +200,7 @@ public class tk2dSpineSkeleton : MonoBehaviour, tk2dRuntime.ISpriteCollectionFor
skeletonDataAsset.ForceUpdate();
skeleton = new Skeleton(skeletonDataAsset.GetSkeletonData());
UpdateSubmeshCache();
UpdateMesh();
}
}

View File

@ -35,6 +35,15 @@ public class tk2dSpineMenus {
Selection.activeObject = gameObject;
}
/*
*/
[MenuItem("GameObject/Create Other/tk2d/Spine Animated Skeleton")]
static public void CreateAnimatedSkeletonGameObject() {
GameObject gameObject = new GameObject("New tk2d Spine Animated Skeleton",typeof(tk2dSpineAnimation));
EditorUtility.FocusProjectWindow();
Selection.activeObject = gameObject;
}
/*
*/
[MenuItem("Component/2D Toolkit/Spine Skeleton")]
@ -48,4 +57,18 @@ public class tk2dSpineMenus {
static public bool ValidateCreateSkeletonComponent() {
return Selection.activeGameObject != null && Selection.activeGameObject.GetComponent(typeof(tk2dSpineSkeleton)) == null;
}
/*
*/
[MenuItem("Component/2D Toolkit/Spine Animation")]
static public void CreateAnimationComponent() {
Selection.activeGameObject.AddComponent(typeof(tk2dSpineAnimation));
}
/*
*/
[MenuItem("Component/2d Toolkit/Spine Animation",true)]
static public bool ValidateCreateAnimationComponent() {
return Selection.activeGameObject != null && Selection.activeGameObject.GetComponent(typeof(tk2dSpineAnimation)) == null;
}
}

Binary file not shown.

View File

@ -4,10 +4,10 @@ using System.Collections;
/*
*/
public class tk2dSpineboy : MonoBehaviour {
private tk2dSpineSkeleton skeleton;
private tk2dSpineAnimation skeleton;
void Start() {
skeleton = GetComponent<tk2dSpineSkeleton>();
skeleton = GetComponent<tk2dSpineAnimation>();
}
void LateUpdate() {

View File

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

View File

@ -1,17 +0,0 @@
Shader "Skeleton" {
Properties {
_MainTex ("Texture to blend", 2D) = "black" {}
}
SubShader {
Tags { "Queue" = "Transparent" }
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass {
SetTexture [_MainTex] {
combine texture
}
}
}
}

View File

@ -1,4 +0,0 @@
fileFormatVersion: 2
guid: a02018010e423474383a6781a025f491
ShaderImporter:
userData:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -21,7 +21,7 @@ TextureImporter:
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 256
maxTextureSize: 512
textureSettings:
filterMode: 1
aniso: 1

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

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