Net.Like.Xue.Tokyo/Packages-Local/Net.BITKit.Bounds.Unity/SceneBasedEnvironmentCatego...

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);
}
}
}