private List <AnimationWindowCurve> GetCurvesAffectedByNodes(List <AnimationWindowHierarchyNode> nodes, bool includeLinkedCurves)
        {
            List <AnimationWindowCurve> curves = new List <AnimationWindowCurve>();

            foreach (var node in nodes)
            {
                AnimationWindowHierarchyNode hierarchyNode = node;

                if (hierarchyNode.parent is AnimationWindowHierarchyPropertyGroupNode && includeLinkedCurves)
                {
                    hierarchyNode = (AnimationWindowHierarchyNode)hierarchyNode.parent;
                }

                if (hierarchyNode.curves == null)
                {
                    continue;
                }

                if (hierarchyNode.curves.Length > 0)
                {
                    // Property or propertygroup
                    if (hierarchyNode is AnimationWindowHierarchyPropertyGroupNode || hierarchyNode is AnimationWindowHierarchyPropertyNode)
                    {
                        curves.AddRange(AnimationWindowUtility.FilterCurves(hierarchyNode.curves, hierarchyNode.path, hierarchyNode.animatableObjectType, hierarchyNode.propertyName));
                    }
                    else
                    {
                        curves.AddRange(AnimationWindowUtility.FilterCurves(hierarchyNode.curves, hierarchyNode.path, hierarchyNode.animatableObjectType));
                    }
                }
            }
            return(curves.Distinct().ToList());
        }
        override protected void RenameEnded()
        {
            string newName = GetRenameOverlay().name;
            string oldName = GetRenameOverlay().originalName;

            if (newName != oldName)
            {
                Undo.RecordObject(state.activeAnimationClip, "Rename Curve");

                foreach (AnimationWindowCurve curve in m_RenamedNode.curves)
                {
                    EditorCurveBinding newBinding = AnimationWindowUtility.GetRenamedBinding(curve.binding, newName);

                    if (AnimationWindowUtility.CurveExists(newBinding, state.allCurves.ToArray()))
                    {
                        Debug.LogWarning("Curve already exists, renaming cancelled.");
                        continue;
                    }

                    AnimationWindowUtility.RenameCurvePath(curve, newBinding, curve.clip);
                }
            }

            m_RenamedNode = null;
        }
        public float GetNodeHeight(AnimationWindowHierarchyNode node)
        {
            if (node is AnimationWindowHierarchyAddButtonNode)
            {
                return(k_AddCurveButtonNodeHeight);
            }

            AnimationWindowHierarchyState hierarchyState = m_TreeView.state as AnimationWindowHierarchyState;

            return(hierarchyState.GetTallMode(node) ? k_DopeSheetRowHeightTall : k_DopeSheetRowHeight);
        }
 public void SetTallMode(AnimationWindowHierarchyNode node, bool tallMode)
 {
     if (tallMode)
     {
         m_TallInstanceIDs.Add(node.id);
     }
     else
     {
         m_TallInstanceIDs.Remove(node.id);
     }
 }
        float GetTopPixelOfRow(int row, IList <TreeViewItem> rows)
        {
            float top = 0f;

            for (int i = 0; i < row && i < rows.Count; i++)
            {
                AnimationWindowHierarchyNode node = rows[i] as AnimationWindowHierarchyNode;
                top += GetNodeHeight(node);
            }
            return(top);
        }
        public override Vector2 GetTotalSize()
        {
            var   rows   = m_TreeView.data.GetRows();
            float height = 0f;

            for (int i = 0; i < rows.Count; i++)
            {
                AnimationWindowHierarchyNode node = rows[i] as AnimationWindowHierarchyNode;
                height += GetNodeHeight(node);
            }

            return(new Vector2(1, height));
        }
        public override Rect GetRowRect(int row, float rowWidth)
        {
            var rows = m_TreeView.data.GetRows();
            AnimationWindowHierarchyNode hierarchyNode = rows[row] as AnimationWindowHierarchyNode;

            if (hierarchyNode.topPixel == null)
            {
                hierarchyNode.topPixel = GetTopPixelOfRow(row, rows);
            }

            float rowHeight = GetNodeHeight(hierarchyNode);

            return(new Rect(0, (float)hierarchyNode.topPixel, rowWidth, rowHeight));
        }
        protected void DoNodeGUI(Rect rect, AnimationWindowHierarchyNode node, bool selected, bool focused, int row)
        {
            InitStyles();

            if (node is AnimationWindowHierarchyMasterNode)
            {
                return;
            }

            float indent = k_BaseIndent + (node.depth + node.indent) * k_IndentWidth;

            if (node is AnimationWindowHierarchyAddButtonNode)
            {
                if (Event.current.type == EventType.MouseMove && s_WasInsideValueRectFrame >= 0)
                {
                    if (s_WasInsideValueRectFrame >= Time.frameCount - 1)
                    {
                        Event.current.Use();
                    }
                    else
                    {
                        s_WasInsideValueRectFrame = -1;
                    }
                }

                using (new EditorGUI.DisabledScope(!state.selection.canAddCurves)) {
                    DoAddCurveButton(rect, node, row);
                }
            }
            else
            {
                DoRowBackground(rect, row);
                DoIconAndName(rect, node, selected, focused, indent);
                DoFoldout(node, rect, indent, row);

                bool enabled = false;
                if (node.curves != null)
                {
                    enabled = !Array.Exists(node.curves, curve => curve.animationIsEditable == false);
                }

                using (new EditorGUI.DisabledScope(!enabled)) {
                    DoValueField(rect, node, row);
                }
                DoCurveDropdown(rect, node, row, enabled);
                HandleContextMenu(rect, node, enabled);
                DoCurveColorIndicator(rect, node);
            }
            EditorGUIUtility.SetIconSize(Vector2.zero);
        }
        private void HandleContextMenu(Rect rect, AnimationWindowHierarchyNode node, bool enabled)
        {
            if (Event.current.type != EventType.ContextClick)
            {
                return;
            }

            if (rect.Contains(Event.current.mousePosition))
            {
                state.SelectHierarchyItem(node.id, true, true);
                //state.animationWindow.RefreshShownCurves (true);
                GenerateMenu(state.selectedHierarchyNodes, enabled).ShowAsContext();
                Event.current.Use();
            }
        }
        // Changing rotation interpolation will change the propertynames of the curves
        // Propertynames are used in treeview node IDs, so we need to anticipate the new IDs by injecting them into treeview state
        // This way treeview state (selection and expanding) will be preserved once the curve data is eventually reloaded
        private void MaintainTreeviewStateAfterRotationInterpolation(RotationCurveInterpolation.Mode newMode)
        {
            List <int> selectedInstaceIDs = state.hierarchyState.selectedIDs;
            List <int> expandedInstaceIDs = state.hierarchyState.expandedIDs;

            List <int> oldIDs = new List <int>();
            List <int> newIds = new List <int>();

            for (int i = 0; i < selectedInstaceIDs.Count; i++)
            {
                AnimationWindowHierarchyNode node = state.hierarchyData.FindItem(selectedInstaceIDs[i]) as AnimationWindowHierarchyNode;

                if (node != null && !node.propertyName.Equals(RotationCurveInterpolation.GetPrefixForInterpolation(newMode)))
                {
                    string oldPrefix       = node.propertyName.Split('.')[0];
                    string newPropertyName = node.propertyName.Replace(oldPrefix, RotationCurveInterpolation.GetPrefixForInterpolation(newMode));

                    // old treeview node id
                    oldIDs.Add(selectedInstaceIDs[i]);
                    // and its new replacement
                    newIds.Add((node.path + node.animatableObjectType.Name + newPropertyName).GetHashCode());
                }
            }

            // Replace old IDs with new ones
            for (int i = 0; i < oldIDs.Count; i++)
            {
                if (selectedInstaceIDs.Contains(oldIDs[i]))
                {
                    int index = selectedInstaceIDs.IndexOf(oldIDs[i]);
                    selectedInstaceIDs[index] = newIds[i];
                }
                if (expandedInstaceIDs.Contains(oldIDs[i]))
                {
                    int index = expandedInstaceIDs.IndexOf(oldIDs[i]);
                    expandedInstaceIDs[index] = newIds[i];
                }
                if (state.hierarchyState.lastClickedID == oldIDs[i])
                {
                    state.hierarchyState.lastClickedID = newIds[i];
                }
            }

            state.hierarchyState.selectedIDs = new List <int>(selectedInstaceIDs);
            state.hierarchyState.expandedIDs = new List <int>(expandedInstaceIDs);
        }
        override public bool BeginRename(TreeViewItem item, float delay)
        {
            m_RenamedNode = item as AnimationWindowHierarchyNode;

            GameObject rootGameObject = null;

            if (m_RenamedNode.curves.Length > 0)
            {
                AnimationWindowSelectionItem selectionBinding = m_RenamedNode.curves[0].selectionBinding;
                if (selectionBinding != null)
                {
                    rootGameObject = selectionBinding.rootGameObject;
                }
            }

            return(GetRenameOverlay().BeginRename(m_RenamedNode.path, item.id, delay));
        }
        private void DoCurveDropdown(Rect rect, AnimationWindowHierarchyNode node, int row, bool enabled)
        {
            rect = new Rect(
                rect.xMax - k_RowRightOffset - 12,
                rect.yMin + 2,
                22, 12);

            // case 767863.
            // This control id is unique to the hierarchy node it refers to.
            // The tree view only renders the elements that are visible, and will cause
            // the control id counter to shift when scrolling through the view.
            if (DoTreeViewButton(m_HierarchyItemButtonControlIDs[row], rect, GUIContent.none, m_AnimationCurveDropdown))
            {
                state.SelectHierarchyItem(node.id, false, false);
                GenericMenu menu = GenerateMenu(new AnimationWindowHierarchyNode[] { node }.ToList(), enabled);
                menu.DropDown(rect);
                Event.current.Use();
            }
        }
示例#13
0
        public List <AnimationWindowHierarchyNode> CreateTreeFromCurves()
        {
            List <AnimationWindowHierarchyNode> nodes = new List <AnimationWindowHierarchyNode>();
            List <AnimationWindowCurve>         singlePropertyCurves = new List <AnimationWindowCurve>();

            AnimationWindowCurve[]       curves     = state.allCurves.ToArray();
            AnimationWindowHierarchyNode parentNode = (AnimationWindowHierarchyNode)m_RootItem;

            for (int i = 0; i < curves.Length; i++)
            {
                AnimationWindowCurve curve = curves[i];

                if (!state.ShouldShowCurve(curve))
                {
                    continue;
                }

                AnimationWindowCurve nextCurve = i < curves.Length - 1 ? curves[i + 1] : null;

                singlePropertyCurves.Add(curve);

                bool areSameGroup       = nextCurve != null && AnimationWindowUtility.GetPropertyGroupName(nextCurve.propertyName) == AnimationWindowUtility.GetPropertyGroupName(curve.propertyName);
                bool areSamePathAndType = nextCurve != null && curve.path.Equals(nextCurve.path) && curve.type == nextCurve.type;

                // We expect curveBindings to come sorted by propertyname
                // So we compare curve vs nextCurve. If its different path or different group (think "scale.xyz" as group), then we know this is the last element of such group.
                if (i == curves.Length - 1 || !areSameGroup || !areSamePathAndType)
                {
                    if (singlePropertyCurves.Count > 1)
                    {
                        nodes.Add(AddPropertyGroupToHierarchy(singlePropertyCurves.ToArray(), parentNode));
                    }
                    else
                    {
                        nodes.Add(AddPropertyToHierarchy(singlePropertyCurves[0], parentNode));
                    }
                    singlePropertyCurves.Clear();
                }
            }

            return(nodes);
        }
        // Draw foldout (after text content above to ensure drop down icon is rendered above selection highlight)
        private void DoFoldout(AnimationWindowHierarchyNode node, Rect rect, float indent, int row)
        {
            if (m_TreeView.data.IsExpandable(node))
            {
                Rect toggleRect = rect;
                toggleRect.x     = indent;
                toggleRect.width = foldoutStyleWidth;
                EditorGUI.BeginChangeCheck();
                bool newExpandedValue = GUI.Toggle(toggleRect, m_HierarchyItemFoldControlIDs[row], m_TreeView.data.IsExpanded(node), GUIContent.none, foldoutStyle);
                if (EditorGUI.EndChangeCheck())
                {
                    if (Event.current.alt)
                    {
                        m_TreeView.data.SetExpandedWithChildren(node, newExpandedValue);
                    }
                    else
                    {
                        m_TreeView.data.SetExpanded(node, newExpandedValue);
                    }
                }
            }
            else
            {
                AnimationWindowHierarchyPropertyNode hierarchyPropertyNode = node as AnimationWindowHierarchyPropertyNode;
                AnimationWindowHierarchyState        hierarchyState        = m_TreeView.state as AnimationWindowHierarchyState;

                if (hierarchyPropertyNode != null && hierarchyPropertyNode.isPptrNode)
                {
                    Rect toggleRect = rect;
                    toggleRect.x     = indent;
                    toggleRect.width = foldoutStyleWidth;

                    EditorGUI.BeginChangeCheck();
                    bool tallMode = hierarchyState.GetTallMode(hierarchyPropertyNode);
                    tallMode = GUI.Toggle(toggleRect, m_HierarchyItemFoldControlIDs[row], tallMode, GUIContent.none, foldoutStyle);
                    if (EditorGUI.EndChangeCheck())
                    {
                        hierarchyState.SetTallMode(hierarchyPropertyNode, tallMode);
                    }
                }
            }
        }
        private void RemoveCurvesFromNodes(List <AnimationWindowHierarchyNode> nodes)
        {
            string undoLabel = "Remove Curve";

            state.SaveKeySelection(undoLabel);

            foreach (var node in nodes)
            {
                AnimationWindowHierarchyNode hierarchyNode = (AnimationWindowHierarchyNode)node;

                if (hierarchyNode.parent is AnimationWindowHierarchyPropertyGroupNode && hierarchyNode.binding != null && AnimationWindowUtility.ForceGrouping((EditorCurveBinding)hierarchyNode.binding))
                {
                    hierarchyNode = (AnimationWindowHierarchyNode)hierarchyNode.parent;
                }

                if (hierarchyNode.curves == null)
                {
                    continue;
                }

                List <AnimationWindowCurve> curves = null;

                // Property or propertygroup
                if (hierarchyNode is AnimationWindowHierarchyPropertyGroupNode || hierarchyNode is AnimationWindowHierarchyPropertyNode)
                {
                    curves = AnimationWindowUtility.FilterCurves(hierarchyNode.curves.ToArray(), hierarchyNode.path, hierarchyNode.animatableObjectType, hierarchyNode.propertyName);
                }
                else
                {
                    curves = AnimationWindowUtility.FilterCurves(hierarchyNode.curves.ToArray(), hierarchyNode.path, hierarchyNode.animatableObjectType);
                }

                foreach (AnimationWindowCurve animationWindowCurve in curves)
                {
                    state.RemoveCurve(animationWindowCurve, undoLabel);
                }
            }

            m_TreeView.ReloadData();

            state.controlInterface.ResampleAnimation();
        }
        private void DoCurveColorIndicator(Rect rect, AnimationWindowHierarchyNode node)
        {
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            Color originalColor = GUI.color;

            if (!state.showCurveEditor)
            {
                GUI.color = k_KeyColorInDopesheetMode;
            }
            else if (node.curves.Length == 1 && !node.curves[0].isPPtrCurve)
            {
                GUI.color = CurveUtility.GetPropertyColor(node.curves[0].binding.propertyName);
            }
            else
            {
                GUI.color = k_KeyColorForNonCurves;
            }

            bool hasKey = false;

            if (state.previewing)
            {
                foreach (var curve in node.curves)
                {
                    if (curve.m_Keyframes.Any(key => state.time.ContainsTime(key.time)))
                    {
                        hasKey = true;
                    }
                }
            }

            Texture icon = hasKey ? CurveUtility.GetIconKey() : CurveUtility.GetIconCurve();

            rect = new Rect(rect.xMax - k_RowRightOffset - (icon.width / 2) - 5, rect.yMin + k_ColorIndicatorTopMargin, icon.width, icon.height);
            GUI.DrawTexture(rect, icon, ScaleMode.ScaleToFit, true, 1);

            GUI.color = originalColor;
        }
        private void DoAddCurveButton(Rect rect, AnimationWindowHierarchyNode node, int row)
        {
            const int k_ButtonWidth = 230;
            float     xMargin       = (rect.width - k_ButtonWidth) / 2f;
            float     yMargin       = 10f;

            Rect rectWithMargin = new Rect(rect.xMin + xMargin, rect.yMin + yMargin, rect.width - xMargin * 2f, rect.height - yMargin * 2f);

            // case 767863.
            // This control id is unique to the hierarchy node it refers to.
            // The tree view only renders the elements that are visible, and will cause
            // the control id counter to shift when scrolling through the view.
            if (DoTreeViewButton(m_HierarchyItemButtonControlIDs[row], rectWithMargin, k_AnimatePropertyLabel, GUI.skin.button))
            {
                AddCurvesPopupHierarchyDataSource.showEntireHierarchy = true;

                if (AddCurvesPopup.ShowAtPosition(rectWithMargin, state, OnNewCurveAdded))
                {
                    GUIUtility.ExitGUI();
                }
            }
        }
示例#18
0
        private AnimationWindowHierarchyPropertyGroupNode AddPropertyGroupToHierarchy(AnimationWindowCurve[] curves, AnimationWindowHierarchyNode parentNode)
        {
            List <AnimationWindowHierarchyNode> childNodes = new List <AnimationWindowHierarchyNode>();

            System.Type animatableObjectType = curves[0].type;
            AnimationWindowHierarchyPropertyGroupNode node = new AnimationWindowHierarchyPropertyGroupNode(animatableObjectType, 0, AnimationWindowUtility.GetPropertyGroupName(curves[0].propertyName), curves[0].path, parentNode);

            node.icon = GetIcon(curves[0].binding);

            node.indent = curves[0].depth;
            node.curves = curves;

            foreach (AnimationWindowCurve curve in curves)
            {
                AnimationWindowHierarchyPropertyNode childNode = AddPropertyToHierarchy(curve, node);
                // For child nodes we do not want to display the type in front (It is already shown by the group node)
                childNode.displayName = AnimationWindowUtility.GetPropertyDisplayName(childNode.propertyName);
                childNodes.Add(childNode);
            }

            TreeViewUtility.SetChildParentReferences(new List <TreeViewItem>(childNodes.ToArray()), node);
            return(node);
        }
        public override void OnRowGUI(Rect rowRect, TreeViewItem node, int row, bool selected, bool focused)
        {
            AnimationWindowHierarchyNode hierarchyNode = node as AnimationWindowHierarchyNode;

            DoNodeGUI(rowRect, hierarchyNode, selected, focused, row);
        }
 public bool GetTallMode(AnimationWindowHierarchyNode node)
 {
     return(m_TallInstanceIDs.Contains(node.id));
 }
        private void DoIconAndName(Rect rect, AnimationWindowHierarchyNode node, bool selected, bool focused, float indent)
        {
            EditorGUIUtility.SetIconSize(new Vector2(13, 13));               // If not set we see icons scaling down if text is being cropped

            // TODO: All this is horrible. SHAME FIX!
            if (Event.current.type == EventType.Repaint)
            {
                if (selected)
                {
                    selectionStyle.Draw(rect, false, false, true, focused);
                }

                // Leave some space for the value field that comes after.
                if (node is AnimationWindowHierarchyPropertyNode)
                {
                    rect.width -= k_ValueFieldOffsetFromRightSide + 2;
                }

                bool isLeftOverCurve = AnimationWindowUtility.IsNodeLeftOverCurve(node);
                bool isAmbiguous     = AnimationWindowUtility.IsNodeAmbiguous(node);
                bool isPhantom       = AnimationWindowUtility.IsNodePhantom(node);

                string warningText = "";
                string tooltipText = "";
                if (isPhantom)
                {
                    warningText = " (Default Value)";
                    tooltipText = "Transform position, rotation and scale can't be partially animated. This value will be animated to the default value";
                }
                if (isLeftOverCurve)
                {
                    warningText = " (Missing!)";
                    tooltipText = "The GameObject or Component is missing (" + node.path + ")";
                }
                if (isAmbiguous)
                {
                    warningText = " (Duplicate GameObject name!)";
                    tooltipText = "Target for curve is ambiguous since there are multiple GameObjects with same name (" + node.path + ")";
                }

                Color oldColor  = lineStyle.normal.textColor;
                Color textColor = oldColor;
                if (node.depth == 0)
                {
                    string nodePrefix = "";
                    if (node.curves.Length > 0)
                    {
                        AnimationWindowSelectionItem selectionBinding = node.curves[0].selectionBinding;
                        string gameObjectName = GetGameObjectName(selectionBinding != null ? selectionBinding.rootGameObject : null, node.path);
                        nodePrefix = string.IsNullOrEmpty(gameObjectName) ? "" : gameObjectName + " : ";
                    }

                    Styles.content = new GUIContent(nodePrefix + node.displayName + warningText, GetIconForItem(node), tooltipText);

                    textColor = EditorGUIUtility.isProSkin ? Color.gray * 1.35f : Color.black;
                }
                else
                {
                    Styles.content = new GUIContent(node.displayName + warningText, GetIconForItem(node), tooltipText);

                    textColor = EditorGUIUtility.isProSkin ? Color.gray : m_LightSkinPropertyTextColor;

                    var phantomColor = selected ? m_PhantomCurveColor * k_SelectedPhantomCurveColorMultiplier : m_PhantomCurveColor;
                    textColor = isPhantom ? phantomColor : textColor;
                }
                textColor = isLeftOverCurve || isAmbiguous ? k_LeftoverCurveColor : textColor;
                SetStyleTextColor(lineStyle, textColor);

                rect.xMin += (int)(indent + foldoutStyleWidth + lineStyle.margin.left);
                GUI.Label(rect, Styles.content, lineStyle);

                SetStyleTextColor(lineStyle, oldColor);
            }

            if (IsRenaming(node.id) && Event.current.type != EventType.Layout)
            {
                GetRenameOverlay().editFieldRect = new Rect(rect.x + k_IndentWidth, rect.y, rect.width - k_IndentWidth - 1, rect.height);
            }
        }
        private void DoValueField(Rect rect, AnimationWindowHierarchyNode node, int row)
        {
            bool curvesChanged = false;

            if (node is AnimationWindowHierarchyPropertyNode)
            {
                AnimationWindowCurve[] curves = node.curves;
                if (curves == null || curves.Length == 0)
                {
                    return;
                }

                // We do valuefields for dopelines that only have single curve
                AnimationWindowCurve curve = curves[0];
                object objectValue         = CurveBindingUtility.GetCurrentValue(state, curve);

                if (objectValue is float)
                {
                    float value = (float)objectValue;

                    Rect valueFieldDragRect = new Rect(rect.xMax - k_ValueFieldOffsetFromRightSide - k_ValueFieldDragWidth, rect.y, k_ValueFieldDragWidth, rect.height);
                    Rect valueFieldRect     = new Rect(rect.xMax - k_ValueFieldOffsetFromRightSide, rect.y, k_ValueFieldWidth, rect.height);

                    if (Event.current.type == EventType.MouseMove && valueFieldRect.Contains(Event.current.mousePosition))
                    {
                        s_WasInsideValueRectFrame = Time.frameCount;
                    }

                    EditorGUI.BeginChangeCheck();

                    if (curve.valueType == typeof(bool))
                    {
                        value = GUI.Toggle(valueFieldRect, m_HierarchyItemValueControlIDs[row], value != 0, GUIContent.none, EditorStyles.toggle) ? 1 : 0;
                    }
                    else
                    {
                        int  id = m_HierarchyItemValueControlIDs[row];
                        bool enterInTextField = (EditorGUIUtility.keyboardControl == id &&
                                                 EditorGUIUtility.editingTextField &&
                                                 Event.current.type == EventType.KeyDown &&
                                                 (Event.current.character == '\n' || (int)Event.current.character == 3));

                        //  Force back keyboard focus to float field editor when editing it.
                        //  TreeView forces keyboard focus on itself at mouse down and we lose focus here.
                        if (EditorGUI.s_RecycledEditor.controlID == id && Event.current.type == EventType.MouseDown && valueFieldRect.Contains(Event.current.mousePosition))
                        {
                            GUIUtility.keyboardControl = id;
                        }

                        value = EditorGUI.DoFloatField(EditorGUI.s_RecycledEditor,
                                                       valueFieldRect,
                                                       valueFieldDragRect,
                                                       id,
                                                       value,
                                                       "g5",
                                                       m_AnimationSelectionTextField,
                                                       true);
                        if (enterInTextField)
                        {
                            GUI.changed = true;
                            Event.current.Use();
                        }
                    }

                    if (float.IsInfinity(value) || float.IsNaN(value))
                    {
                        value = 0;
                    }

                    if (EditorGUI.EndChangeCheck())
                    {
                        string undoLabel = "Edit Key";

                        AnimationKeyTime newAnimationKeyTime = AnimationKeyTime.Time(state.currentTime, curve.clip.frameRate);

                        AnimationWindowKeyframe existingKeyframe = null;
                        foreach (AnimationWindowKeyframe keyframe in curve.m_Keyframes)
                        {
                            if (Mathf.Approximately(keyframe.time, state.currentTime))
                            {
                                existingKeyframe = keyframe;
                            }
                        }

                        if (existingKeyframe == null)
                        {
                            AnimationWindowUtility.AddKeyframeToCurve(curve, value, curve.valueType, newAnimationKeyTime);
                        }
                        else
                        {
                            existingKeyframe.value = value;
                        }

                        state.SaveCurve(curve.clip, curve, undoLabel);
                        curvesChanged = true;
                    }
                }
            }

            if (curvesChanged)
            {
                state.ResampleAnimation();
            }
        }
示例#23
0
        private AnimationWindowHierarchyPropertyNode AddPropertyToHierarchy(AnimationWindowCurve curve, AnimationWindowHierarchyNode parentNode)
        {
            AnimationWindowHierarchyPropertyNode node = new AnimationWindowHierarchyPropertyNode(curve.type, 0, curve.propertyName, curve.path, parentNode, curve.binding, curve.isPPtrCurve);

            if (parentNode.icon != null)
            {
                node.icon = parentNode.icon;
            }
            else
            {
                node.icon = GetIcon(curve.binding);
            }

            node.indent = curve.depth;
            node.curves = new[] { curve };
            return(node);
        }