Files
beyond/Assets/Scripts/Editor/MoveToWindow.cs
2024-11-20 15:21:28 +01:00

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