void readAnimation(string name, SkeletonData skeletonData) { List <Timeline> timelines = new List <Timeline>(); float scale = 1; float duration = 0; //Slot timelines for (int i = 0, n = ReadInt(); i < n; i++) { int slotIndex = ReadInt(); for (int ii = 0, nn = ReadInt(); ii < nn; ii++) { int timelineType = Read(); int frameCount = ReadInt(); switch (timelineType) { case TIMELINE_COLOR: { ColorTimeline timeline = new ColorTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(); m_tempColor = ReadColor(); //Color timeline.setFrame(frameIndex, time, m_tempColor.r, m_tempColor.g, m_tempColor.b, m_tempColor.a); if (frameIndex < frameCount - 1) { readCurve(frameIndex, timeline); } } timelines.Add(timeline); duration = Mathf.Max(duration, timeline.Frames[frameCount * 5 - 5]); break; } case TIMELINE_ATTACHMENT: { AttachmentTimeline timeline = new AttachmentTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.setFrame(frameIndex, ReadFloat(), ReadString()); } timelines.Add(timeline); duration = Mathf.Max(duration, timeline.Frames[frameCount - 1]); break; } } } } //Bone timelines for (int i = 0, n = ReadInt(); i < n; i++) { int boneIndex = ReadInt(); for (int ii = 0, nn = ReadInt(); ii < nn; ii++) { int timelineType = Read(); int frameCount = ReadInt(); switch (timelineType) { case TIMELINE_ROTATE: { RotateTimeline timeline = new RotateTimeline(frameCount); timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(), ReadFloat()); if (frameIndex < frameCount - 1) { readCurve(frameIndex, timeline); } } timelines.Add(timeline); duration = Mathf.Max(duration, timeline.Frames[frameCount * 2 - 2]); break; } case TIMELINE_TRANSLATE: case TIMELINE_SCALE: { TranslateTimeline timeline; float timelineScale = 1; if (timelineType == TIMELINE_SCALE) { timeline = new ScaleTimeline(frameCount); } else { timeline = new TranslateTimeline(frameCount); timelineScale = scale; } timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(), ReadFloat() * timelineScale, ReadFloat() * timelineScale); if (frameIndex < frameCount - 1) { readCurve(frameIndex, timeline); } } timelines.Add(timeline); duration = Mathf.Max(duration, timeline.Frames[frameCount * 3 - 3]); break; } } } } //FFD timelines for (int i = 0, n = ReadInt(); i < n; i++) { Skin skin = skeletonData.skins[ReadInt() + 1]; for (int ii = 0, nn = ReadInt(); ii < nn; ii++) { int slotIndex = ReadInt(); for (int iii = 0, nnn = ReadInt(); iii < nnn; iii++) { Attachment attachment = skin.GetAttachment(slotIndex, ReadString()); int frameCount = ReadInt(); FFDTimeline timeline = new FFDTimeline(frameCount); timeline.slotIndex = slotIndex; timeline.attachment = attachment; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(); float[] vertices; int vertexCount; if (attachment.GetType() == typeof(MeshAttachment)) { vertexCount = ((MeshAttachment)attachment).vertices.Length; } else { vertexCount = ((SkinnedMeshAttachment)attachment).weights.Length / 3 * 2; } int end = ReadInt(); if (end == 0) { if (attachment.GetType() == typeof(MeshAttachment)) { vertices = ((MeshAttachment)attachment).vertices; } else { vertices = new float[vertexCount]; } } else { vertices = new float[vertexCount]; int start = ReadInt(); end += start; if (scale == 1) { for (int v = start; v < end; v++) { vertices[v] = ReadFloat(); } } else { for (int v = start; v < end; v++) { vertices[v] = ReadFloat() * scale; } } if (attachment.GetType() == typeof(MeshAttachment)) { float[] meshVertices = ((MeshAttachment)attachment).vertices; for (int v = 0, vn = vertices.Length; v < vn; v++) { vertices[v] += meshVertices[v]; } } } timeline.setFrame(frameIndex, time, vertices); if (frameIndex < frameCount - 1) { readCurve(frameIndex, timeline); } } timelines.Add(timeline); duration = Mathf.Max(duration, timeline.Frames[frameCount - 1]); } } } //Draw order timeline int drawOrderCount = ReadInt(); if (drawOrderCount > 0) { DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount); int slotCount = skeletonData.slots.Count; for (int i = 0; i < drawOrderCount; i++) { int offsetCount = ReadInt(); int[] drawOrder = new int[slotCount]; for (int ii = slotCount - 1; ii >= 0; ii--) { drawOrder[ii] = -1; } int[] unchanged = new int[slotCount - offsetCount]; int originalIndex = 0, unchangedIndex = 0; for (int ii = 0; ii < offsetCount; ii++) { int slotIndex = ReadInt(); // Collect unchanged items. while (originalIndex != slotIndex) { unchanged[unchangedIndex++] = originalIndex++; } // Set changed items. drawOrder[originalIndex + ReadInt()] = originalIndex++; } // Collect remaining unchanged items. while (originalIndex < slotCount) { unchanged[unchangedIndex++] = originalIndex++; } // Fill in unchanged items. for (int ii = slotCount - 1; ii >= 0; ii--) { if (drawOrder[ii] == -1) { drawOrder[ii] = unchanged[--unchangedIndex]; } } timeline.setFrame(i, ReadFloat(), drawOrder); } timelines.Add(timeline); duration = Mathf.Max(duration, timeline.Frames[drawOrderCount - 1]); } //Event timeline int eventCount = ReadInt(); if (eventCount > 0) { EventTimeline timeline = new EventTimeline(eventCount); for (int i = 0; i < eventCount; i++) { float time = ReadFloat(); EventData eventData = skeletonData.events[ReadInt()]; Spine.Event event1 = new Spine.Event(eventData); event1.Int = ReadInt(false); event1.Float = ReadFloat(); event1.String = ReadBoolean() ? ReadString() : eventData.String; timeline.setFrame(i, time, event1); } timelines.Add(timeline); duration = Mathf.Max(duration, timeline.Frames[eventCount - 1]); } timelines.TrimExcess(); skeletonData.AddAnimation(new Spine.Animation(name, timelines, duration)); }