private static void MoveKey(EditorCurveBinding binding, AnimationClip clip, int keyframeInx, float time)
        {
            AnimationCurve curve;


            if (binding.isPPtrCurve)
            {
                ObjectReferenceKeyframe[] keyframesCurveReferenced = AnimationUtility.GetObjectReferenceCurve(clip, binding);

                if (keyframesCurveReferenced != null && keyframesCurveReferenced.Length > keyframeInx)
                {
                    keyframesCurveReferenced [keyframeInx].time = time;

                    AnimationUtility.SetObjectReferenceCurve(clip, binding, keyframesCurveReferenced);
                }
            }
            else
            {
                curve = AnimationUtility.GetEditorCurve(clip, binding);

                if (curve != null)
                {
                    Keyframe key = curve.keys [keyframeInx];
                    key.time = time;
                    curve.MoveKey(keyframeInx, key);

                    AnimationModeUtility.SaveCurve(curve, clip, binding);
                }
            }
        }
        /// <summary>
        /// Adds the keyframe to clip at time based of current values of root GameObject.
        /// <param name="curveBindingCurrent">Curve binding current.</param>
        /// </summary>
        /// <param name="root">Root.</param>
        /// <param name="clip">Clip.</param>
        /// <param name="time">Time.</param>
        public static void AddKeyframeTo(EditorCurveBinding binding, GameObject root, AnimationClip clip, float time)
        {
            object valueCurrent = AnimationModeUtility.GetCurrentValue(root, binding);

            //if property is "m_LocalRotation.y" create "m_LocalRotation.x" "m_LocalRotation.z" and "m_LocalRotation.w"
            EditorCurveBinding[] array = RotationCurveInterpolationW.RemapAnimationBindingForAddKey(binding, clip);
            if (array != null)
            {
                for (int j = 0; j < array.Length; j++)
                {
                    AddKey(array [j], root, clip, valueCurrent, time);
                }
            }
            else
            {
                AddKey(binding, root, clip, valueCurrent, time);
            }
        }
        /// <summary>
        /// Removes the keyframe from clip (!!! Inserts hidden keyframes in between)
        /// </summary>
        /// <param name="clip">Clip.</param>
        /// <param name="keyframeInx">Keyframe inx.</param>
        public static void RemoveKeyframeFrom(AnimationClip clip, EditorCurveBinding binding, int keyframeInx)
        {
            if (keyframeInx < 0)
            {
                Debug.LogWarning("Try to remove keyframe at index " + keyframeInx + " from prop:" + binding.propertyName + " from " + clip.name);
                return;
            }

            EditorCurveBinding[] curveBindings = RotationCurveInterpolationW.RemapAnimationBindingForAddKey(binding, clip);
            AnimationCurve       curve;



            EditorCurveBinding curveBindingCurrent;

            if (curveBindings != null)
            {
                int curveBindingsNum = curveBindings.Length;

                for (int i = 0; i < curveBindingsNum; i++)
                {
                    curveBindingCurrent = curveBindings [i];
                    curve = AnimationUtility.GetEditorCurve(clip, curveBindingCurrent);

                    if (curve != null && curve.length > keyframeInx)
                    {
                        curve.RemoveKey(keyframeInx);

                        AnimationModeUtility.SaveCurve(curve, clip, curveBindingCurrent);
                    }
                }
            }
            else
            {
                curve = AnimationUtility.GetEditorCurve(clip, binding);

                if (curve != null && curve.length > keyframeInx)
                {
                    curve.RemoveKey(keyframeInx);

                    AnimationModeUtility.SaveCurve(curve, clip, binding);
                }
            }
        }
Beispiel #4
0
//				// Custom Gizmos, Create as many as you'd like
//				[DrawGizmo(GizmoType.NotSelected | GizmoType.Selected)]
//				private static void DrawGizmo (Transform aTarget, GizmoType aGizmoType)
//				{
//
//						if (__gameObjectClipList == null)
//								return;
//
//						int gameObjectCount = __gameObjectClipList.count;
//
//						Vector3[] gameObjectPositionsInTime = null;
//						Vector3 cubeSize = new Vector3 (0.1f, 0.1f, 0.1f);
//						AnimationClip clip = null;
//						Color clr = Color.green;
//
//						for (int i=0; i<gameObjectCount; i++) {
//
//								clip = (__gameObjectClipList.list [i] as EditorClipBinding).clip;
//
//								if (clip != null) {
//										gameObjectPositionsInTime = AnimationUtilityEx.GetPositions (clip);
//
//										clr = Gizmos.color;
//
//
//										Gizmos.color = Color.green;
//
//										for (int j=0; j<gameObjectPositionsInTime.Length; j++)
//												Gizmos.DrawCube (gameObjectPositionsInTime [j], cubeSize);
//
//										Gizmos.color = clr;
//
//								}
//						}
//				}


        /// <summary>
        /// Postprocesses the animation recording and property modifications.
        /// </summary>
        /// <returns>The animation recording modifications.</returns>
        /// <param name="modifications">Modifications.</param>
        private static UndoPropertyModification[] PostprocessAnimationRecordingModifications(UndoPropertyModification[] modifications)
        {
            List <UndoPropertyModification> propertyModificationList = new List <UndoPropertyModification> ();

            EditorClipBinding[] clipBindings = clipBindingsSerialized.value as EditorClipBinding[];

            List <EditorClipBinding> list = clipBindings.ToList();

            list.Add(__mecanimNodeClipBinding);

            list.ForEach((itm) => {
                if (itm.gameObject != null && itm.clip != null)
                {
                    propertyModificationList.Concat(AnimationModeUtility.Process(itm.gameObject, itm.clip, modifications, __timeCurrent));
                }
            });


            return(propertyModificationList.ToArray());
        }
Beispiel #5
0
        void OnGUI()
        {
            if (__binding != default(EditorCurveBinding))
            {
                if (__curveEditor == null)
                {
                    CurveWrapperW[] curveWrappers;

                    __bindings = RotationCurveInterpolationW.RemapAnimationBindingForAddKey(__binding, __clip);


                    CurveWrapperW      curveWrapperNew;
                    Color              curveColor       = Color.red;
                    int                curveBindingsNum = 0;
                    EditorCurveBinding curveBindingCurrent;
                    if (__bindings != null)
                    {
                        curveBindingsNum = __bindings.Length;
                        __curves         = new AnimationCurve[curveBindingsNum];
                        curveWrappers    = new CurveWrapperW[curveBindingsNum];
                        for (int i = 0; i < curveBindingsNum; i++)
                        {
                            curveBindingCurrent = __bindings [i];
                            __curves [i]        = AnimationUtility.GetEditorCurve(__clip, curveBindingCurrent);

                            curveWrapperNew       = new CurveWrapperW();
                            curveWrapperNew.curve = __curves [i];
                            if (i == 1)
                            {
                                curveColor = Color.green;
                            }
                            else if (i == 2)
                            {
                                curveColor = Color.blue;
                            }

                            curveWrapperNew.color = curveColor;
                            curveWrappers [i]     = curveWrapperNew;
                        }
                    }
                    else
                    {
                        __bindings    = new EditorCurveBinding[] { __binding };
                        __curves      = new AnimationCurve[1];
                        __curves [0]  = AnimationUtility.GetEditorCurve(__clip, __binding);
                        curveWrappers = new CurveWrapperW[1];

                        curveWrapperNew       = new CurveWrapperW();
                        curveWrapperNew.curve = __curves [0];


                        curveWrapperNew.color = curveColor;
                        curveWrappers [0]     = curveWrapperNew;
                    }



                    //This makes layout to work (Reserving space)
                    __curveEditorRect = new Rect(0, 0, Screen.width, Screen.height);
                    //GUILayoutUtility.GetRect (Screen.width - 16f, 200);

                    __curveEditor = new CurveEditorW(__curveEditorRect, curveWrappers, false);

                    __curveEditor.FrameSelected(false, true);                                                             //scale y auto
                    __curveEditor.scaleWithWindow = true;
                    __curveEditor.hSlider         = false;
                    __curveEditor.vSlider         = false;

                    __curveEditor.hRangeMin    = __curves [0].keys [0].time;
                    __curveEditor.hRangeMax    = __clip.length;                                                               // __curves [0].keys [__curves [0].length - 1].time;
                    __curveEditor.hRangeLocked = true;
                    __curveEditor.Scale        = new Vector2(__window.position.width / __clip.length, __curveEditor.Scale.y); //scale x manually
                    __curveEditor.leftmargin   = 0f;

                    __curveEditor.rightmargin = 0;                                                            // __window.position.width - __curveEditor.hRangeMax * __clip.length / __window.position.width;


                    //__curveEditor.onSelect += onCurveSelect;
                }
                else
                {
                    __curveEditorRect  = new Rect(0, 0, Screen.width, Screen.height);
                    __curveEditor.rect = __curveEditorRect;
                    //__curveEditor.Scale=new Vector2(237,__curveEditor.Scale.y);
                    //__curveEditor.FrameSelected (false, false);
                }


                //if(Event.current.type==EventType.MouseMove || Event.current.type==EventType.ScrollWheel && !__window.position.Contains(Event.current.mousePosition))
                //this.Close();

                //EditorGUI.BeginChangeCheck ();

//								if (Event.current.type == EventType.MouseMove && !__window.position.Contains (Event.current.mousePosition)) {
//										this.Close ();
//								}

                if (Event.current.type == EventType.MouseDrag && Event.current.button == 0)
                {
                    //if change happen change curve
                    for (int k = 0; k < __bindings.Length; k++)
                    {
                        AnimationModeUtility.SaveCurve(__curves [k], __clip, __bindings [k]);
                        //Debug.Log ("Save");
                    }
                }

                __curveEditor.DoEditor();


                //	Debug.Log ("CurveEditorWindow:"+__curveEditor.Scale + " " + __window.position.width + " " + Event.current.type);

                //if (EditorGUI.EndChangeCheck ()) {


                //}
            }
        }
        private static void AddKey(EditorCurveBinding curveBindingCurrent, GameObject root, AnimationClip clip, object valueCurrent, float time)
        {
            AnimationCurve curve;



            Type type = null;

            int frameCurrent = (int)(time * clip.frameRate);


            UnityEngine.Object objectAnimated = AnimationUtility.GetAnimatedObject(root, curveBindingCurrent);

            if (curveBindingCurrent.type == TransformType)
            {
                type = typeof(float);
            }
            else
            {
                type = objectAnimated.GetType().GetField(curveBindingCurrent.propertyName).FieldType;
            }

            if (curveBindingCurrent.isPPtrCurve)
            {
                ObjectReferenceKeyframe[] keyframesCurveReferenced = AnimationUtility.GetObjectReferenceCurve(clip, curveBindingCurrent);

                if (keyframesCurveReferenced == null)
                {
                    keyframesCurveReferenced = new ObjectReferenceKeyframe[0];
                }


                //if you put first frame somewhere in time there should be one at 0f so curve can be made
                //also if you put first frame in 0f then create one in 1f
                if (keyframesCurveReferenced.Length == 0)
                {
                    if (frameCurrent != 0)
                    {
                        AnimationModeUtility.AddKeyframeToObjectReferenceCurve(keyframesCurveReferenced, clip, curveBindingCurrent, valueCurrent, type, 0);
                    }
                    else
                    {
                        AnimationModeUtility.AddKeyframeToObjectReferenceCurve(keyframesCurveReferenced, clip, curveBindingCurrent, valueCurrent, type, 1f);
                    }
                }


                AnimationModeUtility.AddKeyframeToObjectReferenceCurve(keyframesCurveReferenced, clip, curveBindingCurrent, valueCurrent, type, time);
            }
            else
            {
                curve = AnimationUtility.GetEditorCurve(clip, curveBindingCurrent);

                if (curve == null)
                {
                    curve = new AnimationCurve();
                }



                //if you put first frame somewhere in time there should be one at 0f so curve can be made
                //also if you put first frame in 0f then create one in 1f
                if (curve.length == 0)
                {
                    if (frameCurrent != 0)
                    {
                        AnimationModeUtility.AddKeyframeToCurve(curve, clip, curveBindingCurrent, (float)valueCurrent, type, 0);
                    }
                    else
                    {
                        AnimationModeUtility.AddKeyframeToCurve(curve, clip, curveBindingCurrent, (float)valueCurrent, type, 1f);
                    }
                }

                //Debug.Log("Add key at some other frame");
                AnimationModeUtility.AddKeyframeToCurve(curve, clip, curveBindingCurrent, (float)valueCurrent, type, time);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Show the specified space, clip, node and position.
        /// </summary>
        /// <param name="space">Space.</param>
        /// <param name="clip">Clip.</param>
        /// <param name="node">Node.</param>
        /// <param name="position">Position.</param>
        public static void Show(GameObject space, AnimationClip clip, SerializedNode node, Rect?position)
        {
            MecanimNodeEditorWindow.__spaceGameObject = space;                                    //in this case is character
            MecanimNodeEditorWindow.__spaceGameObjectAnimationClip = clip;
            MecanimNodeEditorWindow.__serializedNode = node;



            ///////   ACCESS SERIALIZED DATA /////////
            NodePropertyIterator iterator = node.GetIterator();

            __isPlaying            = false;
            __isRecording          = false;
            __variableSelected     = null;
            __timeNormalized       = 0f;
            __timeNormalizedUpdate = false;
            __timeCurrent          = 0f;

            AnimationMode.StopAnimationMode();
            Undo.postprocessModifications -= PostprocessAnimationRecordingModifications;

            SceneView.onSceneGUIDelegate += OnSceneGUI;



            if (iterator.Find("clipBindings"))
            {
                clipBindingsSerialized = iterator.current;
            }



            if (__mecanimNodeClipBinding == null)
            {
                __mecanimNodeClipBinding = ScriptableObject.CreateInstance <EditorClipBinding> ();
            }

            __mecanimNodeClipBinding.gameObject = __spaceGameObject;
            __mecanimNodeClipBinding.clip       = __spaceGameObjectAnimationClip;



            /////// INIT SERIALIZED NODE PROPERTIES - CURVES, COLORS, VARIABLES //////


            if (iterator.Find("curves"))
            {
                curvesSerialized = iterator.current;
            }
            else
            {
                Debug.LogError("MecananimNode should have public field 'curves'");
            }

            if (iterator.Find("curvesColors"))
            {
                curvesColorsSerialized = iterator.current;
            }
            else
            {
                Debug.LogError("MecananimNode should have public field 'curvesColors'");
            }

            if (iterator.Find("variablesBindedToCurves"))
            {
                variablesBindedToCurvesSerialized = iterator.current;
            }
            else
            {
                Debug.LogError("MecananimNode should have public field 'variablesBindedToCurves'");
            }



            curves                  = (AnimationCurve[])curvesSerialized.value;
            curveColors             = (Color[])curvesColorsSerialized.value;
            variablesBindedToCurves = (UnityVariable[])variablesBindedToCurvesSerialized.value;

            AnimationModeUtility.ResetBindingsTransformPropertyModification(clipBindingsSerialized.value as EditorClipBinding[]);
            AnimationModeUtility.ResetBindingTransformPropertyModification(__mecanimNodeClipBinding);



            keyframeTimeValues  = new float[0];
            eventTimeValuesPrev = new float[0];

            keyframeTimeValuesSelected = new bool[0];
            keyframesDisplayNames      = new string[0];


            ///////////// create Reordable list of gameObject-animationClip //////////////////

            __gameObjectClipList = new ReorderableList(clipBindingsSerialized.value as IList, typeof(EditorClipBinding), true, true, true, true);
            __gameObjectClipList.drawElementCallback = onDrawElement;



            __gameObjectClipList.drawHeaderCallback = onDrawHeaderElement;

            __gameObjectClipList.onRemoveCallback = onRemoveCallback;
            __gameObjectClipList.onAddCallback    = onAddCallback;
            __gameObjectClipList.onSelectCallback = onSelectCallback;


            //__gameObjectClipList.elementHeight = 32f;


            if (MecanimNodeEditorWindow.__window != null)                                    //restore last
            {
                position = __window.position;
            }


            MecanimNodeEditorWindow.__window = (MecanimNodeEditorWindow)EditorWindow.GetWindow(typeof(MecanimNodeEditorWindow));



            if (position.HasValue)
            {
                MecanimNodeEditorWindow.__window.position = position.Value;
            }

            MecanimNodeEditorWindow.__window.Show();
        }
Beispiel #8
0
        /// <summary>
        /// Handles the GUI event.
        /// </summary>
        void OnGUI()
        {
            if (_keyframeMarker == null)
            {
                _keyframeMarker = new GUIContent(EditorGUILayoutEx.ANIMATION_STYLES.pointIcon);
            }

            if (!Application.isPlaying && __gameObjectClipList != null)
            {
                _curvesEditorShow = EditorGUILayout.Foldout(_curvesEditorShow, "Curves");

                //int indentLevel = 0;

                Rect curveEditorRect = new Rect(0, 0, 0, 0);
                int  i = 0;


                if (_curvesEditorShow)
                {
                    //This makes layout to work (Reserving space)
                    curveEditorRect = GUILayoutUtility.GetRect(Screen.width - 16f, 200);

                    /////// CURVE EDITOR ////////
                    curveEditorRect.width = curveEditorRect.width - 32f;
                    curveEditorRect.x     = 16f;


                    if (curveEditor == null)
                    {
                        CurveWrapperW[] curveWrappers;

                        int numCurves = curves.Length;

                        curveWrappers = new CurveWrapperW[numCurves];

                        CurveWrapperW curveWrapperNew;

                        for (i = 0; i < numCurves; i++)
                        {
                            curveWrapperNew       = new CurveWrapperW();
                            curveWrapperNew.curve = curves [i];
                            curveWrapperNew.color = curveColors [i];
                            curveWrappers [i]     = curveWrapperNew;
                        }



                        curveEditor = new CurveEditorW(curveEditorRect, curveWrappers, false);

                        curveEditor.FrameSelected(true, true);
                        curveEditor.scaleWithWindow = true;
                        curveEditor.hSlider         = false;
                        curveEditor.hRangeMin       = 0f;
                        curveEditor.hRangeMax       = 1f;
                        curveEditor.hRangeLocked    = true;

                        curveEditor.onSelect += onCurveSelect;
                    }
                    else
                    {
                        curveEditor.rect = curveEditorRect;
                        curveEditor.FrameSelected(false, false);
                    }



                    curveEditor.DoEditor();



                    ///////////////////////////////////////////////////////////////////////////////



                    /////////////   ADD/REMOVE CURVE BINDED TO OBJECT PROP OR GLOBAL VARIABLE /////////////
                    ///                                                                                  //

                    EditorGUILayout.BeginHorizontal();



                    //if curve is selected display curve properties
                    if (_curveIndexSelected > -1 && _curveIndexSelected < variablesBindedToCurves.Length)
                    {
                        UnityVariable variableSelected = variablesBindedToCurves [_curveIndexSelected];

                        try {
                            bindingCurvesGUIContent.text = variableSelected.instanceBinded.name + "." + variableSelected.memberPath;

                            EditorGUILayout.LabelField(bindingCurvesGUIContent, new GUILayoutOption[] {});

                            EditorGUI.BeginChangeCheck();
                            Color colorNew = EditorGUILayout.ColorField(curveColors [_curveIndexSelected]);


                            if (EditorGUI.EndChangeCheck())
                            {
                                curveEditor.animationCurves [_curveIndexSelected].color = colorNew;
                                curveColors [_curveIndexSelected] = colorNew;
                                curvesColorsSerialized.ValueChanged();
                                curvesColorsSerialized.ApplyModifiedValue();
                            }
                        } catch (MissingReferenceException ex) {
                            bindingCurvesGUIContent.text = "Invalid UVariable " + ex.Message;
                        }
                    }
                    else
                    {
                        bindingCurvesGUIContent.text = "Curve binding:";


                        List <UnityVariable> blackboardLocalList = (MecanimNodeEditorWindow.__serializedNode.target.blackboard as BlackboardCustom).GetVariableBy(typeof(float));

                        List <GUIContent> displayOptionsList = blackboardLocalList.Select((item) => new GUIContent("Local/" + item.name)).ToList();



                        __variableSelected = EditorGUILayoutEx.UnityVariablePopup(bindingCurvesGUIContent, __variableSelected, typeof(float), displayOptionsList, blackboardLocalList);



                        _colorSelected = EditorGUILayout.ColorField(_colorSelected);
                    }



                    /////////////// ADD CURVE(+) /////////

                    if (GUILayout.Button("Add") && __variableSelected != null)
                    {
                        List <UnityVariable> vList = variablesBindedToCurves.ToList();
                        vList.Add(__variableSelected);
                        variablesBindedToCurvesSerialized.value = variablesBindedToCurves = vList.ToArray();
                        variablesBindedToCurvesSerialized.ValueChanged();
                        //variablesBindedToCurvesSerialized.ApplyModifiedValue ();



                        List <Color> cList = curveColors.ToList();
                        _colorSelected.a = 1;
                        cList.Add(_colorSelected);
                        curvesColorsSerialized.value = curveColors = cList.ToArray();
                        curvesColorsSerialized.ValueChanged();
                        //curvesColorsSerialized.ApplyModifiedValue ();



                        AnimationCurve curveAnimationNew;



                        List <AnimationCurve> crList = curves.ToList();

                        curveAnimationNew = new AnimationCurve(new Keyframe[] {
                            new Keyframe(0f, (float)__variableSelected.Value),
                            new Keyframe(1f, 1f)
                        });

                        //TODO add from preset
                        crList.Add(curveAnimationNew);

                        curvesSerialized.value = curves = crList.ToArray();
                        curvesSerialized.ValueChanged();
                        //curvesColorsSerialized.ApplyModifiedValue ();



                        ///add curve wrapped to CurveEditor
                        CurveWrapperW curveWrapperW = new CurveWrapperW();

                        curveWrapperW.color = _colorSelected;

                        curveWrapperW.curve = curveAnimationNew;

                        curveEditor.AddCurve(curveWrapperW);

                        curveEditor.FrameSelected(true, true);



                        __serializedNode.Update();

                        __serializedNode.ApplyModifiedProperties();


                        __variableSelected = null;
                    }



                    ///////////// DELETE CURVE ////////////

                    if (GUILayout.Button("Del") || Event.current.keyCode == KeyCode.Delete)
                    {
                        curveEditor.RemoveCurveAt(_curveIndexSelected);



                        List <UnityVariable> vList = variablesBindedToCurves.ToList();
                        vList.RemoveAt(_curveIndexSelected);
                        variablesBindedToCurvesSerialized.value = variablesBindedToCurves = vList.ToArray();
                        variablesBindedToCurvesSerialized.ValueChanged();



                        List <Color> cList = curveColors.ToList();

                        cList.RemoveAt(_curveIndexSelected);
                        curvesColorsSerialized.value = curveColors = cList.ToArray();
                        curvesColorsSerialized.ValueChanged();



                        List <AnimationCurve> crList = curves.ToList();

                        crList.RemoveAt(_curveIndexSelected);

                        curvesSerialized.value = curves = crList.ToArray();
                        curvesSerialized.ValueChanged();



                        _curveIndexSelected = -1;
                        __variableSelected  = null;

                        __serializedNode.ApplyModifiedProperties();
                    }



                    EditorGUILayout.EndHorizontal();
                }
                else                                                    //NOT CURVE EDITOR



                ///////////// GAMEOBJECT - CLIP BINDINGS //////////


                {
                    __gameObjectClipList.DoLayoutList();


                    //////////////////////////////////////////////
                }



                EditorGUILayout.Space();



                __mecanimNodeClipBinding.clip = __spaceGameObjectAnimationClip;


                /////////////   TIME CONTROL OF ANIMATION (SLIDER) /////////

                Rect timeControlRect = GUILayoutUtility.GetRect(Screen.width, 26f);



                timeControlRect.xMax = 32f;



                /////////////  PLAY ANIMATION TOGGLE  /////////
                __isPlaying = GUI.Toggle(timeControlRect, __isPlaying, !__isPlaying ? EditorGUILayoutEx.ANIMATION_STYLES.playIcon : EditorGUILayoutEx.ANIMATION_STYLES.pauseIcon, EditorGUILayoutEx.ANIMATION_STYLES.playButton);


                if (__isPlaying)
                {
                }
                else
                {
                }


                timeControlRect.xMin  = timeControlRect.xMax + 1f;
                timeControlRect.xMax  = timeControlRect.xMin + 21f;
                timeControlRect.yMin += 2f;


                EditorGUI.BeginChangeCheck();

                Color color = GUI.color;                                                //save color


                if (AnimationMode.InAnimationMode())
                {
                    GUI.color = AnimationMode.animatedPropertyColor;                                                            //change color of record button to red
                }
                /////////////  RECORD ANIMATION TOGGLE  /////////
                __isRecording = GUI.Toggle(timeControlRect, __isRecording, EditorGUILayoutEx.ANIMATION_STYLES.recordIcon, EditorStyles.toolbarButton);

                GUI.color = color;                                                //restore color

                if (EditorGUI.EndChangeCheck())
                {
                    if (__isRecording)
                    {
                        if (!AnimationMode.InAnimationMode())
                        {
                            List <EditorClipBinding> list = (clipBindingsSerialized.value as EditorClipBinding[]).ToList();
                            list.Add(__mecanimNodeClipBinding);

                            __clipBindingsToBeAnimated = list.ToArray();

                            AnimationMode.StartAnimationMode();
                            Undo.postprocessModifications += PostprocessAnimationRecordingModifications;



                            //calculate offset of boonRoot position before animation from boonRoot position at time=0s.
                            AnimationModeUtility.SaveBindingsOffset(clipBindingsSerialized.value as EditorClipBinding[]);

                            AnimationModeUtility.SaveBindingOffset(__mecanimNodeClipBinding);

                            //calculate time in seconds from the current postion of time scrubber
                            __timeCurrent = __timeNormalized * __spaceGameObjectAnimationClip.length;

                            //apply clip animaiton at __timeCurrent
                            AnimationModeUtility.SampleClipBindingAt(__clipBindingsToBeAnimated
                                                                     , __timeCurrent);

                            LockRootGameObject(true);

                            SceneView.RepaintAll();
                        }
                    }
                    else
                    {
                        //Remove Undo property modificaiton handlers
                        Undo.postprocessModifications -= PostprocessAnimationRecordingModifications;

                        AnimationMode.StopAnimationMode();

                        //reset gameobject with bones to state before animation
                        AnimationModeUtility.ResetBindingsTransformPropertyModification(clipBindingsSerialized.value as EditorClipBinding[]);

                        //reset Node.self gameObject
                        AnimationModeUtility.ResetBindingTransformPropertyModification(__mecanimNodeClipBinding);

                        LockRootGameObject(false);
                    }
                }

                timeControlRect.xMin  = 40f + 16f;
                timeControlRect.xMax  = Screen.width - 68f;
                timeControlRect.yMin -= 2f;



                EditorGUI.BeginChangeCheck();


                /// TIMELINE SLIDER ///
                __timeNormalized = EditorGUILayoutEx.CustomHSlider(timeControlRect, __timeNormalized, 0f, 1f, EditorGUILayoutEx.ANIMATION_STYLES.timeScrubber);



                if (EditorGUI.EndChangeCheck() || __timeNormalizedUpdate)
                {
                    __timeCurrent = __timeNormalized * __spaceGameObjectAnimationClip.length;

                    __timeNormalizedUpdate = false;


                    if (!AnimationMode.InAnimationMode())
                    {
                        AnimationMode.StartAnimationMode();

                        //calculate offset of boonRoot position before animation from boonRoot position at time=0s.
                        AnimationModeUtility.SaveBindingsOffset(clipBindingsSerialized.value as EditorClipBinding[]);

                        AnimationModeUtility.SaveBindingOffset(__mecanimNodeClipBinding);


                        LockRootGameObject(true);
                    }

                    if (!__isRecording)
                    {
                        __isRecording = true;

                        //add recording Undo events handlers
                        Undo.postprocessModifications += PostprocessAnimationRecordingModifications;

                        List <EditorClipBinding> list = (clipBindingsSerialized.value as EditorClipBinding[]).ToList();
                        list.Add(__mecanimNodeClipBinding);

                        __clipBindingsToBeAnimated = list.ToArray();
                    }



                    //moves clip to time: __timeCurrent
                    AnimationModeUtility.SampleClipBindingAt(__clipBindingsToBeAnimated, __timeCurrent);
                }

                /////////////  ROTATION/SCALE KEYFRAMES  /////////////////////////

                Rect keyframesRect = GUILayoutUtility.GetRect(Screen.width - 16f, 16f);

                keyframesRect.xMax = timeControlRect.xMax + _keyframeMarker.image.width * 0.5f;
                keyframesRect.xMin = timeControlRect.xMin - _keyframeMarker.image.width * 0.5f;


                //Show rotation or scale keyframes if Rotation or Scale tools are selected
                if (Selection.activeGameObject != null)
                {
                    if (Tools.current == Tool.Rotate)
                    {
                        EditorClipBinding clipBindingCurrent = (clipBindingsSerialized.value as EditorClipBinding[]).FirstOrDefault((itm) => itm.gameObject != null && itm.gameObject.transform.childCount > 0 && itm.gameObject.transform.GetChild(0).gameObject == Selection.activeGameObject);

                        if (clipBindingCurrent != null && clipBindingCurrent.visible && clipBindingCurrent.clip != null)
                        {
                            EditorCurveBinding curveBinding = AnimationUtilityEx.EditorCurveBinding_RotX;
                            curveBinding.path  = AnimationUtility.CalculateTransformPath(clipBindingCurrent.gameObject.transform.GetChild(0), clipBindingCurrent.gameObject.transform.root);
                            keyframeTimeValues = AnimationUtilityEx.GetTimesNormalized(clipBindingCurrent.clip, curveBinding, __spaceGameObjectAnimationClip.length);
                        }
                        else
                        {
                            keyframeTimeValues = new float[0];
                        }
                    }
                    else
                    if (Tools.current == Tool.Scale)
                    {
                        EditorClipBinding clipBindingCurrent = (clipBindingsSerialized.value as EditorClipBinding[]).FirstOrDefault((itm) => itm.gameObject != null && itm.gameObject.transform.childCount > 0 && itm.gameObject.transform.GetChild(0).gameObject == Selection.activeGameObject);

                        if (clipBindingCurrent != null && clipBindingCurrent.visible && clipBindingCurrent.clip != null)
                        {
                            EditorCurveBinding curveBinding = AnimationUtilityEx.EditorCurveBinding_SclX;
                            curveBinding.path  = AnimationUtility.CalculateTransformPath(clipBindingCurrent.gameObject.transform.GetChild(0), clipBindingCurrent.gameObject.transform.root);
                            keyframeTimeValues = AnimationUtilityEx.GetTimesNormalized(clipBindingCurrent.clip, curveBinding, __spaceGameObjectAnimationClip.length);
                        }
                        else
                        {
                            keyframeTimeValues = new float[0];
                        }
                    }
                    else
                    {
                        keyframeTimeValues = new float[0];
                    }
                }
                else
                {
                    keyframeTimeValues = new float[0];
                }



                keyframesDisplayNames = keyframeTimeValues.Select((itm) => {
                    return(Decimal.Round(Convert.ToDecimal(itm * __spaceGameObjectAnimationClip.length), 2).ToString() + ".s");
                }).ToArray();

                keyframeTimeValuesSelected = new bool[keyframeTimeValues.Length];                                                //used for multiselection option not used here

                //create custom timeline showing rotation or scale keyframes
                EditorGUILayoutEx.CustomTimeLine(ref keyframesRect, _keyframeMarker, ref keyframeTimeValues, ref eventTimeValuesPrev, ref keyframesDisplayNames, ref keyframeTimeValuesSelected, -1f,
                                                 null, onKeyframeDelete, null, onKeyframeEdit, null
                                                 );


                // DISPLAY TIME in [s] and  in [%]
                EditorGUILayout.LabelField("Time: " + Decimal.Round(Convert.ToDecimal(__timeCurrent), 2).ToString() + "s (" + Mathf.FloorToInt(__timeNormalized * 100) + "%) Frame:" + Mathf.FloorToInt(__timeCurrent * __spaceGameObjectAnimationClip.frameRate).ToString());



                ///////////////////////////////////////////////////////////////



                //////////////////////////////////////////////////////////////
                ///
                ///			 Draw red time scrubber line on top of Curve Editor
                ///
                //////////////////////////////////////////////////////////////

                if (_curvesEditorShow)
                {
                    Handles.color = Color.red;



                    float leftrightMargin = 39f;                                                            // 40f;
                    float effectiveWidth  = curveEditorRect.width - 2 * leftrightMargin - curveEditorRect.xMin;
                    float timeLineX       = curveEditorRect.xMin + leftrightMargin + effectiveWidth * __timeNormalized;

                    Handles.DrawLine(new Vector2(timeLineX, curveEditorRect.y), new Vector2(timeLineX, curveEditorRect.y + curveEditorRect.height));
                }



                ////////// EVALUATE CURVES //////////
                int variablesNum = variablesBindedToCurves.Length;
                for (int varriableCurrentinx = 0; varriableCurrentinx < variablesNum; varriableCurrentinx++)
                {
                    try {
                        variablesBindedToCurves [varriableCurrentinx].Value = curves [varriableCurrentinx].Evaluate(__timeNormalized);
                    } catch (Exception ex) {
                        variablesBindedToCurves [varriableCurrentinx].name = "Invalid UVariable" + ex.Message;
                    }
                }
            }
        }