/************************************************************************************************************************/
        #region Context Menu
        /************************************************************************************************************************/

        /// <summary>Adds functions relevant to the <see cref="AnimancerNodeDrawer{T}.Target"/>.</summary>
        protected override void PopulateContextMenu(GenericMenu menu)
        {
            menu.AddDisabledItem(new GUIContent(DetailsPrefix + "CurrentState: " + Target.CurrentState));
            menu.AddDisabledItem(new GUIContent(DetailsPrefix + "CommandCount: " + Target.CommandCount));

            AnimancerEditorUtilities.AddMenuItem(menu, "Stop",
                                                 HasAnyStates((state) => state.IsPlaying || state.Weight != 0),
                                                 () => Target.Stop());

            AnimancerEditorUtilities.AddFadeFunction(menu, "Fade In",
                                                     Target.Index > 0 && Target.Weight != 1, Target,
                                                     (duration) => Target.StartFade(1, duration));
            AnimancerEditorUtilities.AddFadeFunction(menu, "Fade Out",
                                                     Target.Index > 0 && Target.Weight != 0, Target,
                                                     (duration) => Target.StartFade(0, duration));

            AnimancerEditorUtilities.AddContextMenuIK(menu, Target);

            menu.AddSeparator("");

            AnimancerEditorUtilities.AddMenuItem(menu, "Destroy States",
                                                 ActiveStates.Count > 0 || InactiveStates.Count > 0,
                                                 () => Target.DestroyStates());

            AnimancerPlayableDrawer.AddRootFunctions(menu, Target.Root);

            menu.AddSeparator("");

            AnimancerPlayableDrawer.AddDisplayOptions(menu);

            AnimancerEditorUtilities.AddDocumentationLink(menu, "Layer Documentation", "/docs/manual/blending/layers");

            menu.ShowAsContext();
        }
Example #2
0
        /************************************************************************************************************************/
        #region Context Menu
        /************************************************************************************************************************/

        /// <summary>Adds functions relevant to the <see cref="AnimancerNodeDrawer{T}.Target"/>.</summary>
        protected override void PopulateContextMenu(GenericMenu menu)
        {
            AddContextMenuFunctions(menu);

            AnimancerEditorUtilities.AddMenuItem(menu, "Play",
                                                 !Target.IsPlaying || Target.Weight != 1,
                                                 () =>
            {
                Target.Root.UnpauseGraph();
                Target.Root.Play(Target);
            });

            AnimancerEditorUtilities.AddFadeFunction(menu, "Cross Fade (Ctrl + Click)",
                                                     Target.Weight != 1,
                                                     Target, (duration) =>
            {
                Target.Root.UnpauseGraph();
                Target.Root.Play(Target, duration);
            });

            AnimancerEditorUtilities.AddFadeFunction(menu, "Cross Fade Queued (Ctrl + Shift + Click)",
                                                     Target.Weight != 1,
                                                     Target, (duration) =>
            {
                AnimationQueue.CrossFadeQueued(Target);
            });

            menu.AddSeparator("");
            menu.AddItem(new GUIContent("Destroy State"), false, () => Target.Destroy());

            menu.AddSeparator("");
            AnimancerEditorUtilities.AddDocumentationLink(menu, "State Documentation", "/docs/manual/states");
        }
Example #3
0
        /************************************************************************************************************************/

        /// <summary>Adds the details of this state to the menu.</summary>
        protected virtual void AddContextMenuFunctions(GenericMenu menu)
        {
            menu.AddDisabledItem(new GUIContent(DetailsPrefix + "Key: " + Target.Key));

            var length = Target.Length;

            if (!float.IsNaN(length))
            {
                menu.AddDisabledItem(new GUIContent(DetailsPrefix + "Length: " + length));
            }

            menu.AddDisabledItem(new GUIContent(DetailsPrefix + "Playable Path: " + Target.GetPath()));

            var mainAsset = Target.MainObject;

            if (mainAsset != null)
            {
                var assetPath = AssetDatabase.GetAssetPath(mainAsset);
                if (assetPath != null)
                {
                    menu.AddDisabledItem(new GUIContent(DetailsPrefix + "Asset Path: " + assetPath.Replace("/", "->")));
                }
            }

            const string OnEndPrefix = "End Event/";
            {
                var endEvent = Target.Events.endEvent;
                menu.AddDisabledItem(new GUIContent(OnEndPrefix + "NormalizedTime: " + endEvent.normalizedTime));

                if (endEvent.callback == null)
                {
                    menu.AddDisabledItem(new GUIContent(OnEndPrefix + "Callback: null"));
                }
                else
                {
                    var label = OnEndPrefix +
                                (endEvent.callback.Target != null ? ("Target: " + endEvent.callback.Target) : "Target: null");

                    var targetObject = endEvent.callback.Target as Object;
                    AnimancerEditorUtilities.AddMenuItem(menu, label,
                                                         targetObject != null,
                                                         () => Selection.activeObject = targetObject);

                    menu.AddDisabledItem(new GUIContent(
                                             OnEndPrefix + "Declaring Type: " + endEvent.callback.Method.DeclaringType.FullName));

                    menu.AddDisabledItem(new GUIContent(
                                             OnEndPrefix + "Method: " + endEvent.callback.Method));
                }

                AnimancerEditorUtilities.AddMenuItem(menu, OnEndPrefix + "Clear",
                                                     !float.IsNaN(endEvent.normalizedTime) || endEvent.callback != null,
                                                     () => Target.Events.endEvent = new AnimancerEvent(float.NaN, null));

                AnimancerEditorUtilities.AddMenuItem(menu, OnEndPrefix + "Invoke",
                                                     endEvent.callback != null,
                                                     () => Target.Events.endEvent.Invoke(Target));
            }
        }
        /************************************************************************************************************************/
        #region Context Menu
        /************************************************************************************************************************/

        /// <summary>Adds functions relevant to the <see cref="AnimancerNodeDrawer{T}.Target"/>.</summary>
        protected override void PopulateContextMenu(GenericMenu menu)
        {
            menu.AddDisabledItem(new GUIContent(DetailsPrefix + "CurrentState: " + Target.CurrentState));
            menu.AddDisabledItem(new GUIContent(DetailsPrefix + "CommandCount: " + Target.CommandCount));

            AnimancerEditorUtilities.AddMenuItem(menu, "Stop",
                                                 HasAnyStates((state) => state.IsPlaying || state.Weight != 0),
                                                 () => Target.Stop());

            AnimancerEditorUtilities.AddFadeFunction(menu, "Fade In",
                                                     Target.Index > 0 && Target.Weight != 1, Target,
                                                     (duration) => Target.StartFade(1, duration));
            AnimancerEditorUtilities.AddFadeFunction(menu, "Fade Out",
                                                     Target.Index > 0 && Target.Weight != 0, Target,
                                                     (duration) => Target.StartFade(0, duration));

            menu.AddItem(new GUIContent("Inverse Kinematics/Apply Animator IK"),
                         Target.ApplyAnimatorIK,
                         () => Target.ApplyAnimatorIK = !Target.ApplyAnimatorIK);
            menu.AddItem(new GUIContent("Inverse Kinematics/Default Apply Animator IK"),
                         Target.DefaultApplyAnimatorIK,
                         () => Target.DefaultApplyAnimatorIK = !Target.DefaultApplyAnimatorIK);
            menu.AddItem(new GUIContent("Inverse Kinematics/Apply Foot IK"),
                         Target.ApplyFootIK,
                         () => Target.ApplyFootIK = !Target.ApplyFootIK);
            menu.AddItem(new GUIContent("Inverse Kinematics/Default Apply Foot IK"),
                         Target.DefaultApplyFootIK,
                         () => Target.DefaultApplyFootIK = !Target.DefaultApplyFootIK);

            menu.AddSeparator("");

            AnimancerEditorUtilities.AddMenuItem(menu, "Destroy States",
                                                 ActiveStates.Count > 0 || InactiveStates.Count > 0,
                                                 () => Target.DestroyStates());

            AnimancerEditorUtilities.AddMenuItem(menu, "Add Layer",
                                                 Target.Root.Layers.Count < AnimancerPlayable.LayerList.defaultCapacity,
                                                 () => Target.Root.Layers.Count++);
            AnimancerEditorUtilities.AddMenuItem(menu, "Remove Layer",
                                                 Target.Root.Layers.Count > 0,
                                                 () => Target.Root.Layers.Count--);

            menu.AddSeparator("");

            menu.AddItem(new GUIContent("Keep Weightless Playables Connected"),
                         Target.Root.KeepChildrenConnected,
                         () => Target.Root.KeepChildrenConnected = !Target.Root.KeepChildrenConnected);

            AddPrefFunctions(menu);

            menu.AddSeparator("");

            AnimancerEditorUtilities.AddDocumentationLink(menu, "Layer Documentation", "/docs/manual/blending/layers");

            menu.ShowAsContext();
        }
        /************************************************************************************************************************/

        /// <summary>Adds functions for controlling the `playable`.</summary>
        public static void AddRootFunctions(GenericMenu menu, AnimancerPlayable playable)
        {
            AnimancerEditorUtilities.AddMenuItem(menu, "Add Layer",
                                                 playable.Layers.Count < AnimancerPlayable.LayerList.DefaultCapacity,
                                                 () => playable.Layers.Count++);
            AnimancerEditorUtilities.AddMenuItem(menu, "Remove Layer",
                                                 playable.Layers.Count > 0,
                                                 () => playable.Layers.Count--);

            menu.AddItem(new GUIContent("Keep Children Connected ?"),
                         playable.KeepChildrenConnected,
                         () => playable.KeepChildrenConnected = !playable.KeepChildrenConnected);
        }
Example #6
0
        /************************************************************************************************************************/

        /// <summary>Adds a menu function to open the Playable Graph Visualiser if it exists in the project.</summary>
        public static void AddPlayableGraphVisualizerFunction(GenericMenu menu, string prefix, PlayableGraph graph)
        {
            var type = Type.GetType("GraphVisualizer.PlayableGraphVisualizerWindow, Unity.PlayableGraphVisualizer.Editor");

            AnimancerEditorUtilities.AddMenuItem(menu, prefix + "Playable Graph Visualizer", type != null, () =>
            {
                var window = EditorWindow.GetWindow(type);

                var field = type.GetField("m_CurrentGraph", AnimancerEditorUtilities.AnyAccessBindings);

                if (field != null)
                {
                    field.SetValue(window, graph);
                }
            });
        }
Example #7
0
        /************************************************************************************************************************/

        private void AddPlayableGraphVisualizerFunction(GenericMenu menu)
        {
            var type = Type.GetType("GraphVisualizer.PlayableGraphVisualizerWindow," +
                                    " Unity.PlayableGraphVisualizer.Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");

            AnimancerEditorUtilities.AddMenuItem(menu, DetailsPrefix + "Playable Graph Visualizer", type != null, () =>
            {
                var window = EditorWindow.GetWindow(type);

                var field = type.GetField("m_CurrentGraph",
                                          BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

                if (field != null)
                {
                    field.SetValue(window, Target.Root._Graph);
                }
            });
        }
        /************************************************************************************************************************/

        /// <summary>[Editor-Only]
        /// Adds the details of this state to the menu.
        /// By default, that means a single item showing the path of the <see cref="AnimancerState.MainObject"/>.
        /// </summary>
        protected virtual void AddContextMenuFunctions(GenericMenu menu)
        {
            if (State.HasLength)
            {
                menu.AddDisabledItem(new GUIContent(DetailsPrefix + "Length: " + State.Length));
            }

            menu.AddDisabledItem(new GUIContent(DetailsPrefix + "Playable Path: " + State.GetPath()));

            var mainAsset = State.MainObject;

            if (mainAsset != null)
            {
                var assetPath = AssetDatabase.GetAssetPath(mainAsset);
                if (assetPath != null)
                {
                    menu.AddDisabledItem(new GUIContent(DetailsPrefix + "Asset Path: " + assetPath.Replace("/", "->")));
                }
            }

            if (State.OnEnd != null)
            {
                const string OnEndPrefix = "On End/";

                var label = OnEndPrefix +
                            (State.OnEnd.Target != null ? ("Target: " + State.OnEnd.Target) : "Target: null");

                var targetObject = State.OnEnd.Target as Object;
                AnimancerEditorUtilities.AddMenuItem(menu, label,
                                                     targetObject != null,
                                                     () => Selection.activeObject = targetObject);

                menu.AddDisabledItem(new GUIContent(OnEndPrefix + "Declaring Type: " + State.OnEnd.Method.DeclaringType.FullName));
                menu.AddDisabledItem(new GUIContent(OnEndPrefix + "Method: " + State.OnEnd.Method));

                menu.AddItem(new GUIContent(OnEndPrefix + "Clear"), false, () => State.OnEnd = null);
                menu.AddItem(new GUIContent(OnEndPrefix + "Invoke"), false, () => State.OnEnd());
            }
        }
        /// <summary>
        /// Checks if the current event is a context menu click within the 'clickArea' and opens a context menu with various
        /// functions for the <see cref="State"/>.
        /// </summary>
        protected void CheckContextMenu(Rect clickArea)
        {
            if (!AnimancerEditorUtilities.TryUseContextClick(clickArea))
            {
                return;
            }

            var menu = new GenericMenu();

            menu.AddDisabledItem(new GUIContent(DetailsPrefix + "State: " + State.ToString()));

            var key = State.Key;

            if (key != null)
            {
                menu.AddDisabledItem(new GUIContent(DetailsPrefix + "Key: " + key));
            }

            AnimancerEditorUtilities.AddMenuItem(menu, "Play",
                                                 !State.IsPlaying || State.Weight != 1,
                                                 () => State.Root.Play(State));

            AnimancerEditorUtilities.AddFadeFunction(menu, "Cross Fade (Ctrl + Click)",
                                                     State.Weight != 1,
                                                     State, (duration) => State.Root.CrossFade(State, duration));

            AddContextMenuFunctions(menu);

            menu.AddItem(new GUIContent(DetailsPrefix + "Log Details"), false,
                         () => Debug.Log("AnimancerState: " + State.GetDescription(true)));

            menu.AddSeparator("");
            menu.AddItem(new GUIContent("Destroy State"), false, () => State.Dispose());

            menu.AddSeparator("");
            AnimancerEditorUtilities.AddDocumentationLink(menu, "State Documentation", "/docs/manual/animancer-states");

            menu.ShowAsContext();
        }
Example #10
0
        /************************************************************************************************************************/
        #region Context Menu
        /************************************************************************************************************************/

        /// <summary>
        /// Checks if the current event is a context menu click within the 'clickArea' and opens a context menu with various
        /// functions for the <see cref="Layer"/>.
        /// </summary>
        private void CheckContextMenu(Rect clickArea)
        {
            if (!AnimancerEditorUtilities.TryUseContextClick(clickArea))
            {
                return;
            }

            var menu = new GenericMenu();

            menu.AddDisabledItem(new GUIContent(Layer.ToString()));

            AnimancerEditorUtilities.AddMenuItem(menu, "Stop",
                                                 HasAnyStates((state) => state.IsPlaying || state.Weight != 0),
                                                 () => Layer.Stop());

            AnimancerEditorUtilities.AddFadeFunction(menu, "Fade In",
                                                     Layer.PortIndex > 0 && Layer.Weight != 1, Layer,
                                                     (duration) => Layer.StartFade(1, duration));
            AnimancerEditorUtilities.AddFadeFunction(menu, "Fade Out",
                                                     Layer.PortIndex > 0 && Layer.Weight != 0, Layer,
                                                     (duration) => Layer.StartFade(0, duration));

            menu.AddItem(new GUIContent("Inverse Kinematics/Apply Animator IK"),
                         Layer.ApplyAnimatorIK,
                         () => Layer.ApplyAnimatorIK = !Layer.ApplyAnimatorIK);
            menu.AddItem(new GUIContent("Inverse Kinematics/Default Apply Animator IK"),
                         Layer.DefaultApplyAnimatorIK,
                         () => Layer.DefaultApplyAnimatorIK = !Layer.DefaultApplyAnimatorIK);
            menu.AddItem(new GUIContent("Inverse Kinematics/Apply Foot IK"),
                         Layer.ApplyFootIK,
                         () => Layer.ApplyFootIK = !Layer.ApplyFootIK);
            menu.AddItem(new GUIContent("Inverse Kinematics/Default Apply Foot IK"),
                         Layer.DefaultApplyFootIK,
                         () => Layer.DefaultApplyFootIK = !Layer.DefaultApplyFootIK);

            menu.AddSeparator("");

            AnimancerEditorUtilities.AddMenuItem(menu, "Destroy States",
                                                 ActiveStates.Count > 0 || InactiveStates.Count > 0,
                                                 () => Layer.DestroyStates());

            AnimancerEditorUtilities.AddMenuItem(menu, "Add Layer",
                                                 Layer.Root.LayerCount < AnimancerPlayable.maxLayerCount,
                                                 () => Layer.Root.LayerCount++);
            AnimancerEditorUtilities.AddMenuItem(menu, "Remove Layer",
                                                 Layer.Root.LayerCount > 0,
                                                 () => Layer.Root.LayerCount--);

            menu.AddSeparator("");

            menu.AddItem(new GUIContent("Keep Weightless Playables Connected"),
                         Layer.Root.KeepPlayablesConnected,
                         () => Layer.Root.KeepPlayablesConnected = !Layer.Root.KeepPlayablesConnected);

            AddPrefFunctions(menu);

            menu.AddSeparator("");

            AnimancerEditorUtilities.AddDocumentationLink(menu, "Layer Documentation", "/docs/manual/animation-layers");
            AddPlayableGraphVisualizerFunction(menu);

            menu.ShowAsContext();
        }