Skip to content

Commit 1baed78

Browse files
committed
feat: text mode
1 parent ccf6537 commit 1baed78

10 files changed

Lines changed: 296 additions & 0 deletions

Editor.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "GBG.PlayableGraphMonitor.Editor",
3+
"rootNamespace": "GBG.PlayableGraphMonitor.Editor",
4+
"references": [],
5+
"includePlatforms": [],
6+
"excludePlatforms": [],
7+
"allowUnsafeCode": false,
8+
"overrideReferences": false,
9+
"precompiledReferences": [],
10+
"autoReferenced": true,
11+
"defineConstraints": [],
12+
"versionDefines": [],
13+
"noEngineReferences": false
14+
}

Editor/GBG.PlayableGraphMonitor.Editor.asmdef.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Editor/Scripts.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
using System.Collections.Generic;
2+
using UnityEditor;
3+
using UnityEditor.Playables;
4+
using UnityEngine;
5+
using UnityEngine.Animations;
6+
using UnityEngine.Assertions;
7+
using UnityEngine.Playables;
8+
using PlayableUtility = UnityEditor.Playables.Utility;
9+
10+
namespace GBG.PlayableGraphMonitor.Editor
11+
{
12+
public class PlayableGraphMonitorWindow : EditorWindow
13+
{
14+
[MenuItem("Window/Analysis/PlayableGraph Monitor")]
15+
public static PlayableGraphMonitorWindow Open()
16+
{
17+
return GetWindow<PlayableGraphMonitorWindow>("Playable Graph Monitor");
18+
}
19+
20+
21+
private readonly List<PlayableGraph> _graphs = new List<PlayableGraph>();
22+
23+
private string[] _graphPopupMenuItems;
24+
25+
private int _selectedGraphNumber;
26+
27+
private PlayableGraph? _selectedGraph;
28+
29+
private Vector2 _graphListScrollPos;
30+
31+
private GUIStyle _labelStyle;
32+
33+
34+
private void OnEnable()
35+
{
36+
_graphs.AddRange(PlayableUtility.GetAllGraphs());
37+
UpdateGraphPopupMenuItems();
38+
39+
PlayableUtility.graphCreated += OnGraphCreated;
40+
PlayableUtility.destroyingGraph += OnDestroyingGraph;
41+
}
42+
43+
private void OnDisable()
44+
{
45+
PlayableUtility.graphCreated -= OnGraphCreated;
46+
PlayableUtility.destroyingGraph -= OnDestroyingGraph;
47+
}
48+
49+
private void OnGUI()
50+
{
51+
PrepareStyles();
52+
53+
DrawGraphDropdownList();
54+
55+
DrawGraphs();
56+
}
57+
58+
private void Update()
59+
{
60+
Repaint();
61+
}
62+
63+
private void PrepareStyles()
64+
{
65+
if (_labelStyle == null)
66+
{
67+
_labelStyle = new GUIStyle(GUI.skin.label)
68+
{
69+
richText = true
70+
};
71+
}
72+
}
73+
74+
private void DrawGraphDropdownList()
75+
{
76+
EditorGUI.BeginChangeCheck();
77+
_selectedGraphNumber = EditorGUILayout.Popup(_selectedGraphNumber, _graphPopupMenuItems);
78+
if (EditorGUI.EndChangeCheck())
79+
{
80+
_selectedGraph = _selectedGraphNumber == 0 ? null : _graphs[_selectedGraphNumber - 1];
81+
}
82+
}
83+
84+
private void DrawGraphs()
85+
{
86+
_graphListScrollPos = GUILayout.BeginScrollView(_graphListScrollPos);
87+
for (int i = 0; i < _graphs.Count; i++)
88+
{
89+
// graph
90+
var graph = _selectedGraph ?? _graphs[i];
91+
if (!graph.IsValid())
92+
{
93+
EditorGUILayout.LabelField($"<b>[Graph] <color=red>[Invalid]</color></b> {graph.GetEditorName()}",
94+
_labelStyle);
95+
continue;
96+
}
97+
EditorGUILayout.LabelField($"<b>[Graph]</b> {graph.GetEditorName()}", _labelStyle);
98+
99+
// graph output
100+
EditorGUI.indentLevel += 2;
101+
for (int j = 0; j < graph.GetOutputCount(); j++)
102+
{
103+
var output = graph.GetOutput(j);
104+
if (!output.IsOutputValid())
105+
{
106+
EditorGUILayout.LabelField($"<b>[Output] <color=red>[Invalid]</color></b> {output.GetEditorName()}",
107+
_labelStyle);
108+
continue;
109+
}
110+
EditorGUILayout.LabelField($"<b>[Output]</b> {output.GetEditorName()}", _labelStyle);
111+
112+
// output source playable
113+
var sourcePlayable = output.GetSourcePlayable();
114+
ListPlayableRecursively(sourcePlayable);
115+
}
116+
EditorGUI.indentLevel -= 2;
117+
118+
if (_selectedGraph != null)
119+
{
120+
break;
121+
}
122+
}
123+
GUILayout.EndScrollView();
124+
}
125+
126+
private void ListPlayableRecursively(Playable playable)
127+
{
128+
if (playable.IsNull())
129+
{
130+
return;
131+
}
132+
133+
EditorGUI.indentLevel += 2;
134+
var sourcePlayableTypeName = playable.GetPlayableType().Name;
135+
if (!playable.IsValid())
136+
{
137+
EditorGUILayout.LabelField($"<b><color=red>[Invalid]</color></b> {sourcePlayableTypeName}",
138+
_labelStyle);
139+
EditorGUI.indentLevel -= 2;
140+
return;
141+
}
142+
EditorGUILayout.LabelField($"{sourcePlayableTypeName} ({GetPlayableStates(playable)})", _labelStyle);
143+
144+
for (int i = 0; i < playable.GetInputCount(); i++)
145+
{
146+
var input = playable.GetInput(i);
147+
ListPlayableRecursively(input);
148+
}
149+
EditorGUI.indentLevel -= 2;
150+
}
151+
152+
private string GetPlayableStates(Playable playable)
153+
{
154+
Assert.IsTrue(playable.IsValid());
155+
156+
var playState = playable.GetPlayState();
157+
var inputCount = playable.GetInputCount();
158+
var outputCount = playable.GetOutputCount();
159+
var speed = playable.GetSpeed();
160+
var time = playable.GetTime();
161+
var duration = playable.GetDuration();
162+
var durationStr = duration > float.MaxValue ? "+Inf" : duration.ToString("F3");
163+
var isDone = playable.IsDone() ? "Done" : "NotDone";
164+
var clipInfo = string.Empty;
165+
if (playable.IsPlayableOfType<AnimationClipPlayable>())
166+
{
167+
var animClipPlayable = (AnimationClipPlayable)playable;
168+
var clip = animClipPlayable.GetAnimationClip();
169+
clipInfo = $" C:{(clip ? clip.name : "null")}";
170+
}
171+
return $"{playState} {speed:F2}x T:{time:F3}(s)/{durationStr}(s) I:{inputCount} O:{outputCount} {isDone}{clipInfo}";
172+
}
173+
174+
private void UpdateGraphPopupMenuItems()
175+
{
176+
_graphPopupMenuItems = new string[_graphs.Count + 1];
177+
_graphPopupMenuItems[0] = "All";
178+
for (int i = 0; i < _graphs.Count; i++)
179+
{
180+
_graphPopupMenuItems[i + 1] = _graphs[i].GetEditorName();
181+
}
182+
183+
if (_selectedGraph == null)
184+
{
185+
_selectedGraphNumber = 0;
186+
return;
187+
}
188+
189+
_selectedGraphNumber = _graphs.IndexOf(_selectedGraph.Value) + 1;
190+
}
191+
192+
private void OnGraphCreated(PlayableGraph graph)
193+
{
194+
if (!_graphs.Contains(graph))
195+
{
196+
_graphs.Add(graph);
197+
UpdateGraphPopupMenuItems();
198+
}
199+
200+
}
201+
202+
private void OnDestroyingGraph(PlayableGraph graph)
203+
{
204+
_graphs.Remove(graph);
205+
206+
UpdateGraphPopupMenuItems();
207+
}
208+
}
209+
}

Editor/Scripts/PlayableGraphMonitorWindow.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

LICENSE.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "com.greenbamboogames.playablegraphmonitor",
3+
"version": "0.0.1",
4+
"displayName": "PlayableGraphMonitor!",
5+
"description": "Playable graph monitor.",
6+
"unity": "2021.3",
7+
"documentationUrl": "https://github.com/SolarianZ/UnityPlayableGraphMonitorTool",
8+
"changelogUrl": "",
9+
"licensesUrl": "https://github.com/SolarianZ/UnityPlayableGraphMonitorTool/blob/main/LICENSE",
10+
"keywords": [],
11+
"author": {
12+
"name": "GBG",
13+
"email": "vdergow@hotmail.com",
14+
"url": ""
15+
},
16+
"type": "tool",
17+
"hideInEditor": false
18+
}

package.json.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)