public static void ClampCurveRotate360(AnimationCurve rotatecurve, int f, bool rotateCircle) { float prev = rotatecurve.keys[f - 1].value; float curr = rotatecurve.keys[f].value; if (rotateCircle) { //rotate beyond 1 circle if (curr < -180f || curr > 180f) { return; } if (prev < -180f || prev > 180f) { if (f > 1) { prev = rotatecurve.keys[f - 2].value; } } } while ((curr - prev) > 180) { curr -= 360; } while ((curr - prev) < -180) { curr += 360; } if (rotatecurve.keys[f].value != curr) { TangentMode modeIn = KeyframeUtil.GetKeyTangentMode(rotatecurve.keys[f].tangentMode, (int)rotatecurve.keys[f].inTangent); TangentMode modeOut = KeyframeUtil.GetKeyTangentMode(rotatecurve.keys[f].tangentMode, (int)rotatecurve.keys[f].outTangent); if (f == rotatecurve.length - 1) { modeIn = TangentMode.Linear; } rotatecurve.MoveKey(f, KeyframeUtil.GetNew(rotatecurve.keys[f].time, curr, modeIn, modeOut)); } }
// UnityEditor.CurveUtility.cs (c) Unity Technologies public static void UpdateTangentsFromMode(AnimationCurve curve, int index) { if (index < 0 || index >= curve.length) { return; } Keyframe key = curve[index]; if (KeyframeUtil.GetKeyTangentMode(key, 0) == TangentMode.Linear && index >= 1) { key.inTangent = CalculateLinearTangent(curve, index, index - 1); curve.MoveKey(index, key); } if (KeyframeUtil.GetKeyTangentMode(key, 1) == TangentMode.Linear && index + 1 < curve.length) { key.outTangent = CalculateLinearTangent(curve, index, index + 1); curve.MoveKey(index, key); } if (KeyframeUtil.GetKeyTangentMode(key, 0) != TangentMode.Smooth && KeyframeUtil.GetKeyTangentMode(key, 1) != TangentMode.Smooth) { return; } curve.SmoothTangents(index, 0.0f); }
public static void SetCustomTangents(AnimationCurve curve, int i, int nextI, float[] tangentArray) { float diffValue = curve[nextI].value - curve[i].value; float diffTime = curve[nextI].time - curve[i].time; if (diffValue == 0) { return; } float cx1 = tangentArray[0]; float cy1 = tangentArray[1]; float cx2 = tangentArray[2]; float cy2 = tangentArray[3]; Vector2 p0 = new Vector2(0, curve[i].value); Vector2 p3 = new Vector2(diffTime, curve[nextI].value); Vector2 cOrig1 = new Vector2(diffTime * cx1, curve[i].value); cOrig1.y += diffValue > 0 ? diffValue * cy1 : -1.0f * Mathf.Abs(diffValue * cy1); Vector2 cOrig2 = new Vector2(diffTime * cx2, curve[i].value); cOrig2.y += diffValue > 0 ? diffValue * cy2 : -1.0f * Mathf.Abs(diffValue * cy2); Vector2 p1 = GetBezierPoint(p0, cOrig1, cOrig2, p3, 1.0f / 3.0f); Vector2 p2 = GetBezierPoint(p0, cOrig1, cOrig2, p3, 2.0f / 3.0f); Vector2 c1tg, c2tg, c1, c2; CalcControlPoints(p0, p1, p2, p3, out c1, out c2); c1tg = c1 - p0; c2tg = c2 - p3; float outTangent = c1tg.y / c1tg.x; float inTangent = c2tg.y / c2tg.x; object thisKeyframeBoxed = curve[i]; object nextKeyframeBoxed = curve[nextI]; if (!KeyframeUtil.isKeyBroken(thisKeyframeBoxed)) { KeyframeUtil.SetKeyBroken(thisKeyframeBoxed, true); } TangentMode mode = TangentMode.Editable; if (cx1 == 0f && cy1 == 0f) { mode = TangentMode.Linear; } KeyframeUtil.SetKeyTangentMode(thisKeyframeBoxed, 1, mode); if (!KeyframeUtil.isKeyBroken(nextKeyframeBoxed)) { KeyframeUtil.SetKeyBroken(nextKeyframeBoxed, true); } mode = TangentMode.Editable; if (cx2 == 1f && cy2 == 1f) { mode = TangentMode.Linear; } KeyframeUtil.SetKeyTangentMode(nextKeyframeBoxed, 0, mode); Keyframe thisKeyframe = (Keyframe)thisKeyframeBoxed; Keyframe nextKeyframe = (Keyframe)nextKeyframeBoxed; thisKeyframe.outTangent = outTangent; nextKeyframe.inTangent = inTangent; curve.MoveKey(i, thisKeyframe); curve.MoveKey(nextI, nextKeyframe); //* test method float startTime = thisKeyframe.time; for (float j = 0; j < 25f; j++) { float t = j / 25.0f; curve.Evaluate(startTime + diffTime * t); } }