private static bool InitPointsInfo() { if (animationPoints == null) { animationPoints = new List <AnimationPathPoint>(); } animationPoints.Clear(); String inPath = String.Empty; activeRootGameObject = activeGameObject; if (activeGameObject.GetComponent <Animator>() == null && activeGameObject.GetComponent <Animation>() == null) { Transform tr = activeGameObject.transform.parent; while (!(tr.GetComponent <Animator>() != null)) { if (tr == tr.root) { return(false); } tr = tr.parent; } activeRootGameObject = tr.gameObject; inPath = AnimationUtility.CalculateTransformPath(activeGameObject.transform, activeRootGameObject.transform); } activeParentTransform = activeGameObject.transform.parent; Type inType = typeof(Transform); AnimationCurve curveX = AnimationUtility.GetEditorCurve(activeAnimationClip, EditorCurveBinding.FloatCurve(inPath, inType, "m_LocalPosition.x")); AnimationCurve curveY = AnimationUtility.GetEditorCurve(activeAnimationClip, EditorCurveBinding.FloatCurve(inPath, inType, "m_LocalPosition.y")); AnimationCurve curveZ = AnimationUtility.GetEditorCurve(activeAnimationClip, EditorCurveBinding.FloatCurve(inPath, inType, "m_LocalPosition.z")); Vector3 initPosition = activeRootGameObject.transform.localPosition; if (curveX == null || curveY == null || curveZ == null) { // 有可能是UI的动画 var rt = activeRootGameObject.transform.GetComponent <RectTransform>(); if (rt) { inType = typeof(RectTransform); curveX = AnimationUtility.GetEditorCurve(activeAnimationClip, EditorCurveBinding.FloatCurve(inPath, inType, "m_AnchoredPosition.x")); curveY = AnimationUtility.GetEditorCurve(activeAnimationClip, EditorCurveBinding.FloatCurve(inPath, inType, "m_AnchoredPosition.y")); curveZ = AnimationUtility.GetEditorCurve(activeAnimationClip, EditorCurveBinding.FloatCurve(inPath, inType, "m_AnchoredPosition.z")); initPosition = rt.anchoredPosition; if (curveX == null && curveY == null && curveZ == null) { return(false); } } else { return(false); } } animationPoints = AnimationPathPoint.MakePoints(curveX, curveY, curveZ, initPosition); return(true); }
public static List <AnimationPathPoint> MakePoints(AnimationCurve curveX, AnimationCurve curveY, AnimationCurve curveZ, Vector3 initPosition) { List <AnimationPathPoint> points = new List <AnimationPathPoint>(); List <float> times = new List <float>(); if (curveX != null) { for (int i = 0; i < curveX.length; i++) { if (!times.Contains(curveX.keys[i].time)) { times.Add(curveX.keys[i].time); } } } if (curveY != null) { for (int i = 0; i < curveY.length; i++) { if (!times.Contains(curveY.keys[i].time)) { times.Add(curveY.keys[i].time); } } } if (curveZ != null) { for (int i = 0; i < curveZ.length; i++) { if (!times.Contains(curveZ.keys[i].time)) { times.Add(curveZ.keys[i].time); } } } times.Sort(); for (int i = 0; i < times.Count; i++) { float time = times[i]; AnimationPathPoint pathPoint = new AnimationPathPoint( GetKeyframeAtTime(curveX, time, initPosition.x), GetKeyframeAtTime(curveY, time, initPosition.y), GetKeyframeAtTime(curveZ, time, initPosition.z) ); points.Add(pathPoint); } return(points); }
public static void CalcTangents(AnimationPathPoint pathPoint, AnimationPathPoint nextPathPoint, out Vector3 startTangent, out Vector3 endTangent) { startTangent = pathPoint.position; endTangent = nextPathPoint.position; float dx = nextPathPoint.time - pathPoint.time; startTangent.x += (dx * pathPoint.outTangent.x * 1 / 3); startTangent.y += (dx * pathPoint.outTangent.y * 1 / 3); startTangent.z += (dx * pathPoint.outTangent.z * 1 / 3); endTangent.x -= (dx * nextPathPoint.inTangent.x * 1 / 3); endTangent.y -= (dx * nextPathPoint.inTangent.y * 1 / 3); endTangent.z -= (dx * nextPathPoint.inTangent.z * 1 / 3); }
private static bool SetPointTangent(int pointIndex, Vector3 worldTangent, bool isInTangent) { List <AnimationPathPoint> points = animationPoints; AnimationPathPoint pathPoint = null; AnimationPathPoint nextPathPoint = null; Vector3 offset = Vector3.zero; if (isInTangent) { pathPoint = points[pointIndex - 1]; nextPathPoint = points[pointIndex]; offset = GetLocalPosition(worldTangent) - GetLocalPosition(nextPathPoint.worldInTangent); } else { pathPoint = points[pointIndex]; nextPathPoint = points[pointIndex + 1]; offset = GetLocalPosition(worldTangent) - GetLocalPosition(pathPoint.worldOutTangent); } string inPath = AnimationUtility.CalculateTransformPath(activeGameObject.transform, activeRootGameObject.transform); Type inType = typeof(Transform); EditorCurveBinding bindingX = EditorCurveBinding.FloatCurve(inPath, inType, "m_LocalPosition.x"); EditorCurveBinding bindingY = EditorCurveBinding.FloatCurve(inPath, inType, "m_LocalPosition.y"); EditorCurveBinding bindingZ = EditorCurveBinding.FloatCurve(inPath, inType, "m_LocalPosition.z"); AnimationCurve curveX = AnimationUtility.GetEditorCurve(activeAnimationClip, bindingX); AnimationCurve curveY = AnimationUtility.GetEditorCurve(activeAnimationClip, bindingY); AnimationCurve curveZ = AnimationUtility.GetEditorCurve(activeAnimationClip, bindingZ); if (curveX == null || curveY == null || curveZ == null) { return(false); } AnimationPathPoint.ModifyPointTangent(pathPoint, nextPathPoint, offset, isInTangent, curveX, curveY, curveZ); Undo.RegisterCompleteObjectUndo(activeAnimationClip, "Edit Curve"); AnimationUtility.SetEditorCurve(activeAnimationClip, bindingX, curveX); AnimationUtility.SetEditorCurve(activeAnimationClip, bindingY, curveY); AnimationUtility.SetEditorCurve(activeAnimationClip, bindingZ, curveZ); AnimationWindowUtil.Repaint(); return(true); }
public static void ModifyPointTangent(AnimationPathPoint pathPoint, AnimationPathPoint nextPathPoint, Vector3 offset, bool isInTangent, AnimationCurve curveX, AnimationCurve curveY, AnimationCurve curveZ) { Vector3 startTangent; Vector3 endTangent; CalcTangents(pathPoint, nextPathPoint, out startTangent, out endTangent); float time; Vector3 position; Vector3 inTangent; Vector3 outTangent; int[] tangentMode; float dx = nextPathPoint.time - pathPoint.time; if (isInTangent) { time = nextPathPoint.time; position = nextPathPoint.position; endTangent += offset; inTangent = (nextPathPoint.position - endTangent) / dx * 3f; outTangent = nextPathPoint.outTangent; tangentMode = nextPathPoint.tangentMode; } else { time = pathPoint.time; position = pathPoint.position; startTangent += offset; inTangent = pathPoint.inTangent; outTangent = (startTangent - pathPoint.position) / dx * 3f; tangentMode = pathPoint.tangentMode; } int leftRight = isInTangent ? 0 : 1; ModifyCurveAtKeyframe(curveX, time, position.x, inTangent.x, outTangent.x, tangentMode[0], leftRight); ModifyCurveAtKeyframe(curveY, time, position.y, inTangent.y, outTangent.y, tangentMode[1], leftRight); ModifyCurveAtKeyframe(curveZ, time, position.z, inTangent.z, outTangent.z, tangentMode[2], leftRight); }
private static bool InitPointsInfo() { if (animationPoints == null) { animationPoints = new List <AnimationPathPoint>(); } animationPoints.Clear(); String inPath = String.Empty; activeRootGameObject = activeGameObject; if (activeGameObject.GetComponent <Animator>() == null && activeGameObject.GetComponent <Animation>() == null) { Transform tr = activeGameObject.transform.parent; while (!(tr.GetComponent <Animator>() != null)) { if (tr == tr.root) { return(false); } tr = tr.parent; } activeRootGameObject = tr.gameObject; inPath = AnimationUtility.CalculateTransformPath(activeGameObject.transform, activeRootGameObject.transform); } activeParentTransform = activeGameObject.transform.parent; Type inType = typeof(Transform); AnimationCurve curveX = AnimationUtility.GetEditorCurve(activeAnimationClip, EditorCurveBinding.FloatCurve(inPath, inType, "m_LocalPosition.x")); AnimationCurve curveY = AnimationUtility.GetEditorCurve(activeAnimationClip, EditorCurveBinding.FloatCurve(inPath, inType, "m_LocalPosition.y")); AnimationCurve curveZ = AnimationUtility.GetEditorCurve(activeAnimationClip, EditorCurveBinding.FloatCurve(inPath, inType, "m_LocalPosition.z")); if (curveX == null || curveY == null || curveZ == null) { //Debug.LogError(activeGameObject.name + " 必须要有完整的 Position 动画曲线!"); return(false); } animationPoints = AnimationPathPoint.MakePoints(curveX, curveY, curveZ); return(true); }
private static void DrawSceneViewGUI() { if (reloadPointsInfo) { reloadPointsInfo = false; int num = animationPoints.Count; InitPointsInfo(); if (pointShow && animationPoints.Count > num) { // FIXME 这是为了修复新增点的时候,方向杆ID被改变了,所以操作无效 // 不完美,需要第二次点击的时候,才会获取新控件ID GUIUtility.hotControl = 0; Event.current.Use(); } } if (activeGameObject == null) { return; } List <AnimationPathPoint> points = animationPoints; int numPos = points.Count; for (int i = 0; i < numPos; i++) { AnimationPathPoint pathPoint = points[i]; pathPoint.worldPosition = GetWorldPosition(pathPoint.position); } for (int i = 0; i < numPos - 1; i++) { AnimationPathPoint pathPoint = points[i]; AnimationPathPoint nextPathPoint = points[i + 1]; Vector3 startTangent; Vector3 endTangent; AnimationPathPoint.CalcTangents(pathPoint, nextPathPoint, out startTangent, out endTangent); Vector3 p0 = pathPoint.worldPosition; Vector3 p1 = GetWorldPosition(startTangent); Vector3 p2 = GetWorldPosition(endTangent); Vector3 p3 = nextPathPoint.worldPosition; Handles.DrawBezier(p0, p3, p1, p2, Color.white, null, 2f); pathPoint.worldOutTangent = p1; nextPathPoint.worldInTangent = p2; } if (!pointShow) { return; } Quaternion handleRotation = activeParentTransform != null ? activeParentTransform.rotation : Quaternion.identity; for (int i = 0; i < numPos; i++) { int pointIndex = i * 3; Handles.color = Color.green; AnimationPathPoint pathPoint = points[i]; Vector3 position = pathPoint.worldPosition; float pointHandleSize = HandleUtility.GetHandleSize(position) * 0.04f; float pointPickSize = pointHandleSize * 0.7f; Handles.Label(position, " Point " + i); if (Handles.Button(position, handleRotation, pointHandleSize, pointPickSize, Handles.DotCap)) { selectedPointIndex = pointIndex; if (Selection.activeGameObject != activeGameObject) { Selection.activeGameObject = activeGameObject; } AnimationWindowUtil.SetCurrentTime(pathPoint.time); } Handles.color = Color.grey; int inIndex = pointIndex - 1; int outIndex = pointIndex + 1; if (selectedPointIndex < 0 || selectedPointIndex < inIndex || selectedPointIndex > outIndex) { continue; } if (i != 0) { Handles.DrawLine(position, pathPoint.worldInTangent); if (Handles.Button(pathPoint.worldInTangent, handleRotation, pointHandleSize, pointPickSize, Handles.DotCap)) { selectedPointIndex = inIndex; } if (selectedPointIndex == inIndex) { EditorGUI.BeginChangeCheck(); Vector3 pos = Handles.PositionHandle(pathPoint.worldInTangent, handleRotation); if (EditorGUI.EndChangeCheck() && SetPointTangent(i, pos, true)) { return; } } } if (i != numPos - 1) { Handles.DrawLine(position, pathPoint.worldOutTangent); if (Handles.Button(pathPoint.worldOutTangent, handleRotation, pointHandleSize, pointPickSize, Handles.DotCap)) { selectedPointIndex = outIndex; } if (selectedPointIndex == outIndex) { EditorGUI.BeginChangeCheck(); Vector3 pos = Handles.PositionHandle(pathPoint.worldOutTangent, handleRotation); if (EditorGUI.EndChangeCheck() && SetPointTangent(i, pos, false)) { return; } } } } }