static void ParseScaleTimeline (Skeleton skeleton, ScaleTimeline timeline, AnimationClip clip) { var boneData = skeleton.Data.Bones[timeline.BoneIndex]; var bone = skeleton.Bones[timeline.BoneIndex]; AnimationCurve xCurve = new AnimationCurve(); AnimationCurve yCurve = new AnimationCurve(); AnimationCurve zCurve = new AnimationCurve(); float endTime = timeline.Frames[(timeline.FrameCount * 3) - 3]; float currentTime = timeline.Frames[0]; List<Keyframe> xKeys = new List<Keyframe>(); List<Keyframe> yKeys = new List<Keyframe>(); xKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[1] * boneData.ScaleX, 0, 0)); yKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[2] * boneData.ScaleY, 0, 0)); int listIndex = 1; int frameIndex = 1; int f = 3; float[] frames = timeline.Frames; skeleton.SetToSetupPose(); float lastTime = 0; while (currentTime < endTime) { int pIndex = listIndex - 1; float curveType = timeline.GetCurveType(frameIndex - 1); if (curveType == 0) { //linear Keyframe px = xKeys[pIndex]; Keyframe py = yKeys[pIndex]; float time = frames[f]; float x = frames[f + 1] * boneData.ScaleX; float y = frames[f + 2] * boneData.ScaleY; float xOut = (x - px.value) / (time - px.time); float yOut = (y - py.value) / (time - py.time); px.outTangent = xOut; py.outTangent = yOut; xKeys.Add(new Keyframe(time, x, xOut, 0)); yKeys.Add(new Keyframe(time, y, yOut, 0)); xKeys[pIndex] = px; yKeys[pIndex] = py; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 1) { //stepped Keyframe px = xKeys[pIndex]; Keyframe py = yKeys[pIndex]; float time = frames[f]; float x = frames[f + 1] * boneData.ScaleX; float y = frames[f + 2] * boneData.ScaleY; float xOut = float.PositiveInfinity; float yOut = float.PositiveInfinity; px.outTangent = xOut; py.outTangent = yOut; xKeys.Add(new Keyframe(time, x, xOut, 0)); yKeys.Add(new Keyframe(time, y, yOut, 0)); xKeys[pIndex] = px; yKeys[pIndex] = py; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 2) { //bezier Keyframe px = xKeys[pIndex]; Keyframe py = yKeys[pIndex]; float time = frames[f]; int steps = Mathf.FloorToInt((time - px.time) / bakeIncrement); for (int i = 1; i <= steps; i++) { currentTime += bakeIncrement; if (i == steps) currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); px = xKeys[listIndex - 1]; py = yKeys[listIndex - 1]; float xOut = (bone.ScaleX - px.value) / (currentTime - px.time); float yOut = (bone.ScaleY - py.value) / (currentTime - py.time); px.outTangent = xOut; py.outTangent = yOut; xKeys.Add(new Keyframe(currentTime, bone.ScaleX, xOut, 0)); yKeys.Add(new Keyframe(currentTime, bone.ScaleY, yOut, 0)); xKeys[listIndex - 1] = px; yKeys[listIndex - 1] = py; listIndex++; lastTime = currentTime; } } frameIndex++; f += 3; } xCurve = EnsureCurveKeyCount(new AnimationCurve(xKeys.ToArray())); yCurve = EnsureCurveKeyCount(new AnimationCurve(yKeys.ToArray())); string path = GetPath(boneData); string propertyName = "localScale"; clip.SetCurve(path, typeof(Transform), propertyName + ".x", xCurve); clip.SetCurve(path, typeof(Transform), propertyName + ".y", yCurve); clip.SetCurve(path, typeof(Transform), propertyName + ".z", zCurve); }