예제 #1
0
    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);
    }
예제 #2
0
    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);
    }
예제 #3
0
    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);
    }
예제 #4
0
    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);
    }
예제 #5
0
    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);
    }
예제 #6
0
    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);
    }
예제 #7
0
    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;
                    }
                }
            }
        }
    }