예제 #1
0
        /************************************************************************************************************************/

        /// <summary>
        /// Asks if the user wants to delete the root Animancer folder and does so if they confirm.
        /// </summary>
        private void CheckDeleteAnimancer()
        {
            if (!AnimancerEditorUtilities.TryUseClickInLastRect())
            {
                return;
            }

            if (!AssetDatabase.IsValidFolder(AnimancerDirectory))
            {
                Debug.Log(AnimancerDirectory + " doesn't exist." +
                          " You must have moved Animancer somewhere else so you will need to delete it manually.");
                return;
            }

            if (!EditorUtility.DisplayDialog("Delete Animancer?",
                                             "Would you like to delete " + AnimancerDirectory + "?" +
                                             "\n\nYou will then need to reimport Animancer manually.",
                                             "Delete", "Cancel"))
            {
                return;
            }

            AssetDatabase.DeleteAsset(AnimancerDirectory);
            Close();
            File.Delete(LockFile);
        }
예제 #2
0
        /************************************************************************************************************************/

        private void DoLayerWeightWarningGUI()
        {
            for (int i = 0; i < _LayerCount; i++)
            {
                var layer = LayerInfos[i].Layer;
                if (layer.Weight == 1 &&
                    !layer.IsAdditive &&
                    layer._Mask == null &&
                    Mathf.Approximately(layer.GetTotalWeight(), 1))
                {
                    return;
                }
            }

            EditorGUILayout.HelpBox(
                "There are no Override layers at weight 1, which will likely give undesirable results." +
                " Click here for more information.",
                MessageType.Warning);

            if (AnimancerEditorUtilities.TryUseClickInLastRect())
            {
                EditorUtility.OpenWithDefaultApp(
                    AnimancerPlayable.APIDocumentationURL + "/docs/manual/smooth-transitions");
            }
        }
예제 #3
0
        /************************************************************************************************************************/

        private void DoAnimatorGUI()
        {
            var hasAnimator = AnimatorProperty.objectReferenceValue != null;

            var color = GUI.color;

            if (!hasAnimator)
            {
                GUI.color = AnimancerEditorUtilities.WarningFieldColor;
            }

            EditorGUILayout.PropertyField(AnimatorProperty);

            if (!hasAnimator)
            {
                GUI.color = color;

                EditorGUILayout.HelpBox("An Animator is required in order to play animations." +
                                        " Click here to search for one nearby.",
                                        MessageType.Warning);

                if (AnimancerEditorUtilities.TryUseClickInLastRect())
                {
                    AnimancerEditorUtilities.ForEachTarget(AnimatorProperty, (property) =>
                    {
                        var target = (IAnimancerComponent)property.serializedObject.targetObject;

                        // Can't use AnimancerEditorUtilities.GetComponentInHierarchy
                        // because Animancer Lite leaves it outside the DLL.
                        var animator = target.gameObject.GetComponentInParent <Animator>();
                        if (animator == null)
                        {
                            animator = target.gameObject.GetComponentInChildren <Animator>();
                            if (animator == null)
                            {
                                Debug.Log("No Animator found on '" + target + "' or any of its parents or children." +
                                          " You must assign one manually.", target.gameObject);
                                return;
                            }
                        }

                        property.objectReferenceValue = animator;
                    });
                }
            }
        }
예제 #4
0
        /************************************************************************************************************************/

        /// <summary>Draws all states in the given layer.</summary>
        public void DoInspectorGUI(IAnimancerComponent owner)
        {
            AnimancerEditorUtilities.BeginVerticalBox(GUI.skin.box);

            DoHeaderGUI();

            if (HideInactiveStates)
            {
                DoStatesGUI("Active States", ActiveStates, owner);
            }
            else if (SeparateActiveFromInactiveStates)
            {
                DoStatesGUI("Active States", ActiveStates, owner);
                DoStatesGUI("Inactive States", InactiveStates, owner);
            }
            else
            {
                DoStatesGUI("States", ActiveStates, owner);
            }

            if (Layer.PortIndex == 0 &&
                Layer.Weight != 0 &&
                !Layer.IsAdditive &&
                !Mathf.Approximately(Layer.GetTotalWeight(), 1))
            {
                EditorGUILayout.HelpBox(
                    "The total Weight of all states in this layer does not equal 1, which will likely give undesirable results." +
                    " Click here for more information.",
                    MessageType.Warning);

                if (AnimancerEditorUtilities.TryUseClickInLastRect())
                {
                    EditorUtility.OpenWithDefaultApp(
                        AnimancerPlayable.APIDocumentationURL + "/docs/manual/smooth-transitions");
                }
            }

            AnimancerEditorUtilities.EndVerticalBox(GUI.skin.box);

            var totalArea = GUILayoutUtility.GetLastRect();

            HandleDragAndDropAnimations(totalArea, owner, Layer.PortIndex);
            CheckContextMenu(totalArea);
        }
예제 #5
0
        /************************************************************************************************************************/

        /// <summary>
        /// Draws the <see cref="Animator.updateMode"/> field with any appropriate warnings.
        /// </summary>
        private void DoUpdateModeGUI(bool showWithoutWarning)
        {
            if (_UpdateMode == null)
            {
                return;
            }

            var label = AnimancerEditorUtilities.TempContent("Update Mode",
                                                             "Controls when and how often the animations are updated");

            var initialUpdateMode = Targets[0].InitialUpdateMode;
            var updateMode        = (AnimatorUpdateMode)_UpdateMode.intValue;

            EditorGUI.BeginChangeCheck();

            if (!EditorApplication.isPlaying || !AnimancerPlayable.HasChangedToOrFromAnimatePhysics(initialUpdateMode, updateMode))
            {
                if (showWithoutWarning)
                {
                    EditorGUILayout.PropertyField(_UpdateMode, label);
                }
            }
            else
            {
                GUILayout.BeginHorizontal();

                var color = GUI.color;
                GUI.color = AnimancerEditorUtilities.WarningFieldColor;
                EditorGUILayout.PropertyField(_UpdateMode, label);
                GUI.color = color;

                label = AnimancerEditorUtilities.TempContent("Revert", "Revert to initial mode");
                if (GUILayout.Button(label, EditorStyles.miniButton, AnimancerEditorUtilities.DontExpandWidth))
                {
                    _UpdateMode.intValue = (int)initialUpdateMode.Value;
                }

                GUILayout.EndHorizontal();

                EditorGUILayout.HelpBox(
                    "Changing to or from AnimatePhysics mode at runtime has no effect when using the" +
                    " Playables API. It will continue using the original mode it had on startup.",
                    MessageType.Warning);

                if (AnimancerEditorUtilities.TryUseClickInLastRect())
                {
                    EditorUtility.OpenWithDefaultApp(AnimancerPlayable.APIDocumentationURL + "/docs/unity-bugs/update-modes");
                }
            }

            if (EditorGUI.EndChangeCheck())
            {
                _OnEndGUI += () =>
                {
                    for (int i = 0; i < _Animators.Length; i++)
                    {
                        var animator = _Animators[i];
                        if (animator != null)
                        {
                            AnimancerEditorUtilities.Invoke(animator, "OnUpdateModeChanged");
                        }
                    }
                };
            }
        }
예제 #6
0
        /************************************************************************************************************************/

        /// <summary>
        /// Draws the <see cref="Animator.runtimeAnimatorController"/> field with a warning if a controller is
        /// assigned.
        /// </summary>
        private void DoControllerGUI()
        {
            if (_Controller == null)
            {
                return;
            }

            var controller = _Animators[0].runtimeAnimatorController;

            var showMixedValue = EditorGUI.showMixedValue;

            for (int i = 1; i < _Animators.Length; i++)
            {
                if (_Animators[i].runtimeAnimatorController != controller)
                {
                    EditorGUI.showMixedValue = true;
                    break;
                }
            }

            if (controller == null && !EditorGUI.showMixedValue)
            {
                return;
            }

            var label = AnimancerEditorUtilities.TempContent("Controller");

            EditorGUI.BeginChangeCheck();

            var area = EditorGUILayout.BeginHorizontal();

            label = EditorGUI.BeginProperty(area, label, _Controller);

            var color = GUI.color;

            GUI.color = AnimancerEditorUtilities.WarningFieldColor;

            controller = (RuntimeAnimatorController)EditorGUILayout.ObjectField(label, controller,
                                                                                typeof(RuntimeAnimatorController), false);

            GUI.color = color;

            if (GUILayout.Button("Remove", EditorStyles.miniButton, AnimancerEditorUtilities.DontExpandWidth))
            {
                controller = null;
            }

            GUILayout.EndHorizontal();
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObjects(_Animators, "Changed AnimatorController");
                for (int i = 0; i < _Animators.Length; i++)
                {
                    _Animators[i].runtimeAnimatorController = controller;
                }
                OnControllerChanged();
            }

            EditorGUI.showMixedValue = showMixedValue;

            EditorGUILayout.HelpBox(
                "The AnimatorController will not affect the model while Animancer is active," +
                " however Unity will still execute it's state machine in the background," +
                " which may be a waste of processing time if you aren't using it intentionally." +
                " Click here for more information.", MessageType.Warning);

            if (AnimancerEditorUtilities.TryUseClickInLastRect())
            {
                EditorUtility.OpenWithDefaultApp(AnimancerPlayable.APIDocumentationURL + "/docs/manual/animator-controller-states");
            }
        }