diff --git a/Assets/GraphVisualizer/Clients/GraphVisualizerClient.cs b/Assets/GraphVisualizer/Clients/GraphVisualizerClient.cs index 120619d..f436187 100644 --- a/Assets/GraphVisualizer/Clients/GraphVisualizerClient.cs +++ b/Assets/GraphVisualizer/Clients/GraphVisualizerClient.cs @@ -8,7 +8,7 @@ public class GraphVisualizerClient { private static GraphVisualizerClient s_Instance; - private Dictionary m_Graphs = new Dictionary(); + private List m_Graphs = new List(); public static GraphVisualizerClient instance { @@ -19,26 +19,29 @@ public static GraphVisualizerClient instance return s_Instance; } } + ~GraphVisualizerClient() { m_Graphs.Clear(); } - public static void Show(PlayableGraph graph, string name) + + public static void Show(PlayableGraph graph) { - if (!instance.m_Graphs.ContainsKey(graph)) + if (!instance.m_Graphs.Contains(graph)) { - instance.m_Graphs.Add(graph, name); + instance.m_Graphs.Add(graph); } } + public static void Hide(PlayableGraph graph) { - if (instance.m_Graphs.ContainsKey(graph)) + if (instance.m_Graphs.Contains(graph)) { instance.m_Graphs.Remove(graph); } } - public static IEnumerable> GetGraphs() + public static IEnumerable GetGraphs() { return instance.m_Graphs; } diff --git a/Assets/GraphVisualizer/Editor/PlayableGraphVisualizerWindow.cs b/Assets/GraphVisualizer/Editor/PlayableGraphVisualizerWindow.cs index 64b7669..11f2a5e 100644 --- a/Assets/GraphVisualizer/Editor/PlayableGraphVisualizerWindow.cs +++ b/Assets/GraphVisualizer/Editor/PlayableGraphVisualizerWindow.cs @@ -8,63 +8,58 @@ public class PlayableGraphVisualizerWindow : EditorWindow, IHasCustomMenu { - private struct PlayableGraphInfo - { - public PlayableGraph graph; - public string name; - } - private IGraphRenderer m_Renderer; private IGraphLayout m_Layout; - private PlayableGraphInfo m_CurrentGraphInfo; + private List m_Graphs; + private PlayableGraph m_CurrentGraph; private GraphSettings m_GraphSettings; - private bool m_AutoScanScene = true; - #region Configuration +#region Configuration private static readonly float s_ToolbarHeight = 17f; private static readonly float s_DefaultMaximumNormalizedNodeSize = 0.8f; private static readonly float s_DefaultMaximumNodeSizeInPixels = 100.0f; private static readonly float s_DefaultAspectRatio = 1.5f; - #endregion +#endregion + private PlayableGraphVisualizerWindow() { m_GraphSettings.maximumNormalizedNodeSize = s_DefaultMaximumNormalizedNodeSize; m_GraphSettings.maximumNodeSizeInPixels = s_DefaultMaximumNodeSizeInPixels; m_GraphSettings.aspectRatio = s_DefaultAspectRatio; m_GraphSettings.showLegend = true; - m_AutoScanScene = true; } [MenuItem("Window/PlayableGraph Visualizer")] public static void ShowWindow() { - GetWindow("Playable Graph Visualizer"); + GetWindow("PlayableGraph Visualizer"); } - private PlayableGraphInfo GetSelectedGraphInToolBar(IList graphs, PlayableGraphInfo currentGraph) + private PlayableGraph GetSelectedGraphInToolBar(List graphs, PlayableGraph currentGraph) { EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.Width(position.width)); - List options = new List(graphs.Count);// = graphs.Select(d => d.ToString()).ToArray(); - foreach (var g in graphs) + List options = new List(graphs.Count); + foreach (var graph in graphs) { - options.Add(g.name); + string name = graph.GetEditorName(); + options.Add(name.Length != 0 ? name : "[Unnamed]"); } int currentSelection = graphs.IndexOf(currentGraph); int newSelection = EditorGUILayout.Popup(currentSelection != -1 ? currentSelection : 0, options.ToArray(), GUILayout.Width(200)); - PlayableGraphInfo selectedDirector = new PlayableGraphInfo(); + PlayableGraph selectedGraph = new PlayableGraph(); if (newSelection != -1) - selectedDirector = graphs[newSelection]; + selectedGraph = graphs[newSelection]; GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); - return selectedDirector; + return selectedGraph; } private static void ShowMessage(string msg) @@ -98,78 +93,52 @@ void OnInspectorUpdate() Repaint(); } - void OnGUI() + void OnEnable() { - // Create a list of all the playable graphs extracted. - IList graphInfos = new List(); + m_Graphs = new List(UnityEditor.Playables.Utility.GetAllGraphs()); - PlayableGraphInfo info; + UnityEditor.Playables.Utility.graphCreated += OnGraphCreated; + UnityEditor.Playables.Utility.destroyingGraph += OnDestroyingGraph; + } - // If we requested, we extract automatically the PlayableGraphs from all the components - // that are in the current scene. - if (m_AutoScanScene) - { - // This code could be generalized, maybe if we added a IHasPlayableGraph Interface. - IList directors = FindObjectsOfType(); - if (directors != null) - { - foreach (var director in directors) - { - if (director.playableGraph.IsValid()) - { - info.name = director.name; - info.graph = director.playableGraph; - graphInfos.Add(info); - } - } - } - - IList animators = FindObjectsOfType(); - if (animators != null) - { - foreach (var animator in animators) - { - if (animator.playableGraph.IsValid()) - { - info.name = animator.name; - info.graph = animator.playableGraph; - graphInfos.Add(info); - } - } - } - } + void OnGraphCreated(PlayableGraph graph) + { + if (!m_Graphs.Contains(graph)) + m_Graphs.Add(graph); + } - if (GraphVisualizerClient.GetGraphs() != null) - { - foreach (var clientGraph in GraphVisualizerClient.GetGraphs()) - { - if (clientGraph.Key.IsValid()) - { - info.name = clientGraph.Value; - info.graph = clientGraph.Key; - graphInfos.Add(info); - } - } - } + void OnDestroyingGraph(PlayableGraph graph) + { + m_Graphs.Remove(graph); + } + void OnDisable() + { + UnityEditor.Playables.Utility.graphCreated -= OnGraphCreated; + UnityEditor.Playables.Utility.destroyingGraph -= OnDestroyingGraph; + } + + void OnGUI() + { // Early out if there is no graphs. - if (graphInfos.Count == 0) + var selectedGraphs = GetGraphList(); + if (selectedGraphs.Count == 0) { ShowMessage("No PlayableGraph in the scene"); return; } GUILayout.BeginVertical(); - m_CurrentGraphInfo = GetSelectedGraphInToolBar(graphInfos, m_CurrentGraphInfo); + m_CurrentGraph = GetSelectedGraphInToolBar(selectedGraphs, m_CurrentGraph); GUILayout.EndVertical(); - if (!m_CurrentGraphInfo.graph.IsValid()) + if (!m_CurrentGraph.IsValid()) { ShowMessage("Selected PlayableGraph is invalid"); return; } - var graph = new PlayableGraphVisualizer(m_CurrentGraphInfo.graph); + var graph = new PlayableGraphVisualizer(m_CurrentGraph); graph.Refresh(); if (graph.IsEmpty()) @@ -191,21 +160,32 @@ void OnGUI() m_Renderer.Draw(m_Layout, graphRect, m_GraphSettings); } + private List GetGraphList() + { + var selectedGraphs = new List(); + foreach (var clientGraph in GraphVisualizerClient.GetGraphs()) + { + if (clientGraph.IsValid()) + selectedGraphs.Add(clientGraph); + } + + if (selectedGraphs.Count == 0) + selectedGraphs = m_Graphs.ToList(); + + return selectedGraphs; + } + #region Custom_Menu public virtual void AddItemsToMenu(GenericMenu menu) { menu.AddItem(new GUIContent("Legend"), m_GraphSettings.showLegend, ToggleLegend); - menu.AddItem(new GUIContent("Auto Scan Scene"), m_AutoScanScene, ToggleAutoScanScene); } + void ToggleLegend() { m_GraphSettings.showLegend = !m_GraphSettings.showLegend; } - void ToggleAutoScanScene() - { - m_AutoScanScene = !m_AutoScanScene; - } #endregion } diff --git a/README.md b/README.md index b20a2d3..3450a23 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,29 @@ -# PlayableGraph Visualizer # -## Introduction ## -The PlayableGraph Visualizer window can be used to display any *PlayableGraph*. +# PlayableGraph Visualizer + +## Introduction + +The PlayableGraph Visualizer window can be used to display any `PlayableGraph`. The tool can be used in both Play and Edit mode and will always reflect the current state of the graph. Playable Handles in the graph are represented by colored nodes, varying according to their type. Wire color intensity indicates the local weight of the blending. -## Setup ## + +## Setup + - Download the release that matches your current Unity version, or the latest if there your Unity version is more recent than the latest release. - Copy the content of this repos Asset folder into a the Asset folder of an Unity Project. You will need to do this for every project. -## Window ## + +## Window + - You can open the Timeline Visualizer in **Window > PlayableGraph Visualizer**. -## Usage ## -- Open any scene that contains at least one *PlayableGraph*. -- Register your *PlayableGraph* with the method GraphVisualizerClient.Show(PlayableGraph, string). -- Select the *PlayableGraph* to display in the top-left combo box. + +## Usage + +- Open any scene that contains at least one `PlayableGraph`. +- By default, all the `PlayableGraph`s of your scene will be listed in the editor's top-left list. + - You can show just your `PlayableGraph` using `GraphVisualizerClient.Show(PlayableGraph)`. +- Select the `PlayableGraph` to display in the top-left list. - Click on a Node to display more information about the associated Playable Handle. -## Notes ## -- This tool was previously named Timeline Visualizer, but was renamed as we are refactoring it to support *PlayableGraph* stored in different types of component. -- If your *PlayableGraph* is only available in Play mode, you will not be able to see it in Edit mode. + +## Notes + +- This tool was previously named Timeline Visualizer, but was renamed as we are refactoring it to support `PlayableGraph` stored in different types of component. +- If your `PlayableGraph` is only available in Play mode, you will not be able to see it in Edit mode.