/// <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();
                }
            }
        }
예제 #2
0
        /// <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.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;

                                                ev.timeNormalized.ApplyModifiedProperties ();

                                        }

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

                                        // Apply modified properties
                                        this.serializedNode.ApplyModifiedProperties ();

                                }

                        }
        }