private static SpineData.AnimationBoneData ParseBoneAnimTimeline(SpineArmatureEditor armatureEditor, string boneName, Bones2D.JSONClass bonesAnimObj, string animType) { Bones2D.JSONArray animObjArr = bonesAnimObj[animType].AsArray; SpineData.AnimationBoneData spineAnimBoneData = new SpineData.AnimationBoneData(); spineAnimBoneData.name = boneName; spineAnimBoneData.timelines = new SpineData.BoneTimeline[animObjArr.Count]; for (int i = 0; i < animObjArr.Count; ++i) { Bones2D.JSONClass animObj = animObjArr[i].AsObject; SpineData.BoneTimeline timeline = new SpineData.BoneTimeline(); timeline.type = animType; spineAnimBoneData.timelines[i] = timeline; if (animObj.ContainKey("time")) { timeline.time = animObj["time"].AsFloat; } //The bone's rotation relative to the setup pose if (animObj.ContainKey("angle")) { timeline.angle = animObj["angle"].AsFloat; } //The bone's x,y relative to the setup pose if (animObj.ContainKey("x")) { timeline.x = animObj["x"].AsFloat; if (animType == "translate") { timeline.x *= armatureEditor.unit; } } if (animObj.ContainKey("y")) { timeline.y = animObj["y"].AsFloat; if (animType == "translate") { timeline.y *= armatureEditor.unit; } } if (animObj.ContainKey("curve")) { if (animObj["curve"] == "stepped") { timeline.tweenEasing = "stepped"; } else if (animObj["curve"] == "linear") { //default } else { timeline.curve = ConvertJsonArrayToFloatArr(animObj["curve"].AsArray); } } } return(spineAnimBoneData); }
static bool CreateAnimBone(SpineArmatureEditor armatureEditor, AnimationClip clip, SpineData.AnimationBoneData[] animBoneDatas) { Dictionary <string, string> bonePathKV = new Dictionary <string, string>(); for (int i = 0; i < animBoneDatas.Length; ++i) { SpineData.AnimationBoneData animBoneData = animBoneDatas[i]; Transform bone = armatureEditor.bonesKV[animBoneData.name]; AnimationCurve xcurve = new AnimationCurve(); AnimationCurve ycurve = new AnimationCurve(); AnimationCurve sxcurve = new AnimationCurve(); AnimationCurve sycurve = new AnimationCurve(); AnimationCurve rotatecurve = new AnimationCurve(); bool isHaveCurve = false; for (int j = 0; j < animBoneData.timelines.Length; ++j) { SpineData.BoneTimeline timeline = animBoneData.timelines[j]; string prevTweeneasing = "linear"; //前一帧的tweenEasing float[] prevCurves = null; if (j > 0) { prevTweeneasing = animBoneData.timelines[j - 1].tweenEasing; prevCurves = animBoneData.timelines[j - 1].curve; } TangentMode tanModeL = GetPrevFrameTangentMode(prevTweeneasing, prevCurves); TangentMode tanModeR = TangentMode.Linear; if (timeline.curve != null && timeline.curve.Length > 0) { tanModeR = TangentMode.Editable; isHaveCurve = true; } else { if (timeline.tweenEasing == "stepped") { tanModeR = TangentMode.Stepped; } else { tanModeR = TangentMode.Linear; } } if (timeline.type == "rotate") //rotate,scale,translate,shear { if (!float.IsNaN(timeline.angle)) { float rotate = timeline.angle + bone.localEulerAngles.z; rotatecurve.AddKey(KeyframeUtil.GetNew(timeline.time, rotate, tanModeL, tanModeR)); } } else if (timeline.type == "translate") { if (!float.IsNaN(timeline.x)) { xcurve.AddKey(KeyframeUtil.GetNew(timeline.time, timeline.x + bone.localPosition.x, tanModeL, tanModeR)); } if (!float.IsNaN(timeline.y)) { ycurve.AddKey(KeyframeUtil.GetNew(timeline.time, timeline.y + bone.localPosition.y, tanModeL, tanModeR)); } } else if (timeline.type == "scale") { if (!float.IsNaN(timeline.x)) { sxcurve.AddKey(KeyframeUtil.GetNew(timeline.time, timeline.x * bone.localScale.x, tanModeL, tanModeR)); } if (!float.IsNaN(timeline.y)) { sycurve.AddKey(KeyframeUtil.GetNew(timeline.time, timeline.y * bone.localScale.y, tanModeL, tanModeR)); } } } CurveExtension.OptimizesCurve(xcurve); CurveExtension.OptimizesCurve(ycurve); CurveExtension.OptimizesCurve(sxcurve); CurveExtension.OptimizesCurve(sycurve); CurveExtension.OptimizesCurve(rotatecurve); string path = ""; if (bonePathKV.ContainsKey(bone.name)) { path = bonePathKV[bone.name]; } else { path = GetNodeRelativePath(armatureEditor, bone); bonePathKV[bone.name] = path; if (slotPathKV.ContainsKey(bone.name) && slotPathKV[bone.name].Equals(path)) { Debug.LogError("Bone2D Error: Name conflict ->" + path); return(false); } } bool localPosFlag = false; if (xcurve.keys != null && xcurve.keys.Length > 0 && CheckCurveValid(xcurve, bone.localPosition.x)) { localPosFlag = true; } if (ycurve.keys != null && ycurve.keys.Length > 0 && CheckCurveValid(ycurve, bone.localPosition.y)) { localPosFlag = true; } if (localPosFlag) { if (isHaveCurve) { SetCustomCurveTangents(xcurve, animBoneData.timelines); } CurveExtension.UpdateAllLinearTangents(xcurve); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.x"), xcurve); if (isHaveCurve) { SetCustomCurveTangents(ycurve, animBoneData.timelines); } CurveExtension.UpdateAllLinearTangents(ycurve); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.y"), ycurve); //add pose AnimationCurve posexcurve = new AnimationCurve(); AnimationCurve poseycurve = new AnimationCurve(); posexcurve.AddKey(new Keyframe(0f, bone.localPosition.x)); poseycurve.AddKey(new Keyframe(0f, bone.localPosition.y)); AnimationUtility.SetEditorCurve(poseClip, EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.x"), posexcurve); AnimationUtility.SetEditorCurve(poseClip, EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalPosition.y"), poseycurve); } Bone myBone = bone.GetComponent <Bone>(); string scPath = path; if (myBone && myBone.inheritScale) { scPath = myBone.inheritScale.name; } bool localSc = false; if (sxcurve.keys != null && sxcurve.keys.Length > 0 && CheckCurveValid(sxcurve, bone.localScale.x)) { localSc = true; } if (sycurve.keys != null && sycurve.keys.Length > 0 && CheckCurveValid(sycurve, bone.localScale.y)) { localSc = true; } if (localSc) { if (isHaveCurve) { SetCustomCurveTangents(sxcurve, animBoneData.timelines); } CurveExtension.UpdateAllLinearTangents(sxcurve); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(scPath, typeof(Transform), "m_LocalScale.x"), sxcurve); if (isHaveCurve) { SetCustomCurveTangents(sycurve, animBoneData.timelines); } CurveExtension.UpdateAllLinearTangents(sycurve); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(scPath, typeof(Transform), "m_LocalScale.y"), sycurve); //add pose AnimationCurve posesxcurve = new AnimationCurve(); AnimationCurve posesycurve = new AnimationCurve(); posesxcurve.AddKey(new Keyframe(0f, bone.localScale.x)); posesycurve.AddKey(new Keyframe(0f, bone.localScale.y)); AnimationUtility.SetEditorCurve(poseClip, EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalScale.x"), posesxcurve); AnimationUtility.SetEditorCurve(poseClip, EditorCurveBinding.FloatCurve(path, typeof(Transform), "m_LocalScale.y"), posesycurve); } string rotatePath = path; if (myBone && myBone.inheritRotation) { rotatePath = myBone.inheritRotation.name; } if (rotatecurve.keys != null && rotatecurve.keys.Length > 0 && CheckCurveValid(rotatecurve, bone.localEulerAngles.z)) { CurveExtension.ClampCurveRotate360(rotatecurve, false); if (isHaveCurve) { SetCustomCurveTangents(rotatecurve, animBoneData.timelines); } CurveExtension.UpdateAllLinearTangents(rotatecurve); clip.SetCurve(rotatePath, typeof(Transform), "localEulerAngles.z", rotatecurve); //add pose AnimationCurve posesrotatecurve = new AnimationCurve(); posesrotatecurve.AddKey(new Keyframe(0f, bone.localEulerAngles.z)); AnimationUtility.SetEditorCurve(poseClip, EditorCurveBinding.FloatCurve(path, typeof(Transform), "localEulerAngles.z"), posesrotatecurve); } } return(true); }