mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-15 03:21:35 +08:00
Multiple atlas support, animation component was extracted from tk2dSpineSkeleton
This commit is contained in:
parent
dc33e82c35
commit
ba279725a8
42
spine-tk2d/Code/tk2dSpineAnimation.cs
Normal file
42
spine-tk2d/Code/tk2dSpineAnimation.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
8
spine-tk2d/Code/tk2dSpineAnimation.cs.meta
Normal file
8
spine-tk2d/Code/tk2dSpineAnimation.cs.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c36a835202febaa4ba99b918635b1920
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
@ -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 + ")");
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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.
@ -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() {
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ca40ac45f5827b4cb73b6350a93ba0c
|
||||
DefaultImporter:
|
||||
userData:
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a02018010e423474383a6781a025f491
|
||||
ShaderImporter:
|
||||
userData:
|
||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 33 KiB |
@ -21,7 +21,7 @@ TextureImporter:
|
||||
generateCubemap: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -3
|
||||
maxTextureSize: 256
|
||||
maxTextureSize: 512
|
||||
textureSettings:
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
|
||||
Binary file not shown.
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60e10894b87b9d94ea8c33e508c0554e
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
BIN
spine-tk2d/Example/Spineboy/Atlas/SpineboyAtlas Data/atlas1.png
Normal file
BIN
spine-tk2d/Example/Spineboy/Atlas/SpineboyAtlas Data/atlas1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
@ -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:
|
||||
Binary file not shown.
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52a0c49b9eed9494ba69c9ca457348a3
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
BIN
spine-tk2d/Example/Spineboy/Atlas/SpineboyAtlas Data/atlas2.png
Normal file
BIN
spine-tk2d/Example/Spineboy/Atlas/SpineboyAtlas Data/atlas2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.8 KiB |
@ -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:
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user