|
1 | 1 | using GBG.PlayableGraphMonitor.Editor.Node; |
2 | 2 | using System; |
3 | 3 | using System.Collections.Generic; |
| 4 | +using System.Linq; |
4 | 5 | using UnityEditor; |
5 | 6 | using UnityEditor.Playables; |
6 | 7 | using UnityEditor.UIElements; |
@@ -156,23 +157,15 @@ private void CreateToolbar() |
156 | 157 | { |
157 | 158 | text = "Select Output Node" |
158 | 159 | }; |
159 | | -#if UNITY_2020_1_OR_NEWER |
160 | | - _selectOutputNodeMenu.RegisterCallback<ClickEvent>(OnClickSelectOutputNodeMenu); |
161 | | -#else |
162 | | - _selectOutputNodeMenu.RegisterCallback<PointerDownEvent>(OnClickSelectOutputNodeMenu); |
163 | | -#endif |
| 160 | + _selectOutputNodeMenu.RegisterCallback<PointerEnterEvent>(OnHoverSelectOutputNodeMenu); |
164 | 161 | _toolbar.Add(_selectOutputNodeMenu); |
165 | 162 |
|
166 | 163 | // Select root node |
167 | 164 | _selectRootNodeMenu = new ToolbarMenu |
168 | 165 | { |
169 | 166 | text = "Select Root Node" |
170 | 167 | }; |
171 | | -#if UNITY_2020_1_OR_NEWER |
172 | | - _selectRootNodeMenu.RegisterCallback<ClickEvent>(OnClickSelectRootNodeMenu); |
173 | | -#else |
174 | | - _selectRootNodeMenu.RegisterCallback<PointerDownEvent>(OnClickSelectRootNodeMenu); |
175 | | -#endif |
| 168 | + _selectRootNodeMenu.RegisterCallback<PointerEnterEvent>(OnHoverSelectRootNodeMenu); |
176 | 169 | _toolbar.Add(_selectRootNodeMenu); |
177 | 170 | } |
178 | 171 |
|
@@ -250,84 +243,95 @@ private void OnFrameAllButtonClicked() |
250 | 243 | _graphView.FrameAll(); |
251 | 244 | } |
252 | 245 |
|
253 | | -#if UNITY_2020_1_OR_NEWER |
254 | | - private void OnClickSelectOutputNodeMenu(ClickEvent evt) |
255 | | -#else |
256 | | - private void OnClickSelectOutputNodeMenu(PointerDownEvent evt) |
257 | | -#endif |
| 246 | + private void OnHoverSelectOutputNodeMenu(PointerEnterEvent evt) |
258 | 247 | { |
259 | | - var itemCount = _selectOutputNodeMenu.menu.MenuItems().Count; |
260 | | - for (int i = itemCount - 1; i >= 0; i--) |
| 248 | + _selectOutputNodeMenu.menu.MenuItems().Clear(); |
| 249 | + |
| 250 | + var playableGraph = _graphPopupField.value; |
| 251 | + if (!playableGraph.IsValid()) |
261 | 252 | { |
262 | | - _selectOutputNodeMenu.menu.RemoveItemAt(i); |
| 253 | + return; |
263 | 254 | } |
264 | 255 |
|
265 | 256 | var nodeList = new List<UNode>(); |
266 | 257 | _graphView.nodes.ToList(nodeList); |
267 | | - foreach (var node in nodeList) |
| 258 | + // _graphView.nodes.ToList() method returns nodes in random order, |
| 259 | + // ensure that the menu items are ordered |
| 260 | + var outputCount = playableGraph.GetOutputCount(); |
| 261 | + for (int i = 0; i < outputCount; i++) |
268 | 262 | { |
269 | | - if (node is PlayableOutputNode outputNode && |
270 | | - outputNode.PlayableOutput.IsOutputValid()) |
| 263 | + var playableOutput = playableGraph.GetOutput(i); |
| 264 | + var outputNode = nodeList.First(node => |
271 | 265 | { |
272 | | - var nodeName = $"{outputNode.PlayableOutput.GetPlayableOutputType().Name}" + |
273 | | - $" ({outputNode.PlayableOutput.GetEditorName()})"; |
274 | | - _selectOutputNodeMenu.menu.AppendAction(nodeName, _ => |
| 266 | + if (node is PlayableOutputNode oNode) |
275 | 267 | { |
276 | | - _graphView.ClearSelection(); |
277 | | - _graphView.AddToSelection(outputNode); |
278 | | - _graphView.FrameSelection(); |
279 | | - }); |
| 268 | + return oNode.PlayableOutput.GetHandle() == playableOutput.GetHandle(); |
| 269 | + } |
| 270 | + |
| 271 | + return false; |
| 272 | + }) as PlayableOutputNode; |
| 273 | + |
| 274 | + if (!outputNode.PlayableOutput.IsOutputValid()) |
| 275 | + { |
| 276 | + continue; |
280 | 277 | } |
| 278 | + |
| 279 | + var nodeName = $"{outputNode.PlayableOutput.GetPlayableOutputType().Name}" + |
| 280 | + $" ({outputNode.PlayableOutput.GetEditorName()})"; |
| 281 | + _selectOutputNodeMenu.menu.AppendAction(nodeName, _ => |
| 282 | + { |
| 283 | + _graphView.ClearSelection(); |
| 284 | + _graphView.AddToSelection(outputNode); |
| 285 | + _graphView.FrameSelection(); |
| 286 | + }); |
281 | 287 | } |
282 | 288 | } |
283 | 289 |
|
284 | | -#if UNITY_2020_1_OR_NEWER |
285 | | - private void OnClickSelectRootNodeMenu(ClickEvent evt) |
286 | | -#else |
287 | | - private void OnClickSelectRootNodeMenu(PointerDownEvent evt) |
288 | | -#endif |
| 290 | + private void OnHoverSelectRootNodeMenu(PointerEnterEvent evt) |
289 | 291 | { |
290 | | - var itemCount = _selectRootNodeMenu.menu.MenuItems().Count; |
291 | | - for (int i = itemCount - 1; i >= 0; i--) |
292 | | - { |
293 | | - _selectRootNodeMenu.menu.RemoveItemAt(i); |
294 | | - } |
| 292 | + _selectRootNodeMenu.menu.MenuItems().Clear(); |
295 | 293 |
|
296 | 294 | var playableGraph = _graphPopupField.value; |
297 | 295 | if (!playableGraph.IsValid()) |
298 | 296 | { |
299 | 297 | return; |
300 | 298 | } |
301 | 299 |
|
302 | | - var rootPlayableCount = playableGraph.GetRootPlayableCount(); |
303 | | - var rootPlayableHandles = new HashSet<PlayableHandle>(); |
304 | | - for (int i = 0; i < rootPlayableCount; i++) |
305 | | - { |
306 | | - var rootPlayableHandle = playableGraph.GetRootPlayable(i).GetHandle(); |
307 | | - rootPlayableHandles.Add(rootPlayableHandle); |
308 | | - } |
309 | | - |
310 | 300 | var nodeList = new List<UNode>(); |
311 | 301 | _graphView.nodes.ToList(nodeList); |
312 | | - foreach (var node in nodeList) |
| 302 | + // _graphView.nodes.ToList() method returns nodes in random order, |
| 303 | + // ensure that the menu items are ordered |
| 304 | + var rootPlayableCount = playableGraph.GetRootPlayableCount(); |
| 305 | + for (int i = 0; i < rootPlayableCount; i++) |
313 | 306 | { |
314 | | - if (node is PlayableNode playableNode && |
315 | | - playableNode.Playable.IsValid() && |
316 | | - rootPlayableHandles.Contains(playableNode.Playable.GetHandle())) |
| 307 | + var playable = playableGraph.GetRootPlayable(i); |
| 308 | + var playableNode = nodeList.First(node => |
317 | 309 | { |
318 | | - var nodeName = $"{playableNode.Playable.GetPlayableType()?.Name ?? "?"}"; |
319 | | - if (!string.IsNullOrEmpty(playableNode.ExtraLabel)) |
| 310 | + if (node is PlayableNode pNode) |
320 | 311 | { |
321 | | - nodeName = $"{nodeName} ({playableNode.ExtraLabel})"; |
| 312 | + return pNode.Playable.GetHandle() == playable.GetHandle(); |
322 | 313 | } |
323 | 314 |
|
324 | | - _selectRootNodeMenu.menu.AppendAction(nodeName, _ => |
325 | | - { |
326 | | - _graphView.ClearSelection(); |
327 | | - _graphView.AddToSelection(playableNode); |
328 | | - _graphView.FrameSelection(); |
329 | | - }); |
| 315 | + return false; |
| 316 | + }) as PlayableNode; |
| 317 | + |
| 318 | + if (!playableNode.Playable.IsValid()) |
| 319 | + { |
| 320 | + continue; |
330 | 321 | } |
| 322 | + |
| 323 | + var nodeName = $"{playableNode.Playable.GetPlayableType()?.Name ?? "?"}"; |
| 324 | + if (!string.IsNullOrEmpty(playableNode.ExtraLabel)) |
| 325 | + { |
| 326 | + nodeName = $"{nodeName} ({playableNode.ExtraLabel})"; |
| 327 | + } |
| 328 | + |
| 329 | + _selectRootNodeMenu.menu.AppendAction(nodeName, _ => |
| 330 | + { |
| 331 | + _graphView.ClearSelection(); |
| 332 | + _graphView.AddToSelection(playableNode); |
| 333 | + _graphView.FrameSelection(); |
| 334 | + }); |
331 | 335 | } |
332 | 336 | } |
333 | 337 | } |
|
0 commit comments