diff --git a/Assets/Scripts/Editor/CustomHierarchyDecorator.cs b/Assets/Scripts/Editor/CustomHierarchyDecorator.cs new file mode 100644 index 000000000..fc7a61461 --- /dev/null +++ b/Assets/Scripts/Editor/CustomHierarchyDecorator.cs @@ -0,0 +1,161 @@ +using UnityEditor; +using UnityEngine; +using System.Linq; + +[InitializeOnLoad] +public static class CustomHierarchyDecorator +{ + private static HierarchyDecoratorSettings settings; + + static CustomHierarchyDecorator() + { + LoadSettings(); + + // Rejestracja funkcji odpowiedzialnej za rysowanie niestandardowych nagłówków + EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyGUI; + EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI; + + // Monitorowanie zmian w hierarchii + EditorApplication.hierarchyChanged += OnHierarchyChanged; + } + + // Aktualizacja ustawień + public static void UpdateSettings(HierarchyDecoratorSettings newSettings) + { + settings = newSettings; + EditorApplication.RepaintHierarchyWindow(); + } + + // Ładowanie ustawień + 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."); + return; + } + + //Debug.Log("HierarchyDecoratorSettings loaded successfully."); + } + + // Rysowanie nagłówka + private static void OnHierarchyGUI(int instanceID, Rect selectionRect) + { + if (settings == null) return; + + GameObject obj = EditorUtility.InstanceIDToObject(instanceID) as GameObject; + if (obj != null && obj.name.Contains("=")) + { + DrawCustomHeader(selectionRect, obj); + + // Całkowite zablokowanie zmiany nazwy w Hierarchii + Event e = Event.current; + if (e != null && e.type == EventType.MouseDown && e.clickCount == 2 && selectionRect.Contains(e.mousePosition)) + { + // Zapobiegamy aktywacji trybu edycji nazwy + GUIUtility.keyboardControl = 0; // Zapobiegamy edytowaniu nazwy + e.Use(); + } + } + } + + // Funkcja rysująca niestandardowy nagłówek + private static void DrawCustomHeader(Rect rect, GameObject obj) + { + if (obj.name.Trim().StartsWith("= Clean")) // <-- ZMIANA TUTAJ + { + // Jeśli nazwa zaczyna się od "Clean", rysujemy tylko tło + EditorGUI.DrawRect(rect, settings.cleanBackgroundColor); + return; + } + + string[] parts = obj.name.Split(new[] { '=' }, System.StringSplitOptions.RemoveEmptyEntries); + if (parts.Length < 1) return; + + string mainText = parts[0].Trim(); + string descriptionText = parts.Length > 1 ? parts[1].Trim() : ""; // Jeśli istnieje drugi `=`, traktujemy go jako opis + + // Obsługa identyfikatora koloru + int colorIdentifier; + bool hasIdentifier = int.TryParse(parts[0].Trim(), out colorIdentifier); + + if (hasIdentifier) + { + // Jeśli jest identyfikator, przypisujemy główny tekst i opis + mainText = parts.Length > 1 ? parts[1].Trim() : parts[0].Trim(); + descriptionText = parts.Length > 2 ? parts[2].Trim() : ""; // Jeśli jest opis, przypisujemy go + } + + Color backgroundColor = obj.activeSelf ? settings.defaultBackgroundColor : settings.defaultInactiveBackgroundColor; + Color textColor = obj.activeSelf ? settings.defaultTextColor : settings.defaultInactiveTextColor; + Color descriptionTextColor = settings.descriptionTextColor; + + if (hasIdentifier) + { + // Sprawdzamy identyfikator koloru i przypisujemy odpowiednie kolory + ColorScheme scheme = settings.colorSchemes.FirstOrDefault(s => s.identifier == colorIdentifier); + if (scheme != null) + { + backgroundColor = obj.activeSelf ? scheme.activeBackgroundColor : scheme.inactiveBackgroundColor; + textColor = obj.activeSelf ? scheme.activeTextColor : scheme.inactiveTextColor; + descriptionTextColor = scheme.activeTextColor; + } + } + + // Rysujemy tło dla obiektu + EditorGUI.DrawRect(rect, backgroundColor); + + // Styl dla głównego tekstu (wycentrowany) + GUIStyle mainTextStyle = new GUIStyle(EditorStyles.boldLabel) + { + alignment = TextAnchor.MiddleLeft, // Wyrównanie do lewej strony + fontStyle = FontStyle.Bold, + normal = { textColor = textColor }, + wordWrap = false // Wyłączenie zawijania tekstu + }; + + Rect mainTextRect = new Rect(rect.x + settings.mainTextOffset, rect.y, rect.width - 10, rect.height); // Zmniejszamy szerokość + EditorGUI.LabelField(mainTextRect, new GUIContent(mainText), mainTextStyle); + + // Jeśli istnieje opis, wyświetlamy go mniejszą czcionką po prawej stronie + if (!string.IsNullOrEmpty(descriptionText)) + { + GUIStyle descriptionStyle = new GUIStyle(EditorStyles.label) + { + alignment = TextAnchor.MiddleLeft, // Zmieniono na wyrównanie do lewej + fontSize = settings.descriptionFontSize, // Stała czcionka + normal = { textColor = descriptionTextColor }, + wordWrap = false // Wyłączenie zawijania tekstu + }; + + // Opis wyrównany do końca głównego tekstu, zawsze w tej samej odległości + float descriptionX = rect.x + settings.mainTextOffset + mainTextStyle.CalcSize(new GUIContent(mainText)).x + settings.descriptionOffset; + Rect descriptionRect = new Rect(descriptionX, rect.y, rect.width - descriptionX, rect.height); // Dostosowanie szerokości do głównego tekstu + + EditorGUI.LabelField(descriptionRect, new GUIContent(descriptionText), descriptionStyle); + } + } + + // Funkcja monitorująca zmiany w hierarchii (np. zablokowanie dodawania dzieci do separatorów) + private static void OnHierarchyChanged() + { + EditorApplication.delayCall += () => + { + GameObject[] cleanSeparators = Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None) + .Where(obj => obj.name.Trim().StartsWith("= Clean")) // <-- ZMIANA TUTAJ + .ToArray(); + + foreach (var cleanObj in cleanSeparators) + { + for (int i = cleanObj.transform.childCount - 1; i >= 0; i--) + { + Transform child = cleanObj.transform.GetChild(i); + Undo.SetTransformParent(child, null, "Prevent Child to Clean Separator"); + Debug.Log($"Blocked child object {child.name} from being added to {cleanObj.name}"); + } + } + }; + } +} diff --git a/Assets/Scripts/Editor/CustomHierarchyDecorator.cs.meta b/Assets/Scripts/Editor/CustomHierarchyDecorator.cs.meta index 959457bc7..090d08b6f 100644 --- a/Assets/Scripts/Editor/CustomHierarchyDecorator.cs.meta +++ b/Assets/Scripts/Editor/CustomHierarchyDecorator.cs.meta @@ -1,11 +1,2 @@ fileFormatVersion: 2 -guid: 8c30c8eec324efa4da95a4c6290af0c9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +guid: ab24c60b91e1a52408877997339ec28f \ No newline at end of file diff --git a/Assets/Scripts/Editor/HeaderWithBackgroundAttribute.cs b/Assets/Scripts/Editor/HeaderWithBackgroundAttribute.cs new file mode 100644 index 000000000..c805a3b0e --- /dev/null +++ b/Assets/Scripts/Editor/HeaderWithBackgroundAttribute.cs @@ -0,0 +1,15 @@ +using UnityEngine; + +// Atrybut, który będzie używany do oznaczania nagłówków z tłem +public class HeaderWithBackgroundAttribute : PropertyAttribute +{ + public string HeaderText; // Tekst nagłówka + public Color BackgroundColor; // Kolor tła + + // Konstruktor, który ustawia tekst i kolor tła + public HeaderWithBackgroundAttribute(string headerText, float r, float g, float b) + { + HeaderText = headerText; + BackgroundColor = new Color(r, g, b, 1f); // Kolor z pełną przezroczystością + } +} diff --git a/Assets/Scripts/Editor/HeaderWithBackgroundAttribute.cs.meta b/Assets/Scripts/Editor/HeaderWithBackgroundAttribute.cs.meta new file mode 100644 index 000000000..59950b81f --- /dev/null +++ b/Assets/Scripts/Editor/HeaderWithBackgroundAttribute.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: b62518d902db2fb4191ed45c85857660 \ No newline at end of file