Example #1
0
        //
        // Methods
        //



        /// <summary>
        /// Handles the onGUI event.
        /// </summary>
        /// <param name="property">Property.</param>
        /// <param name="node">Node.</param>
        /// <param name="guiContent">GUI content.</param>
        public override void OnGUI(SerializedNodeProperty property, ActionNode node, GUIContent guiContent)
        {
            //if (animatorSerialized == null || aniController == null) {
            if (aniController == null)
            {
                //!!! Serialization never serialized Animator cos its initialized in Reset after
//								NodePropertyIterator iter= property.serializedNode.GetIterator();
//								iter.Find(attribute.animatorFieldName);
//								 animatorSerialized=iter.current;
                //				//								if(animatorSerialized==null || animatorSerialized.value==null){
                //										Debug.LogError("AnimatorStateNodePropertyDrawer> No Animator component set on node parent GameObject");
                //									return;
                //								}

                //runtimeContoller =( (Animator)animatorSerialized.value).runtimeAnimatorController;
                Animator animator = node.GetType().GetField(attribute.animatorFieldName).GetValue(node) as Animator;



                RuntimeAnimatorController runtimeContoller;


                runtimeContoller = animator.runtimeAnimatorController;

                if (runtimeContoller is AnimatorOverrideController)
                {
                    aniController = ((AnimatorOverrideController)runtimeContoller).runtimeAnimatorController as UnityEditor.Animations.AnimatorController;
                }
                else
                {
                    aniController = runtimeContoller as UnityEditor.Animations.AnimatorController;
                }
            }



            animatorStateDisplayOptions = MecanimUtility.GetDisplayOptions(aniController);
            animatorStateValues         = MecanimUtility.GetAnimatorStates(aniController);



            if (property.value != null)
            {
                if (animatorStateValues.Length > 0)
                {
                    animatorStateSelectedPrev = animatorStateSelected = animatorStateValues.FirstOrDefault((itm) => itm.nameHash == ((ws.winx.unity.AnimatorState)property.value).nameHash);
                }
            }


            animatorStateSelected = EditorGUILayoutEx.CustomObjectPopup(guiContent, animatorStateSelected, animatorStateDisplayOptions, animatorStateValues);                                     //,compare);



            //TODO try Begin/End Check
            if (animatorStateSelectedPrev != animatorStateSelected)
            {
                NodePropertyIterator iter = property.serializedNode.GetIterator();
                iter.Find(attribute.layerIndexFieldName);
                SerializedNodeProperty layerIndexSerialized = iter.current;

                layerIndexSerialized.value = MecanimUtility.GetLayerIndex(aniController, animatorStateSelected);
                layerIndexSerialized.ApplyModifiedValue();



                ws.winx.unity.AnimatorState state = property.value as ws.winx.unity.AnimatorState;
                if (state == null)
                {
                    state = ScriptableObject.CreateInstance <ws.winx.unity.AnimatorState>();
                }

                state.motion   = animatorStateSelected.motion;
                state.nameHash = animatorStateSelected.nameHash;
                state.layer    = (int)layerIndexSerialized.value;

                if (state.motion is UnityEditor.Animations.BlendTree)
                {
                    BlendTree tree           = (BlendTree)state.motion;
                    int       blendParamsNum = tree.GetRecursiveBlendParamCount();

                    state.blendParamsHashes = new int[blendParamsNum];

                    for (int i = 0; i < blendParamsNum; i++)
                    {
                        state.blendParamsHashes[i] = Animator.StringToHash(tree.GetRecursiveBlendParam(i));
                    }
                }
                else
                {
                    state.blendParamsHashes = null;
                }

                //property.value=state;
                property.ValueChanged();


                property.ApplyModifiedValue();

                animatorStateSelectedPrev = animatorStateSelected;
            }



            if (animatorStateSelected.motion == null)
            {
                Debug.LogError("Selected state doesn't have Motion set");
            }
        }
        public override void OnGUI(SerializedNodeProperty property, BehaviourMachine.ActionNode node, GUIContent guiContent)
        {
            // Now draw the property as a Slider or an IntSlider based on whether it’s a float or integer.
            if (property.type != typeof(MinMaxRangeSO))
            {
                Debug.LogWarning("Use only with MinMaxRange type");
            }
            else
            {
                var range = attribute as MinMaxRangeSAttribute;
                var so    = (MinMaxRangeSO)property.value;


                //set or reset to default full range
                if (so.rangeStart == so.rangeEnd)
                {
                    so.rangeStart = range.minLimit;
                    so.rangeEnd   = range.maxLimit;
                }

                var newMin = so.rangeStart;
                var newMax = so.rangeEnd;


                Rect position = GUILayoutUtility.GetRect(Screen.width - 32f, 32f);

                var xDivision = position.width * 0.33f;
                var yDivision = position.height * 0.5f;
                EditorGUI.LabelField(new Rect(position.x, position.y, xDivision, yDivision)
                                     , guiContent);

                EditorGUI.LabelField(new Rect(position.x, position.y + yDivision, position.width, yDivision)
                                     , range.minLimit.ToString("0.##"));
                EditorGUI.LabelField(new Rect(position.x + position.width - 28f, position.y + yDivision, position.width, yDivision)
                                     , range.maxLimit.ToString("0.##"));


                EditorGUI.MinMaxSlider(new Rect(position.x + 24f, position.y + yDivision, position.width - 48f, yDivision)
                                       , ref newMin, ref newMax, range.minLimit, range.maxLimit);

                EditorGUI.LabelField(new Rect(position.x + xDivision, position.y, xDivision, yDivision)
                                     , "From: ");
                newMin = Mathf.Clamp(EditorGUI.FloatField(new Rect(position.x + xDivision + 30, position.y, xDivision - 30, yDivision)
                                                          , newMin)
                                     , range.minLimit, newMax);
                EditorGUI.LabelField(new Rect(position.x + xDivision * 2f, position.y, xDivision, yDivision)
                                     , "To: ");
                newMax = Mathf.Clamp(EditorGUI.FloatField(new Rect(position.x + xDivision * 2f + 24, position.y, xDivision - 24, yDivision)
                                                          , newMax)
                                     , newMin, range.maxLimit);

                so.rangeStart = newMin;
                so.rangeEnd   = newMax;

                property.ValueChanged();

                property.ApplyModifiedValue();

                property.serializedNode.ApplyModifiedProperties();
            }
        }
Example #3
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;
                    }
                }
            }
        }