using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; using UnityEngine.UIElements; namespace BITKit.GameEditor { //This is a helper can make scene not category assets to be categorized public sealed class SceneBasedEnvironmentCategoryWindow : EditorWindow { private const string EnvironmentCategory = nameof(EnvironmentCategory); [MenuItem("Tools/Scenes/Category Window")] public static void Open() { var window = GetWindow(); window.Show(); } private Label _reportLabel; private Button _categoryButton; private readonly Dictionary> _dictionary = new(); private void OnEnable() { Rebuild(); } private void Rebuild() { var button = new Button(); rootVisualElement.Add(button); _categoryButton = new Button(); rootVisualElement.Add(_categoryButton); var scroll = new ScrollView(); rootVisualElement.Add(scroll); _reportLabel = new Label(); scroll.Add(_reportLabel); _reportLabel.text = "0"; button.text = "Search"; button.clicked += Execute; _categoryButton.SetEnabled(false); _categoryButton.text = "Category"; _categoryButton.clicked += Category; scroll.style.paddingLeft = 8; scroll.style.paddingRight = 8; scroll.style.paddingTop= 8; scroll.style.paddingBottom = 8; } private void Category() { var autoCategory = GameObject.Find(nameof(EnvironmentCategory))??new GameObject(nameof(EnvironmentCategory)); var dictionary = new Dictionary(); for (int i = 0; i < autoCategory.transform.childCount; i++) { var child = autoCategory.transform.GetChild(i); dictionary[child.name]=child.gameObject; } foreach (var (source,list) in _dictionary) { if (dictionary.TryGetValue(source.name, out var category) is false) { dictionary[source.name] = category = new GameObject(source.name); } category.transform.SetParent(autoCategory.transform); foreach (var go in list) { go.transform.SetParent(category.transform,true); } } EditorUtility.SetDirty(autoCategory); } private void Execute() { var stringBuilder = new System.Text.StringBuilder(); //Get All Root GameObject in editor _dictionary.Clear(); foreach (var gameObject in Selection.gameObjects) { // 判断是否是 Prefab 实例 var status = PrefabUtility.GetPrefabInstanceStatus(gameObject); switch (status) { case PrefabInstanceStatus.MissingAsset: case PrefabInstanceStatus.NotAPrefab: continue; } // 判断是否是 Root var root = PrefabUtility.GetOutermostPrefabInstanceRoot(gameObject); if (gameObject != root)continue; var source = PrefabUtility.GetCorrespondingObjectFromSource(gameObject); if (_dictionary.TryGetValue(source, out var list) is false) { _dictionary[source] = list = new List(); } list.Add(gameObject); } foreach (var (source, list) in _dictionary) { stringBuilder.AppendLine($"{source.name}*{list.Count}"); } _reportLabel.text = stringBuilder.ToString(); _categoryButton.SetEnabled(_dictionary.Count > 0); } } }