307 lines
9.4 KiB
C#
307 lines
9.4 KiB
C#
using UnityEditor;
|
|
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
using System.Text.RegularExpressions;
|
|
using System.Linq;
|
|
|
|
public class MoveToWindow : EditorWindow
|
|
{
|
|
private static List<GameObject> selectedObjects;
|
|
private static List<GameObject> topLevelObjects;
|
|
private string filterText = "";
|
|
private bool isPinned = false;
|
|
private static HierarchyDecoratorSettings settings;
|
|
private Vector2 scrollPosition;
|
|
private Dictionary<Color, bool> colorFilters = new Dictionary<Color, bool>();
|
|
private bool showDefaultColor = true;
|
|
|
|
[MenuItem("Window/Move To...")]
|
|
public static void ShowWindow()
|
|
{
|
|
UpdateTopLevelObjects();
|
|
MoveToWindow window = GetWindow<MoveToWindow>("Move To...");
|
|
LoadSettings();
|
|
UpdateSelectedObjects();
|
|
window.Show();
|
|
}
|
|
|
|
[MenuItem("GameObject/Move To...", false, -100)]
|
|
private static void MoveToContextMenu(MenuCommand command)
|
|
{
|
|
UpdateSelectedObjects();
|
|
ShowWindow();
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
DrawHeader();
|
|
DrawControls();
|
|
DrawHideColorsSection();
|
|
DrawTabsList();
|
|
}
|
|
|
|
private void DrawHeader()
|
|
{
|
|
GUILayout.Label("Select a tab to move the selected objects:", new GUIStyle(EditorStyles.boldLabel) { alignment = TextAnchor.MiddleCenter });
|
|
isPinned = EditorGUILayout.Toggle("Pin Window", isPinned);
|
|
filterText = EditorGUILayout.TextField("Filter tabs", filterText);
|
|
GUILayout.Space(10);
|
|
}
|
|
|
|
private void DrawControls()
|
|
{
|
|
EditorGUILayout.BeginHorizontal();
|
|
GUILayout.FlexibleSpace();
|
|
|
|
if (GUILayout.Button("Enable All", GUILayout.Width(100)))
|
|
{
|
|
SetAllTabsActiveState(true);
|
|
}
|
|
if (GUILayout.Button("Disable All", GUILayout.Width(100)))
|
|
{
|
|
SetAllTabsActiveState(false);
|
|
}
|
|
if (GUILayout.Button("Collapse All", GUILayout.Width(100)))
|
|
{
|
|
CollapseAllInHierarchy();
|
|
}
|
|
|
|
GUILayout.FlexibleSpace();
|
|
EditorGUILayout.EndHorizontal();
|
|
GUILayout.Space(10);
|
|
}
|
|
|
|
private void DrawHideColorsSection()
|
|
{
|
|
GUILayout.Label("----------------------------------------------------------", EditorStyles.centeredGreyMiniLabel);
|
|
GUILayout.Label("Hide Colors", new GUIStyle(EditorStyles.boldLabel) { alignment = TextAnchor.MiddleCenter });
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
GUILayout.FlexibleSpace();
|
|
try
|
|
{
|
|
showDefaultColor = EditorGUILayout.ToggleLeft(new GUIContent(" ", MakeColorIcon(settings.defaultBackgroundColor)), showDefaultColor, GUILayout.Width(30));
|
|
foreach (var colorEntry in colorFilters.Keys.ToList())
|
|
{
|
|
colorFilters[colorEntry] = EditorGUILayout.ToggleLeft(new GUIContent(" ", MakeColorIcon(colorEntry)), colorFilters[colorEntry], GUILayout.Width(30));
|
|
GUILayout.Space(5);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
GUILayout.FlexibleSpace();
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
|
|
GUILayout.Label("----------------------------------------------------------", EditorStyles.centeredGreyMiniLabel);
|
|
GUILayout.Space(10);
|
|
}
|
|
|
|
private void DrawTabsList()
|
|
{
|
|
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
|
|
|
foreach (var obj in topLevelObjects)
|
|
{
|
|
Color tabColor = GetTabColor(obj);
|
|
|
|
if (!showDefaultColor && tabColor == settings.defaultBackgroundColor)
|
|
continue;
|
|
|
|
if (colorFilters.ContainsKey(tabColor) && colorFilters[tabColor] == false)
|
|
continue;
|
|
|
|
string cleanName = Regex.Replace(obj.name, @"^\d*=\s*|\s*=.*$", "").Trim();
|
|
|
|
if (obj.name.Contains("= Clean"))
|
|
continue;
|
|
|
|
if (!string.IsNullOrEmpty(filterText) && !cleanName.ToLower().Contains(filterText.ToLower()))
|
|
continue;
|
|
|
|
DrawTabItem(obj, cleanName, tabColor);
|
|
}
|
|
|
|
EditorGUILayout.EndScrollView();
|
|
}
|
|
|
|
private void DrawTabItem(GameObject obj, string cleanName, Color tabColor)
|
|
{
|
|
EditorGUILayout.BeginHorizontal();
|
|
GUILayout.FlexibleSpace();
|
|
|
|
bool isActive = obj.activeSelf;
|
|
bool newActiveState = EditorGUILayout.Toggle(isActive, GUILayout.Width(20));
|
|
if (newActiveState != isActive)
|
|
{
|
|
obj.SetActive(newActiveState);
|
|
}
|
|
|
|
GUIStyle colorStyle = new GUIStyle(GUI.skin.box)
|
|
{
|
|
normal = { background = MakeTex(1, 1, tabColor) },
|
|
margin = new RectOffset(0, 5, 4, 4),
|
|
fixedWidth = 15,
|
|
fixedHeight = 15
|
|
};
|
|
GUILayout.Box(GUIContent.none, colorStyle);
|
|
GUILayout.Space(10);
|
|
|
|
GUIStyle tabButtonStyle = new GUIStyle(GUI.skin.button)
|
|
{
|
|
alignment = TextAnchor.MiddleCenter,
|
|
normal = { background = MakeTex(1, 1, obj.activeSelf ? new Color(0.2f, 0.2f, 0.2f) : new Color(0.15f, 0.15f, 0.15f)) }
|
|
};
|
|
|
|
if (GUILayout.Button(cleanName, tabButtonStyle, GUILayout.Width(250))) // Zwiêkszono szerokoœæ przycisku do 250
|
|
{
|
|
MoveObjectsToTab(selectedObjects, obj);
|
|
|
|
if (!isPinned)
|
|
{
|
|
Close();
|
|
}
|
|
}
|
|
|
|
GUILayout.Space(20);
|
|
|
|
GUIStyle showInHierarchyStyle = new GUIStyle(GUI.skin.button)
|
|
{
|
|
alignment = TextAnchor.MiddleCenter,
|
|
normal = { textColor = Color.gray, background = MakeTex(1, 1, new Color(0.1f, 0.1f, 0.1f)) },
|
|
fontStyle = FontStyle.Italic
|
|
};
|
|
|
|
if (GUILayout.Button("Show in Hierarchy", showInHierarchyStyle, GUILayout.Width(120)))
|
|
{
|
|
EditorGUIUtility.PingObject(obj);
|
|
}
|
|
|
|
GUILayout.FlexibleSpace();
|
|
EditorGUILayout.EndHorizontal();
|
|
GUILayout.Space(5);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (isPinned)
|
|
{
|
|
UpdateTopLevelObjects();
|
|
UpdateSelectedObjects();
|
|
Repaint();
|
|
}
|
|
}
|
|
|
|
private static void LoadSettings()
|
|
{
|
|
settings = AssetDatabase.LoadAssetAtPath<HierarchyDecoratorSettings>("Assets/Scripts/Editor/HierarchyDecoratorSettings.asset");
|
|
if (settings == null)
|
|
{
|
|
Debug.LogWarning("HierarchyDecoratorSettings not found! Please create one in Assets/Scripts/Editor folder or check the path.");
|
|
}
|
|
}
|
|
|
|
private static void UpdateSelectedObjects()
|
|
{
|
|
selectedObjects = new List<GameObject>(Selection.gameObjects);
|
|
}
|
|
|
|
private static void UpdateTopLevelObjects()
|
|
{
|
|
topLevelObjects = new List<GameObject>();
|
|
foreach (GameObject obj in Resources.FindObjectsOfTypeAll<GameObject>())
|
|
{
|
|
if (HasColorInHierarchy(obj) && !obj.name.Contains("= Clean"))
|
|
{
|
|
topLevelObjects.Add(obj);
|
|
}
|
|
}
|
|
topLevelObjects = topLevelObjects.OrderBy(obj => GetHierarchyDepth(obj)).ThenBy(obj => obj.transform.GetSiblingIndex()).ToList();
|
|
}
|
|
|
|
private static int GetHierarchyDepth(GameObject obj)
|
|
{
|
|
int depth = 0;
|
|
Transform current = obj.transform;
|
|
while (current.parent != null)
|
|
{
|
|
depth++;
|
|
current = current.parent;
|
|
}
|
|
return depth;
|
|
}
|
|
|
|
private void SetAllTabsActiveState(bool isActive)
|
|
{
|
|
foreach (var obj in topLevelObjects)
|
|
{
|
|
obj.SetActive(isActive);
|
|
}
|
|
}
|
|
|
|
private void CollapseAllInHierarchy()
|
|
{
|
|
foreach (GameObject obj in topLevelObjects)
|
|
{
|
|
if (PrefabUtility.IsAnyPrefabInstanceRoot(obj) || obj.transform.childCount > 0)
|
|
{
|
|
obj.SetActive(false);
|
|
obj.SetActive(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static bool HasColorInHierarchy(GameObject obj)
|
|
{
|
|
return obj.name.Contains("=");
|
|
}
|
|
|
|
private Color GetTabColor(GameObject obj)
|
|
{
|
|
Color color = settings != null ? settings.defaultBackgroundColor : Color.gray;
|
|
|
|
if (settings != null && obj.name.Contains("="))
|
|
{
|
|
int colorIdentifier;
|
|
string[] parts = obj.name.Split('=');
|
|
if (parts.Length > 0 && int.TryParse(parts[0].Trim(), out colorIdentifier))
|
|
{
|
|
var scheme = settings.colorSchemes.FirstOrDefault(s => s.identifier == colorIdentifier);
|
|
if (scheme != null)
|
|
{
|
|
color = obj.activeSelf ? scheme.activeBackgroundColor : scheme.inactiveBackgroundColor;
|
|
if (!colorFilters.ContainsKey(color))
|
|
{
|
|
colorFilters[color] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return color;
|
|
}
|
|
|
|
private Texture2D MakeTex(int width, int height, Color col)
|
|
{
|
|
Color[] pix = new Color[width * height];
|
|
for (int i = 0; i < pix.Length; i++)
|
|
pix[i] = col;
|
|
Texture2D result = new Texture2D(width, height);
|
|
result.SetPixels(pix);
|
|
result.Apply();
|
|
return result;
|
|
}
|
|
|
|
private Texture2D MakeColorIcon(Color color)
|
|
{
|
|
return MakeTex(12, 12, color);
|
|
}
|
|
|
|
private void MoveObjectsToTab(List<GameObject> objects, GameObject targetTab)
|
|
{
|
|
foreach (var obj in objects)
|
|
{
|
|
Undo.SetTransformParent(obj.transform, targetTab.transform, "Move objects to folder");
|
|
}
|
|
}
|
|
}
|