123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- using System;
- using System.IO;
- using UnityEditor;
- using UnityEngine;
- using System.Linq;
- using UnityEditor.UIElements;
- using UnityEngine.UIElements;
- using System.Collections.Generic;
- using Object = UnityEngine.Object;
- namespace IntelligentProjectAnalyzer.Editor.DependencyViewer
- {
- /// <summary>
- /// An editor window that displays the dependencies and references for a selected asset.
- /// It uses UI Toolkit for its interface and a DependencyGraph for data processing.
- /// </summary>
- public class DependencyViewerWindow : EditorWindow
- {
- private const string UxmlPath = "DependencyViewerWindow.uxml";
- private const string USSPath = "DependencyViewerWindow.uss";
- private ObjectField _assetSelector;
- private ListView _dependenciesList;
- private ListView _referencesList;
- private Button _refreshButton;
- private Object _selectedAsset;
- private DependencyGraph _graph;
- [MenuItem("Analyzer/Dependency Viewer")]
- public static void ShowWindow()
- {
- var wnd = GetWindow<DependencyViewerWindow>();
- wnd.titleContent = new GUIContent("Dependency Viewer");
- }
- public void CreateGUI()
- {
- var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(FindAssetPath(UxmlPath));
- if (visualTree == null)
- {
- rootVisualElement.Add(new Label($"Could not find UXML file at path '{UxmlPath}'. Make sure it's in an 'Editor' folder."));
- return;
- }
- visualTree.CloneTree(rootVisualElement);
- var styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>(FindAssetPath(USSPath));
- if (styleSheet != null)
- {
- rootVisualElement.styleSheets.Add(styleSheet);
- }
- _graph = new DependencyGraph();
- _assetSelector = rootVisualElement.Q<ObjectField>("script-selector");
- _dependenciesList = rootVisualElement.Q<ListView>("dependencies-list");
- _referencesList = rootVisualElement.Q<ListView>("references-list");
- _refreshButton = rootVisualElement.Q<Button>("refresh-button");
-
- _assetSelector.objectType = typeof(Object);
- _assetSelector.RegisterValueChangedCallback(OnAssetSelected);
- _refreshButton.clicked += OnRefreshClicked;
- ConfigureListView(_dependenciesList);
- ConfigureListView(_referencesList);
- }
- private static void ConfigureListView(ListView listView)
- {
- listView.makeItem = () =>
- {
- var root = new VisualElement { style = { flexDirection = FlexDirection.Row, alignItems = Align.Center }};
- var objField = new ObjectField { objectType = typeof(Object), style = { flexGrow = 1 } };
- objField.SetEnabled(false);
- var pingButton = new Button { text = "Ping", style = { flexShrink = 0, marginLeft = 5 }};
-
- pingButton.clicked += () =>
- {
- if (pingButton.userData is Object objToPing)
- {
- EditorGUIUtility.PingObject(objToPing);
- }
- };
-
- root.Add(objField);
- root.Add(pingButton);
- return root;
- };
- listView.bindItem = (element, index) =>
- {
- var objField = element.Q<ObjectField>();
- var pingButton = element.Q<Button>();
- var guid = listView.itemsSource[index] as string;
- var assetPath = AssetDatabase.GUIDToAssetPath(guid);
- var asset = AssetDatabase.LoadAssetAtPath<Object>(assetPath);
- if (objField != null) objField.value = asset;
- if (pingButton != null) pingButton.userData = asset;
- };
- }
-
- private void OnAssetSelected(ChangeEvent<Object> evt)
- {
- var newAsset = evt.newValue;
- if (newAsset == null)
- {
- _selectedAsset = null;
- PopulateLists();
- return;
- }
- // --- Validation Step 1: Check if it's a project asset ---
- var assetPath = AssetDatabase.GetAssetPath(newAsset);
- if (string.IsNullOrEmpty(assetPath) || !assetPath.StartsWith("Assets/"))
- {
- EditorUtility.DisplayDialog("Invalid Asset Location", "Please select an asset from the project's 'Assets' folder. Assets from packages or built-in resources are not supported.", "OK");
- _assetSelector.SetValueWithoutNotify(null); // Clear the selection
- _selectedAsset = null;
- PopulateLists();
- return;
- }
-
- // If all checks pass, update the selection and populate the lists.
- _selectedAsset = newAsset;
- PopulateLists();
- }
- private void OnRefreshClicked()
- {
- _graph.BuildGraph();
- PopulateLists();
- Debug.Log("Dependency data refreshed.");
- }
- private void PopulateLists()
- {
- string guid = null;
- if (_selectedAsset != null)
- {
- var assetPath = AssetDatabase.GetAssetPath(_selectedAsset);
- guid = AssetDatabase.AssetPathToGUID(assetPath);
- }
- if (string.IsNullOrEmpty(guid))
- {
- _dependenciesList.itemsSource = new List<string>();
- _referencesList.itemsSource = new List<string>();
- }
- else
- {
- _dependenciesList.itemsSource = _graph.GetDependencies(guid);
- _referencesList.itemsSource = _graph.GetReferences(guid);
- }
-
- _dependenciesList.Rebuild();
- _referencesList.Rebuild();
- }
- private static string FindAssetPath(string assetName)
- {
- var guids = AssetDatabase.FindAssets(Path.GetFileNameWithoutExtension(assetName));
- return guids.Select(AssetDatabase.GUIDToAssetPath).FirstOrDefault(path => Path.GetFileName(path).Equals(assetName, StringComparison.OrdinalIgnoreCase));
- }
- }
- }
|