/// <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 ();
        }
        /// <summary>
        /// The custom inspector.
        /// </summary>
        public override void OnInspectorGUI()
        {
            int i = 0;



            //////  RESTORE SAVED  //////
            //restore and delete clipboard


            mecanimNode = target as MecanimNode;

            if (mecanimNode != null)
            {
                Motion motion = null;



                //////////////////////////////////////////////////////////////
                ///                         PRESEVE RESTORE					//
                if (EditorApplication.isPlaying || EditorApplication.isPaused)
                {
                    if (GUILayout.Button("Preserve"))
                    {
                        serializedNode.ApplyModifiedProperties();

                        UnityVariable.SetDirty(mecanimNode.blendX);

                        UnityVariable.SetDirty(mecanimNode.blendY);
                        UnityVariable.SetDirty(mecanimNode.motionOverride);

//												if (variablesBindedToCurves != null) {
//														UnityVariable[] varArray = variablesBindedToCurves;
//
//														int varNumber = varArray.Length;
//														for (int varCurrent=0; varCurrent<varNumber; varCurrent++) {
//																varArray [varCurrent].OnBeforeSerialize ();
//
//														}
//												}


                        EditorUtilityEx.Clipboard.preserve(mecanimNode.instanceID, mecanimNode, mecanimNode.GetType().GetFields());
                    }
                }
                else
                {
                    if (EditorUtilityEx.Clipboard.HasBeenPreseved(mecanimNode.instanceID) && GUILayout.Button("Apply Playmode Changes"))
                    {
                        EditorUtilityEx.Clipboard.restore(mecanimNode.instanceID, mecanimNode);

                        animatorStateSerialized = null;
                        NodePropertyIterator iterator = serializedNode.GetIterator();



                        while (iterator.Next(true))
                        {
                            if (iterator.current.value is UnityVariable)
                            {
                                //Debug.Log("OnBeforeDeserialize:"+((UnityVariable)iterator.current.value).Value);
                                ((UnityVariable)iterator.current.value).OnAfterDeserialize();

                                //Debug.Log("OnAfterDeserialize:"+((UnityVariable)iterator.current.value).Value);
                            }
                            else if (iterator.current.value is UnityVariable[])
                            {
                                UnityVariable[] varArray  = (UnityVariable[])iterator.current.value;
                                int             varNumber = varArray.Length;
                                for (int varCurrent = 0; varCurrent < varNumber; varCurrent++)
                                {
                                    varArray [varCurrent].OnAfterDeserialize();
                                }
                            }


                            iterator.current.ValueChanged();

                            this.serializedNode.Update();

                            iterator.current.ApplyModifiedValue();
                        }
                    }
                }
                //////////////////////


                if (Event.current.type == EventType.Layout)
                {
                    this.serializedNode.Update();
                }



                DrawDefaultInspector();

//
//				if (EditorGUILayoutEx.ANIMATION_STYLES == null)
//					EditorGUILayoutEx.ANIMATION_STYLES = new EditorGUILayoutEx.AnimationStyles ();



                /////////////////////////////// ANIMATOR STATE /////////////////////////////////

                if (animatorStateSerialized == null)
                {
                    NodePropertyIterator iterator = this.serializedNode.GetIterator();
                    if (iterator.Find("animatorStateSelected"))
                    {
                        animatorStateSerialized = iterator.current;
                    }


                    if (iterator.Find("motionOverride"))
                    {
                        motionOverrideSerialized = iterator.current;
                    }
                }



                //////////  MOTION OVERRIDE HANDLING  //////////
                if (animatorStateSerialized.value != null)
                {
                    UnityVariable motionOverridVariable = (UnityVariable)motionOverrideSerialized.value;

                    //if there are no override use motion of selected AnimationState
                    //Debug.Log(((UnityEngine.Object)mecanimNode.motionOverride.Value).);
                    if (motionOverridVariable == null || motionOverridVariable.Value == null || motionOverridVariable.ValueType != typeof(AnimationClip))
                    {
                        motion = ((ws.winx.unity.AnimatorState)animatorStateSerialized.value).motion;
                    }
                    else                                                             //
                    {
                        motion = (Motion)motionOverridVariable.Value;
                    }



                    if (motionOverridVariable != null && motionOverridVariable.Value != null && ((ws.winx.unity.AnimatorState)animatorStateSerialized.value).motion == null)
                    {
                        Debug.LogError("Can't override state that doesn't contain motion");
                    }
                }
                ///////////////////////////////////////////////////

                if (GUILayout.Button("BindEditor") && motion != null)
                {
                    MecanimNodeEditorWindow.Show(mecanimNode.self, motion as AnimationClip, this.serializedNode, null);
                }

                /////////////   TIME CONTROL OF ANIMATION (SLIDER) /////////
                if (Application.isPlaying)
                {
                    if (animatorStateRuntimeControlEnabledSerialized == null)
                    {
                        NodePropertyIterator iterator = this.serializedNode.GetIterator();

                        if (iterator.Find("animationRunTimeControlEnabled"))
                        {
                            animatorStateRuntimeControlEnabledSerialized = iterator.current;
                        }

                        if (iterator.Find("animatorStateRunTimeControl"))
                        {
                            animatorStateRunTimeControlSerialized = iterator.current;
                        }
                    }



                    if (animatorStateRuntimeControlEnabledSerialized != null && animatorStateRunTimeControlSerialized != null && (bool)animatorStateRuntimeControlEnabledSerialized.value)
                    {
                        Rect timeControlRect = GUILayoutUtility.GetRect(Screen.width - 16f, 26f);
                        timeControlRect.xMin += 38f;
                        timeControlRect.xMax -= 70f;
                        animatorStateRunTimeControlSerialized.value = EditorGUILayoutEx.CustomHSlider(timeControlRect, (float)animatorStateRunTimeControlSerialized.value, 0f, 1f, EditorGUILayoutEx.ANIMATION_STYLES.timeScrubber);
                    }
                }
                ///////////////////////////////////////////////////////////////


                /////////// AVATAR Preview GUI ////////////


                if (!Application.isPlaying && motion != null)
                {
                    //This makes layout to work (Reserving space)
                    Rect avatarRect = GUILayoutUtility.GetRect(Screen.width - 16f, 200);
                    avatarRect.width -= 70f;
                    avatarRect.xMin  += 6f;


                    if (avatarPreview == null)
                    {
                        avatarPreview = new AvatarPreviewW(null, motion);
                    }
                    else
                    {
                        avatarPreview.SetPreviewMotion(motion);
                    }



                    EditorGUILayout.BeginHorizontal();



                    if (eventTimeValues != null && Event.current.type == EventType.Repaint)
                    {
                        //find first selected if exist
                        int eventTimeValueSelectedIndex = Array.IndexOf(eventTimeValuesSelected, true);



                        if (eventTimeValueSelectedIndex > -1)
                        {
                            avatarPreview.SetTimeAt(eventTimeValues [eventTimeValueSelectedIndex]);
                        }
                        else
                        {
                            //!!! changing
                            //avatarPreview.timeControl.startTime
                            // start/stop makes AvatarPreview to play from start to stop
                            // and the rest of animation isn't visible in Timeline so not good for selecting range
                            // but its not offer good usability of resized animation


                            if (avatarPreview.timeControl.playing)
                            {
                                //restrict animation into this range
                                if (avatarPreview.timeControl.normalizedTime < mecanimNode.range.rangeStart || avatarPreview.timeControl.normalizedTime > mecanimNode.range.rangeEnd)
                                {
                                    avatarPreview.timeControl.nextCurrentTime = avatarPreview.timeControl.startTime * (1f - mecanimNode.range.rangeStart) + avatarPreview.timeControl.stopTime * mecanimNode.range.rangeStart;
                                }
                            }
                            else
                            {
                                //set AvatarPreview animation time range depending of drag of range control handles
                                if (Math.Abs(mecanimNode.range.rangeStart - timeNormalizedStartPrev) > 0.01f)
                                {
                                    timeNormalizedStartPrev = mecanimNode.range.rangeStart;

                                    avatarPreview.SetTimeAt(timeNormalizedStartPrev);
                                }
                                else
                                if (Math.Abs(mecanimNode.range.rangeEnd - timeNormalizedEndPrev) > 0.01f)
                                {
                                    timeNormalizedEndPrev = mecanimNode.range.rangeEnd;
                                    avatarPreview.SetTimeAt(timeNormalizedEndPrev);
                                }
                            }
                        }
                    }



                    avatarPreview.timeControl.playbackSpeed = mecanimNode.speed;



                    avatarPreview.DoAvatarPreview(avatarRect, GUIStyle.none);



                    //Debug.Log(avatarPreview.timeControl.currentTime+" "+);
                    EditorGUILayout.EndHorizontal();



                    ////////// Events Timeline GUI //////////

                    if (!eventTimeLineInitalized)
                    {
                        //TODO calculate PopupRect

                        eventTimeLineValuePopUpRect = new Rect((Screen.width - 250) * 0.5f, (Screen.height - 150) * 0.5f, 250, 150);


                        //select the time values from nodes
                        //eventTimeValues = mecanimNode.children.Select ((val) => (float)((SendEventNormalized)val).timeNormalized.Value).ToArray ();


                        eventTimeValues = mecanimNode.children.Select((val) => (float)(((SendEventNormalizedNode)val).timeNormalized.serializedProperty as SerializedProperty).floatValue).ToArray();


                        eventDisplayNames       = mecanimNode.children.Select((val) => ((SendEventNormalizedNode)val).name).ToArray();
                        eventTimeValuesSelected = new bool[eventTimeValues.Length];

                        playButtonStyle = "TimeScrubberButton";

                        if (playButtonStyle != null)
                        {
                            playButtonSize = playButtonStyle.CalcSize(new GUIContent());
                        }

                        eventTimeLineInitalized = true;
                    }



                    Rect timeLineRect = GUILayoutUtility.GetRect(Screen.width - 16f, 50f);
                    //Rect timeLineRect = GUILayoutUtility.GetLastRect ();


                    Texture eventMarkerTexture = EditorGUILayoutEx.ANIMATION_STYLES.eventMarker.image;
                    timeLineRect.xMin += playButtonSize.x - eventMarkerTexture.width * 0.5f;
                    timeLineRect.xMax -= eventMarkerTexture.width * 0.5f;
                    //timeLineRect.height = EditorGUILayoutEx.eventMarkerTexture.height * 3 * 0.66f + playButtonSize.y;
                    timeLineRect.width -= 66f;
                    EditorGUILayoutEx.CustomTimeLine(ref timeLineRect, new GUIContent(eventMarkerTexture), ref eventTimeValues, ref eventTimeValuesPrev, ref eventDisplayNames, ref eventTimeValuesSelected, avatarPreview.timeControl.normalizedTime,
                                                     onMecanimEventAdd, onMecanimEventDelete, onMecanimEventClose, onMecanimEventEdit, onMecanimEventDragEnd
                                                     );

                    EditorGUILayout.LabelField("Events Timeline");

                    SendEventNormalizedNode ev;



                    //update time values
                    int eventTimeValuesNumber = mecanimNode.children.Length;
                    for (i = 0; i < eventTimeValuesNumber; i++)
                    {
                        ev = ((SendEventNormalizedNode)mecanimNode.children [i]);
                        //ev.timeNormalized.Value = eventTimeValues [i];
                        ev.timeNormalized.Value = eventTimeValues [i];

                        //if changes have been made in pop editor or SendEventNormailized inspector
                        if (ev.name != eventDisplayNames [i])
                        {
                            eventDisplayNames [i] = ((SendEventNormalizedNode)mecanimNode.children [i]).name;
                        }

                        EditorUtilityEx.ApplySerializedPropertyChangeTo(ev.timeNormalized);
                        //ev.timeNormalized.ApplyModifiedProperties ();
                    }



                    // Restore the indent level
                    //EditorGUI.indentLevel = indentLevel;

                    // Apply modified properties
                    this.serializedNode.ApplyModifiedProperties();
                }
            }
        }
Esempio n. 3
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();
        }