136 lines
3.2 KiB
C#
136 lines
3.2 KiB
C#
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<SceneBasedEnvironmentCategoryWindow>();
|
|
window.Show();
|
|
}
|
|
|
|
private Label _reportLabel;
|
|
private Button _categoryButton;
|
|
|
|
private readonly Dictionary<GameObject, List<GameObject>> _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<string, GameObject>();
|
|
|
|
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<GameObject>();
|
|
}
|
|
|
|
list.Add(gameObject);
|
|
}
|
|
|
|
|
|
foreach (var (source, list) in _dictionary)
|
|
{
|
|
stringBuilder.AppendLine($"{source.name}*{list.Count}");
|
|
}
|
|
|
|
|
|
_reportLabel.text = stringBuilder.ToString();
|
|
|
|
_categoryButton.SetEnabled(_dictionary.Count > 0);
|
|
}
|
|
}
|
|
}
|