using UnityEditor; using UnityEngine; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Linq; public class MoveToWindow : EditorWindow { private static List selectedObjects; private static List topLevelObjects; private string filterText = ""; private bool isPinned = false; private static HierarchyDecoratorSettings settings; private Vector2 scrollPosition; private Dictionary colorFilters = new Dictionary(); private bool showDefaultColor = true; [MenuItem("Window/Move To...")] public static void ShowWindow() { UpdateTopLevelObjects(); MoveToWindow window = GetWindow("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("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(Selection.gameObjects); } private static void UpdateTopLevelObjects() { topLevelObjects = new List(); foreach (GameObject obj in Resources.FindObjectsOfTypeAll()) { 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 objects, GameObject targetTab) { foreach (var obj in objects) { Undo.SetTransformParent(obj.transform, targetTab.transform, "Move objects to folder"); } } }