Beispiel #1
0
 public AnimationWindowHierarchyPropertyGroupNode(System.Type animatableObjectType, int setId, string propertyName, string path, TreeViewItem parent)
     : base(AnimationWindowUtility.GetPropertyNodeID(setId, path, animatableObjectType, propertyName), parent != null ? parent.depth + 1 : -1, parent, animatableObjectType, AnimationWindowUtility.GetPropertyGroupName(propertyName), path, AnimationWindowUtility.GetNicePropertyGroupDisplayName(animatableObjectType, propertyName))
 {
 }
 private void HandleHotKeys()
 {
     if (GUI.enabled && !this.m_State.disabled)
     {
         bool flag = false;
         if (AnimEditor.kAnimationPrevKeyframe.activated)
         {
             this.MoveToPreviousKeyframe();
             flag = true;
         }
         if (AnimEditor.kAnimationNextKeyframe.activated)
         {
             this.MoveToNextKeyframe();
             flag = true;
         }
         if (AnimEditor.kAnimationNextFrame.activated)
         {
             this.m_State.frame++;
             flag = true;
         }
         if (AnimEditor.kAnimationPrevFrame.activated)
         {
             this.m_State.frame--;
             flag = true;
         }
         if (AnimEditor.kAnimationFirstKey.activated)
         {
             this.MoveToFirstKeyframe();
             flag = true;
         }
         if (AnimEditor.kAnimationLastKey.activated)
         {
             this.MoveToLastKeyframe();
             flag = true;
         }
         if (flag)
         {
             Event.current.Use();
             this.Repaint();
         }
         if (AnimEditor.kAnimationPlayToggle.activated)
         {
             this.m_State.playing      = !this.m_State.playing;
             this.m_PreviousUpdateTime = Time.realtimeSinceStartup;
             Event.current.Use();
         }
         if (AnimEditor.kAnimationPlayToggle.activated)
         {
             this.m_State.playing      = !this.m_State.playing;
             this.m_PreviousUpdateTime = Time.realtimeSinceStartup;
             Event.current.Use();
         }
         if (AnimEditor.kAnimationRecordKeyframe.activated)
         {
             this.SaveCurveEditorKeySelection();
             AnimationKeyTime time = AnimationKeyTime.Time(this.m_State.currentTime, this.m_State.frameRate);
             AnimationWindowUtility.AddSelectedKeyframes(this.m_State, time);
             this.UpdateSelectedKeysToCurveEditor();
             Event.current.Use();
         }
     }
 }
Beispiel #3
0
        private void SetupWizardOnGUI(Rect position)
        {
            Rect position1 = new Rect(position.x, position.y, position.width - 15f, position.height - 15f);

            GUI.BeginClip(position1);
            GUI.enabled = true;
            this.m_State.showCurveEditor = false;
            this.m_State.timeArea        = (TimeArea)this.m_DopeSheet;
            this.m_State.timeArea.SetShownHRangeInsideMargins(0.0f, 1f);
            if ((bool)((UnityEngine.Object)Selection.activeGameObject) && !EditorUtility.IsPersistent((UnityEngine.Object)Selection.activeGameObject))
            {
                string     str       = (bool)((UnityEngine.Object) this.m_State.activeRootGameObject) || (bool)((UnityEngine.Object) this.m_State.activeAnimationClip) ? AnimationWindowStyles.animationClip.text : AnimationWindowStyles.animatorAndAnimationClip.text;
                GUIContent content   = GUIContent.Temp(string.Format(AnimationWindowStyles.formatIsMissing.text, (object)Selection.activeGameObject.name, (object)str));
                Vector2    vector2   = GUI.skin.label.CalcSize(content);
                Rect       position2 = new Rect((float)((double)position1.width * 0.5 - (double)vector2.x * 0.5), (float)((double)position1.height * 0.5 - (double)vector2.y * 0.5), vector2.x, vector2.y);
                GUI.Label(position2, content);
                if (GUI.Button(new Rect((float)((double)position1.width * 0.5 - 35.0), position2.yMax + 3f, 70f, 20f), AnimationWindowStyles.create) && AnimationWindowUtility.InitializeGameobjectForAnimation(Selection.activeGameObject))
                {
                    this.m_State.activeAnimationClip = AnimationUtility.GetAnimationClips(AnimationWindowUtility.GetClosestAnimationPlayerComponentInParents(Selection.activeGameObject.transform).gameObject)[0];
                    this.m_State.recording           = true;
                    this.m_State.currentTime         = 0.0f;
                    this.m_State.ResampleAnimation();
                }
            }
            else
            {
                Color color = GUI.color;
                GUI.color = Color.gray;
                Vector2 vector2 = GUI.skin.label.CalcSize(AnimationWindowStyles.noAnimatableObjectSelectedText);
                GUI.Label(new Rect((float)((double)position1.width * 0.5 - (double)vector2.x * 0.5), (float)((double)position1.height * 0.5 - (double)vector2.y * 0.5), vector2.x, vector2.y), AnimationWindowStyles.noAnimatableObjectSelectedText);
                GUI.color = color;
            }
            GUI.EndClip();
            GUI.enabled = false;
        }
        static bool IsRotationCurve(string propertyName)
        {
            string groupName = AnimationWindowUtility.GetPropertyGroupName(propertyName);

            return(groupName == kLocalRotation || groupName == kLocalEulerHint);
        }
        public override void GoToNextKeyframe()
        {
            var newTime = AnimationWindowUtility.GetNextKeyframeTime(GetCurves(), time.time, m_AnimWindowState.clipFrameRate);

            GoToTime(m_AnimWindowState.SnapToFrame(newTime, AnimationWindowState.SnapMode.SnapToClipFrame));
        }
        public override void GoToNextKeyframe()
        {
            float nextKeyframeTime = AnimationWindowUtility.GetNextKeyframeTime(this.GetCurves(), this.get_time().get_time(), this.m_AnimWindowState.get_clipFrameRate());

            this.GoToTime(this.m_AnimWindowState.SnapToFrame(nextKeyframeTime, 2));
        }
        private void FillInMissingTransformCurves(List <AnimationWindowCurve> transformCurves, ref List <AnimationWindowCurve> curvesCache)
        {
            EditorCurveBinding lastBinding = transformCurves[0].binding;
            var    propertyGroup           = new EditorCurveBinding?[3];
            string propertyGroupName;

            foreach (var transformCurve in transformCurves)
            {
                var transformBinding = transformCurve.binding;
                //if it's a new property group
                if (transformBinding.path != lastBinding.path ||
                    AnimationWindowUtility.GetPropertyGroupName(transformBinding.propertyName) != AnimationWindowUtility.GetPropertyGroupName(lastBinding.propertyName))
                {
                    propertyGroupName = AnimationWindowUtility.GetPropertyGroupName(lastBinding.propertyName);

                    FillPropertyGroup(ref propertyGroup, lastBinding, propertyGroupName, ref curvesCache);

                    lastBinding = transformBinding;

                    propertyGroup = new EditorCurveBinding?[3];
                }

                AssignBindingToRightSlot(transformBinding, ref propertyGroup);
            }
            FillPropertyGroup(ref propertyGroup, lastBinding, AnimationWindowUtility.GetPropertyGroupName(lastBinding.propertyName), ref curvesCache);
        }
Beispiel #8
0
 public AddCurvesPopupPropertyNode(TreeViewItem parent, EditorCurveBinding[] curveBindings)
     : base(curveBindings[0].GetHashCode(), parent.depth + 1, parent, AnimationWindowUtility.NicifyPropertyGroupName(curveBindings[0].type, AnimationWindowUtility.GetPropertyGroupName(curveBindings[0].propertyName)))
 {
     this.curveBindings = curveBindings;
 }
Beispiel #9
0
        private TreeViewItem AddGameObjectToHierarchy(GameObject gameObject, GameObject rootGameObject, AnimationClip animationClip, TreeViewItem parent)
        {
            string path = AnimationUtility.CalculateTransformPath(gameObject.transform, rootGameObject.transform);
            AddCurvesPopupGameObjectNode node       = new AddCurvesPopupGameObjectNode(gameObject, parent, gameObject.name);
            List <TreeViewItem>          childNodes = new List <TreeViewItem>();

            if (m_RootItem == null)
            {
                m_RootItem = node;
            }

            // Iterate over all animatable objects
            EditorCurveBinding[]      allCurveBindings     = AnimationUtility.GetAnimatableBindings(gameObject, rootGameObject);
            List <EditorCurveBinding> singleObjectBindings = new List <EditorCurveBinding>();

            for (int i = 0; i < allCurveBindings.Length; i++)
            {
                EditorCurveBinding curveBinding = allCurveBindings[i];

                singleObjectBindings.Add(curveBinding);

                // Don't create group for GameObject.m_IsActive. It looks messy
                if (curveBinding.propertyName == "m_IsActive")
                {
                    // Don't show for the root go
                    if (curveBinding.path != "")
                    {
                        TreeViewItem newNode = CreateNode(singleObjectBindings.ToArray(), node);
                        if (newNode != null)
                        {
                            childNodes.Add(newNode);
                        }
                        singleObjectBindings.Clear();
                    }
                    else
                    {
                        singleObjectBindings.Clear();
                    }
                }
                else
                {
                    // We expect allCurveBindings to come sorted by type

                    bool isLastItemOverall     = (i == allCurveBindings.Length - 1);
                    bool isLastItemOnThisGroup = false;

                    if (!isLastItemOverall)
                    {
                        isLastItemOnThisGroup = (allCurveBindings[i + 1].type != curveBinding.type);
                    }

                    // Let's not add those that already have a existing curve.
                    if (AnimationWindowUtility.IsCurveCreated(animationClip, curveBinding))
                    {
                        singleObjectBindings.Remove(curveBinding);
                    }

                    // Remove animator enabled property which shouldn't be animated.
                    if (curveBinding.type == typeof(Animator) && curveBinding.propertyName == "m_Enabled")
                    {
                        singleObjectBindings.Remove(curveBinding);
                    }

                    if ((isLastItemOverall || isLastItemOnThisGroup) && singleObjectBindings.Count > 0)
                    {
                        childNodes.Add(AddAnimatableObjectToHierarchy(singleObjectBindings.ToArray(), node, path));
                        singleObjectBindings.Clear();
                    }
                }
            }

            var animator = rootGameObject.GetComponent <Animator>();

            if (animator != null)
            {
                //If the Animator has a human avatar, we need to check if the avatar's hierarchy matches that of the current GameObject. If they do not match, disable the node.
                if (animator.avatarRoot != null && animator.isHuman)
                {
                    if (animator.avatarRoot.Find(path) == null)
                    {
                        node.disabled = true;
                    }
                }
            }


            if (showEntireHierarchy)
            {
                // Iterate over all child GOs
                for (int i = 0; i < gameObject.transform.childCount; i++)
                {
                    Transform    childTransform = gameObject.transform.GetChild(i);
                    TreeViewItem childNode      = AddGameObjectToHierarchy(childTransform.gameObject, rootGameObject, animationClip, node);
                    if (childNode != null)
                    {
                        childNodes.Add(childNode);
                    }
                }
            }

            TreeViewUtility.SetChildParentReferences(childNodes, node);
            return(node);
        }
Beispiel #10
0
        static void AddRotationKey(AnimationClip clip, EditorCurveBinding sourceBind, SerializedProperty prop, double time)
        {
            if (prop.propertyType != SerializedPropertyType.Quaternion)
            {
                return;
            }

            var updateCurves   = new List <AnimationCurve>();
            var updateBindings = new List <EditorCurveBinding>();

            var info = AnimationClipCurveCache.Instance.GetCurveInfo(clip);

            for (var i = 0; i < info.bindings.Length; i++)
            {
                if (sourceBind.type != info.bindings[i].type)
                {
                    continue;
                }

                if (info.bindings[i].propertyName.Contains("localEuler"))
                {
                    updateBindings.Add(info.bindings[i]);
                    updateCurves.Add(info.curves[i]);
                }
            }

            // use this instead of serialized properties because the editor will attempt to maintain
            // correct localeulers
            var eulers = ((Transform)prop.serializedObject.targetObject).localEulerAngles;

            if (updateBindings.Count == 0)
            {
                var propName = AnimationWindowUtility.GetPropertyGroupName(sourceBind.propertyName);
                updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".x"));
                updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".y"));
                updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".z"));

                var curveX = new AnimationCurve();
                var curveY = new AnimationCurve();
                var curveZ = new AnimationCurve();
                AddKeyFrameToCurve(curveX, (float)time, clip.frameRate, eulers.x, false);
                AddKeyFrameToCurve(curveY, (float)time, clip.frameRate, eulers.y, false);
                AddKeyFrameToCurve(curveZ, (float)time, clip.frameRate, eulers.z, false);

                updateCurves.Add(curveX);
                updateCurves.Add(curveY);
                updateCurves.Add(curveZ);
            }

            for (var i = 0; i < updateBindings.Count; i++)
            {
                var c     = updateBindings[i].propertyName.Last();
                var value = eulers.x;
                if (c == 'y')
                {
                    value = eulers.y;
                }
                else if (c == 'z')
                {
                    value = eulers.z;
                }
                AddKeyFrameToCurve(updateCurves[i], (float)time, clip.frameRate, value, false);
            }

            UpdateEditorCurves(clip, updateBindings, updateCurves);
        }
Beispiel #11
0
        private TreeViewItem AddAnimatableObjectToHierarchy(EditorCurveBinding[] curveBindings, TreeViewItem parentNode, string path)
        {
            TreeViewItem node = new AddCurvesPopupObjectNode(parentNode, path, GetClassName(curveBindings[0]));

            node.icon = GetIcon(curveBindings[0]);

            List <TreeViewItem>       childNodes             = new List <TreeViewItem>();
            List <EditorCurveBinding> singlePropertyBindings = new List <EditorCurveBinding>();

            for (int i = 0; i < curveBindings.Length; i++)
            {
                EditorCurveBinding curveBinding = curveBindings[i];

                singlePropertyBindings.Add(curveBinding);

                // We expect curveBindings to come sorted by propertyname
                if (i == curveBindings.Length - 1 || AnimationWindowUtility.GetPropertyGroupName(curveBindings[i + 1].propertyName) != AnimationWindowUtility.GetPropertyGroupName(curveBinding.propertyName))
                {
                    TreeViewItem newNode = CreateNode(singlePropertyBindings.ToArray(), node);
                    if (newNode != null)
                    {
                        childNodes.Add(newNode);
                    }
                    singlePropertyBindings.Clear();
                }
            }

            childNodes.Sort();

            TreeViewUtility.SetChildParentReferences(childNodes, node);
            return(node);
        }
Beispiel #12
0
        // Add a floating point curve key
        static void AddFloatKey(AnimationClip clip, EditorCurveBinding sourceBind, SerializedProperty prop, double time)
        {
            var updateCurves   = new List <AnimationCurve>();
            var updateBindings = new List <EditorCurveBinding>();

            var updated = false;
            var info    = AnimationClipCurveCache.Instance.GetCurveInfo(clip);

            for (var i = 0; i < info.bindings.Length; i++)
            {
                var binding = info.bindings[i];
                if (binding.type != sourceBind.type)
                {
                    continue;
                }

                SerializedProperty valProp = null;
                var curve = info.curves[i];

                // perfect match on property path, editting a float
                if (prop.propertyPath.Equals(binding.propertyName))
                {
                    valProp = prop;
                }
                // this is a child object
                else if (binding.propertyName.Contains(prop.propertyPath))
                {
                    valProp = prop.serializedObject.FindProperty(binding.propertyName);
                }

                if (valProp != null)
                {
                    var value = GetKeyValue(valProp);
                    if (!float.IsNaN(value)) // Nan indicates an error retrieving the property value
                    {
                        updated = true;
                        AddKeyFrameToCurve(curve, (float)time, clip.frameRate, value, valProp.propertyType == SerializedPropertyType.Boolean);
                        updateCurves.Add(curve);
                        updateBindings.Add(binding);
                    }
                }
            }

            // Curves don't exist, add them
            if (!updated)
            {
                var propName = AnimationWindowUtility.GetPropertyGroupName(sourceBind.propertyName);
                if (!prop.hasChildren)
                {
                    var value = GetKeyValue(prop);
                    if (!float.IsNaN(value))
                    {
                        updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, sourceBind.propertyName));
                        var curve = new AnimationCurve();
                        AddKeyFrameToCurve(curve, (float)time, clip.frameRate, value, prop.propertyType == SerializedPropertyType.Boolean);
                        updateCurves.Add(curve);
                    }
                }
                else
                {
                    // special case because subproperties on color aren't 'visible' so you can't iterate over them
                    if (prop.propertyType == SerializedPropertyType.Color)
                    {
                        updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".r"));
                        updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".g"));
                        updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".b"));
                        updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".a"));

                        var c = prop.colorValue;
                        for (var i = 0; i < 4; i++)
                        {
                            var curve = new AnimationCurve();
                            AddKeyFrameToCurve(curve, (float)time, clip.frameRate, c[i], prop.propertyType == SerializedPropertyType.Boolean);
                            updateCurves.Add(curve);
                        }
                    }
                    else
                    {
                        prop = prop.Copy();
                        foreach (SerializedProperty cp in prop)
                        {
                            updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, cp.propertyPath));
                            var curve = new AnimationCurve();
                            AddKeyFrameToCurve(curve, (float)time, clip.frameRate, GetKeyValue(cp), cp.propertyType == SerializedPropertyType.Boolean);
                            updateCurves.Add(curve);
                        }
                    }
                }
            }

            UpdateEditorCurves(clip, updateBindings, updateCurves);
        }
Beispiel #13
0
        public override void OnInspectorGUI()
        {
            bool isEditingMultipleObjects = targets.Length > 1;

            bool cullingModeChanged = false;
            bool updateModeChanged  = false;

            Animator firstAnimator = target as Animator;

            serializedObject.UpdateIfRequiredOrScript();

            UpdateShowOptions();

            EditorGUI.BeginChangeCheck();
            var controller = EditorGUILayout.ObjectField("Controller", firstAnimator.runtimeAnimatorController, typeof(RuntimeAnimatorController), false) as RuntimeAnimatorController;

            if (EditorGUI.EndChangeCheck())
            {
                foreach (Animator animator in targets)
                {
                    Undo.RecordObject(animator, "Changed AnimatorController");
                    animator.runtimeAnimatorController = controller;
                }
                AnimationWindowUtility.ControllerChanged();
            }

            EditorGUILayout.PropertyField(m_Avatar);
            if (firstAnimator.supportsOnAnimatorMove && !isEditingMultipleObjects)
            {
                EditorGUILayout.LabelField("Apply Root Motion", "Handled by Script");
            }
            else
            {
                EditorGUILayout.PropertyField(m_ApplyRootMotion, styles.applyRootMotion);

                // This might change between layout & repaint so we have local cached value to only update on layout
                if (Event.current.type == EventType.Layout)
                {
                    m_IsRootPositionOrRotationControlledByCurves = firstAnimator.isRootPositionOrRotationControlledByCurves;
                }

                if (!m_ApplyRootMotion.boolValue && m_IsRootPositionOrRotationControlledByCurves)
                {
                    EditorGUILayout.HelpBox("Root position or rotation are controlled by curves", MessageType.Info, true);
                }
            }

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(m_UpdateMode, styles.updateMode);
            updateModeChanged = EditorGUI.EndChangeCheck();


            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(m_CullingMode, styles.cullingMode);
            cullingModeChanged = EditorGUI.EndChangeCheck();


            if (!isEditingMultipleObjects)
            {
                EditorGUILayout.HelpBox(firstAnimator.GetStats(), MessageType.Info, true);
            }

            if (EditorGUILayout.BeginFadeGroup(m_ShowWarningMessage.faded))
            {
                EditorGUILayout.HelpBox(WarningMessage, MessageType.Warning, true);
            }
            EditorGUILayout.EndFadeGroup();


            serializedObject.ApplyModifiedProperties();

            foreach (Animator animator in targets)
            {
                if (cullingModeChanged)
                {
                    animator.OnCullingModeChanged();
                }

                if (updateModeChanged)
                {
                    animator.OnUpdateModeChanged();
                }
            }
        }
Beispiel #14
0
 public AnimationWindowHierarchyPropertyNode(System.Type animatableObjectType, int setId, string propertyName, string path, TreeViewItem parent, EditorCurveBinding binding, bool isPptrNode)
     : base(AnimationWindowUtility.GetPropertyNodeID(setId, path, animatableObjectType, propertyName), parent != null ? parent.depth + 1 : -1, parent, animatableObjectType, propertyName, path, AnimationWindowUtility.GetNicePropertyDisplayName(animatableObjectType, propertyName))
 {
     this.binding    = binding;
     this.isPptrNode = isPptrNode;
 }
 private void DeleteKeysAtCurrentTime(List <AnimationWindowCurve> curves)
 {
     AnimationWindowUtility.RemoveKeyframes(state, curves, state.time);
 }
Beispiel #16
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);
        }
        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();
        }
Beispiel #18
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);
        }
        private void HandleHotKeys()
        {
            if (!GUI.enabled || m_State.disabled)
            {
                return;
            }

            bool keyChanged = false;

            if (kAnimationPrevKeyframe.activated)
            {
                controlInterface.GoToPreviousKeyframe();
                keyChanged = true;
            }

            if (kAnimationNextKeyframe.activated)
            {
                controlInterface.GoToNextKeyframe();
                keyChanged = true;
            }

            if (kAnimationNextFrame.activated)
            {
                controlInterface.GoToNextFrame();
                keyChanged = true;
            }

            if (kAnimationPrevFrame.activated)
            {
                controlInterface.GoToPreviousFrame();
                keyChanged = true;
            }

            if (kAnimationFirstKey.activated)
            {
                controlInterface.GoToFirstKeyframe();
                keyChanged = true;
            }

            if (kAnimationLastKey.activated)
            {
                controlInterface.GoToLastKeyframe();
                keyChanged = true;
            }

            if (keyChanged)
            {
                Event.current.Use();
                Repaint();
            }

            if (kAnimationPlayToggle.activated)
            {
                if (controlInterface.playing)
                {
                    controlInterface.StopPlayback();
                }
                else
                {
                    controlInterface.StartPlayback();
                }

                Event.current.Use();
            }

            if (kAnimationRecordKeyframeSelected.activated)
            {
                SaveCurveEditorKeySelection();
                AnimationWindowUtility.AddSelectedKeyframes(m_State, controlInterface.time);
                UpdateSelectedKeysToCurveEditor();

                Event.current.Use();
            }

            if (kAnimationRecordKeyframeModified.activated)
            {
                SaveCurveEditorKeySelection();
                controlInterface.ProcessCandidates();
                UpdateSelectedKeysToCurveEditor();

                Event.current.Use();
            }
        }
Beispiel #20
0
        private static bool CreateAnimation(GameObject gameObject, UnityEngine.Object[] frames, SpriteUtility.ShowFileDialogDelegate saveFileDialog)
        {
            SpriteUtility.ShowFileDialogDelegate arg_26_0;
            if ((arg_26_0 = saveFileDialog) == null)
            {
                if (SpriteUtility.< > f__mg$cache1 == null)
                {
                    SpriteUtility.< > f__mg$cache1 = new SpriteUtility.ShowFileDialogDelegate(EditorUtility.SaveFilePanelInProject);
                }
                arg_26_0 = SpriteUtility.< > f__mg$cache1;
            }
            saveFileDialog = arg_26_0;
            Array.Sort <UnityEngine.Object>(frames, (UnityEngine.Object a, UnityEngine.Object b) => EditorUtility.NaturalCompare(a.name, b.name));
            Animator animator = (!AnimationWindowUtility.EnsureActiveAnimationPlayer(gameObject)) ? null : AnimationWindowUtility.GetClosestAnimatorInParents(gameObject.transform);
            bool     flag     = animator != null;
            bool     result;

            if (animator != null)
            {
                string message          = string.Format("Create a new animation for the game object '{0}':", gameObject.name);
                string activeFolderPath = ProjectWindowUtil.GetActiveFolderPath();
                string text             = saveFileDialog("Create New Animation", "New Animation", "anim", message, activeFolderPath);
                if (string.IsNullOrEmpty(text))
                {
                    UnityEngine.Object.DestroyImmediate(animator);
                    result = false;
                    return(result);
                }
                AnimationClip animationClip = AnimationWindowUtility.CreateNewClipAtPath(text);
                if (animationClip != null)
                {
                    SpriteUtility.AddSpriteAnimationToClip(animationClip, frames);
                    flag = AnimationWindowUtility.AddClipToAnimatorComponent(animator, animationClip);
                }
            }
            if (!flag)
            {
                Debug.LogError("Failed to create animation for dragged object");
            }
            result = flag;
            return(result);
        }
 public void SaveCurve(AnimationWindowCurve curve)
 {
     Undo.RegisterCompleteObjectUndo(activeAnimationClip, L10n.Tr("Edit Curve"));
     AnimationWindowUtility.SaveCurve(activeAnimationClip, curve);
 }
 static bool DoesPropertyPathMatch(string a, string b)
 {
     return(AnimationWindowUtility.GetPropertyGroupName(a).Equals(AnimationWindowUtility.GetPropertyGroupName(a)));
 }
 public static bool DoesPropertyPathMatch(string a, string b)
 {
     return(AnimationWindowUtility.GetPropertyGroupName(a).Equals(AnimationWindowUtility.GetPropertyGroupName(b)) || IsRotationCurve(a) && IsRotationCurve(b));
 }
        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);
            }
        }
 // identifier to generate an id thats the same for all curves in the same group
 public static string GetGroupID(this EditorCurveBinding binding)
 {
     return(binding.type + AnimationWindowUtility.GetPropertyGroupName(binding.propertyName));
 }
        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();
            }
        }
Beispiel #27
0
        private void RenderClipOverlay(Rect rect)
        {
            Vector2 timeRange = this.m_State.timeRange;

            AnimationWindowUtility.DrawRangeOfClip(rect, this.m_State.TimeToPixel(timeRange.x) + rect.xMin, this.m_State.TimeToPixel(timeRange.y) + rect.xMin);
        }
        private GenericMenu GenerateMenu(List <AnimationWindowHierarchyNode> interactedNodes, bool enabled)
        {
            List <AnimationWindowCurve> curves = GetCurvesAffectedByNodes(interactedNodes, false);
            // Linked curves are like regular affected curves but always include transform siblings
            List <AnimationWindowCurve> linkedCurves = GetCurvesAffectedByNodes(interactedNodes, true);

            bool forceGroupRemove = curves.Count == 1 ? AnimationWindowUtility.ForceGrouping(curves[0].binding) : false;

            GenericMenu menu = new GenericMenu();

            // Remove curves
            GUIContent removePropertyContent = new GUIContent(curves.Count > 1 || forceGroupRemove ? "Remove Properties" : "Remove Property");

            if (!enabled)
            {
                menu.AddDisabledItem(removePropertyContent);
            }
            else
            {
                menu.AddItem(removePropertyContent, false, RemoveCurvesFromSelectedNodes);
            }

            // Change rotation interpolation
            bool showInterpolation = true;

            EditorCurveBinding[] curveBindings = new EditorCurveBinding[linkedCurves.Count];
            for (int i = 0; i < linkedCurves.Count; i++)
            {
                curveBindings[i] = linkedCurves[i].binding;
            }
            RotationCurveInterpolation.Mode rotationInterpolation = GetRotationInterpolationMode(curveBindings);
            if (rotationInterpolation == RotationCurveInterpolation.Mode.Undefined)
            {
                showInterpolation = false;
            }
            else
            {
                foreach (var node in interactedNodes)
                {
                    if (!(node is AnimationWindowHierarchyPropertyGroupNode))
                    {
                        showInterpolation = false;
                    }
                }
            }
            if (showInterpolation)
            {
                string legacyWarning = state.activeAnimationClip.legacy ? " (Not fully supported in Legacy)" : "";
                GenericMenu.MenuFunction2 nullMenuFunction2 = null;
                menu.AddItem(EditorGUIUtility.TrTextContent("Interpolation/Euler Angles" + legacyWarning), rotationInterpolation == RotationCurveInterpolation.Mode.RawEuler, enabled ? ChangeRotationInterpolation : nullMenuFunction2, RotationCurveInterpolation.Mode.RawEuler);
                menu.AddItem(EditorGUIUtility.TrTextContent("Interpolation/Euler Angles (Quaternion)"), rotationInterpolation == RotationCurveInterpolation.Mode.Baked, enabled ? ChangeRotationInterpolation : nullMenuFunction2, RotationCurveInterpolation.Mode.Baked);
                menu.AddItem(EditorGUIUtility.TrTextContent("Interpolation/Quaternion"), rotationInterpolation == RotationCurveInterpolation.Mode.NonBaked, enabled ? ChangeRotationInterpolation : nullMenuFunction2, RotationCurveInterpolation.Mode.NonBaked);
            }

            // Menu items that are only applicaple when in animation mode:
            if (state.previewing)
            {
                menu.AddSeparator("");

                bool allHaveKeys  = true;
                bool noneHaveKeys = true;
                foreach (AnimationWindowCurve curve in curves)
                {
                    bool curveHasKey = curve.HasKeyframe(state.time);
                    if (!curveHasKey)
                    {
                        allHaveKeys = false;
                    }
                    else
                    {
                        noneHaveKeys = false;
                    }
                }

                string str;

                str = "Add Key";
                if (allHaveKeys || !enabled)
                {
                    menu.AddDisabledItem(new GUIContent(str));
                }
                else
                {
                    menu.AddItem(new GUIContent(str), false, AddKeysAtCurrentTime, curves);
                }

                str = "Delete Key";
                if (noneHaveKeys || !enabled)
                {
                    menu.AddDisabledItem(new GUIContent(str));
                }
                else
                {
                    menu.AddItem(new GUIContent(str), false, DeleteKeysAtCurrentTime, curves);
                }
            }

            return(menu);
        }
Beispiel #29
0
 private void MoveToNextKeyframe()
 {
     this.m_State.currentTime = AnimationWindowUtility.GetNextKeyframeTime((!this.m_State.showCurveEditor ? this.m_State.allCurves : this.m_State.activeCurves).ToArray(), this.m_State.FrameToTime((float)this.m_State.frame), this.m_State.frameRate);
     this.m_State.frame       = this.m_State.TimeToFrameFloor(this.m_State.currentTime);
 }
        public override void OnInspectorGUI()
        {
            bool     flag     = base.targets.Length > 1;
            Animator animator = base.target as Animator;

            base.serializedObject.UpdateIfDirtyOrScript();
            this.UpdateShowOptions();
            EditorGUI.BeginChangeCheck();
            RuntimeAnimatorController runtimeAnimatorController = EditorGUILayout.ObjectField("Controller", animator.runtimeAnimatorController, typeof(RuntimeAnimatorController), false, new GUILayoutOption[0]) as RuntimeAnimatorController;

            if (EditorGUI.EndChangeCheck())
            {
                UnityEngine.Object[] targets = base.targets;
                for (int i = 0; i < targets.Length; i++)
                {
                    Animator animator2 = (Animator)targets[i];
                    Undo.RecordObject(animator2, "Changed AnimatorController");
                    animator2.runtimeAnimatorController = runtimeAnimatorController;
                }
                AnimationWindowUtility.ControllerChanged();
            }
            EditorGUILayout.PropertyField(this.m_Avatar, new GUILayoutOption[0]);
            if (animator.supportsOnAnimatorMove && !flag)
            {
                EditorGUILayout.LabelField("Apply Root Motion", "Handled by Script", new GUILayoutOption[0]);
            }
            else
            {
                EditorGUILayout.PropertyField(this.m_ApplyRootMotion, AnimatorInspector.styles.applyRootMotion, new GUILayoutOption[0]);
                if (Event.current.type == EventType.Layout)
                {
                    this.m_IsRootPositionOrRotationControlledByCurves = animator.isRootPositionOrRotationControlledByCurves;
                }
                if (!this.m_ApplyRootMotion.boolValue && this.m_IsRootPositionOrRotationControlledByCurves)
                {
                    EditorGUILayout.HelpBox("Root position or rotation are controlled by curves", MessageType.Info, true);
                }
            }
            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(this.m_UpdateMode, AnimatorInspector.styles.updateMode, new GUILayoutOption[0]);
            bool flag2 = EditorGUI.EndChangeCheck();

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(this.m_CullingMode, AnimatorInspector.styles.cullingMode, new GUILayoutOption[0]);
            bool flag3 = EditorGUI.EndChangeCheck();

            if (!flag)
            {
                EditorGUILayout.HelpBox(animator.GetStats(), MessageType.Info, true);
            }
            if (EditorGUILayout.BeginFadeGroup(this.m_ShowWarningMessage.faded))
            {
                EditorGUILayout.HelpBox(this.WarningMessage, MessageType.Warning, true);
            }
            EditorGUILayout.EndFadeGroup();
            base.serializedObject.ApplyModifiedProperties();
            UnityEngine.Object[] targets2 = base.targets;
            for (int j = 0; j < targets2.Length; j++)
            {
                Animator animator3 = (Animator)targets2[j];
                if (flag3)
                {
                    animator3.OnCullingModeChanged();
                }
                if (flag2)
                {
                    animator3.OnUpdateModeChanged();
                }
            }
        }