Ruined Town Sectors

This commit is contained in:
szczuras4
2025-11-27 01:51:39 +01:00
parent 8c28049d38
commit 14c2949ba1
7 changed files with 9925 additions and 2552 deletions

View File

@@ -843,11 +843,17 @@ MonoBehaviour:
- playOnce: 0 - playOnce: 0
delayToStart: 0 delayToStart: 0
customOutput: {fileID: 0} customOutput: {fileID: 0}
barks: [] barks:
- barkConversation: CH02/RUINEDTOWN/CH02_ruinedtown_vo_Sidranna_wonderer_01
barkText:
clip: {fileID: 8300000, guid: 5ae21a99ae2a8bd46be39515bdb64e44, type: 3}
- playOnce: 0 - playOnce: 0
delayToStart: 0 delayToStart: 0
customOutput: {fileID: 0} customOutput: {fileID: 0}
barks: [] barks:
- barkConversation: CH02/RUINEDTOWN/CH02_vo_bay_wanderer_00
barkText:
clip: {fileID: 8300000, guid: 03230376dca45d6428cd6155236fa94c, type: 3}
- playOnce: 0 - playOnce: 0
delayToStart: 0 delayToStart: 0
customOutput: {fileID: 385000820370598951, guid: 5dd761199ee4b7045a10fd9b79e36026, customOutput: {fileID: 385000820370598951, guid: 5dd761199ee4b7045a10fd9b79e36026,

File diff suppressed because it is too large Load Diff

View File

@@ -10,82 +10,114 @@ public static class CustomHierarchyDecorator
static CustomHierarchyDecorator() static CustomHierarchyDecorator()
{ {
LoadSettings(); LoadSettings();
// Rejestracja funkcji odpowiedzialnej za rysowanie niestandardowych nag³ówków
EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyGUI; EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyGUI;
EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI; EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
// Monitorowanie zmian w hierarchii
EditorApplication.hierarchyChanged += OnHierarchyChanged;
} }
// Aktualizacja ustawieñ
public static void UpdateSettings(HierarchyDecoratorSettings newSettings) public static void UpdateSettings(HierarchyDecoratorSettings newSettings)
{ {
settings = newSettings; settings = newSettings;
EditorApplication.RepaintHierarchyWindow(); EditorApplication.RepaintHierarchyWindow();
} }
// £adowanie ustawieñ
private static void LoadSettings() private static void LoadSettings()
{ {
settings = AssetDatabase.LoadAssetAtPath<HierarchyDecoratorSettings>("Assets/Scripts/Editor/HierarchyDecoratorSettings.asset"); 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.");
return;
} }
//Debug.Log("HierarchyDecoratorSettings loaded successfully.");
}
// Rysowanie nag³ówka
private static void OnHierarchyGUI(int instanceID, Rect selectionRect) private static void OnHierarchyGUI(int instanceID, Rect selectionRect)
{ {
if (settings == null) return; if (settings == null) return;
// 1. Rysowanie Linii Drzewa (Tree Lines) - DODATKOWY BAJER
if (settings.showTreeLines)
{
DrawTreeLines(selectionRect);
}
GameObject obj = EditorUtility.InstanceIDToObject(instanceID) as GameObject; GameObject obj = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
if (obj != null && obj.name.Contains("=")) if (obj == null) return;
{
DrawCustomHeader(selectionRect, obj);
// Ca³kowite zablokowanie zmiany nazwy w Hierarchii // 2. Sprawdzamy typ nag³ówka
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 // Typ: "= Clean" (Pusty separator)
private static void DrawCustomHeader(Rect rect, GameObject obj) if (obj.name.Trim().StartsWith("= Clean"))
{ {
if (obj.name.Trim().StartsWith("= Clean")) // <-- ZMIANA TUTAJ EditorGUI.DrawRect(selectionRect, settings.cleanBackgroundColor);
{
// Jeœli nazwa zaczyna siê od "Clean", rysujemy tylko t³o
EditorGUI.DrawRect(rect, settings.cleanBackgroundColor);
return; return;
} }
// Typ: "# Nazwa" (Subtelny nag³ówek sekcji) - NOWOŒÆ
if (obj.name.Trim().StartsWith("#"))
{
DrawSectionHeader(selectionRect, obj);
PreventRename(selectionRect);
return;
}
// Typ: "1= Nazwa" (Kolorowy nag³ówek)
if (obj.name.Contains("="))
{
DrawColoredHeader(selectionRect, obj);
PreventRename(selectionRect);
}
}
// --- NOWOή: Rysowanie linii hierarchii ---
private static void DrawTreeLines(Rect rect)
{
// Unity wciêcie to zazwyczaj 14 pikseli na poziom
float indentWidth = 14f;
// Obliczamy poziom zagnie¿d¿enia na podstawie pozycji X
// (To trik, bo nie mamy dostêpu do obj.transform.parent w tym miejscu ³atwo bez obiektu)
// Ale rect.x przesuwa siê w prawo.
// Rysujemy pionowe linie co 14 pikseli w lewo od rect.x
for (float x = rect.x - indentWidth; x > 0; x -= indentWidth)
{
Rect lineRect = new Rect(x, rect.y, 1f, rect.height);
EditorGUI.DrawRect(lineRect, settings.treeLineColor);
}
}
// --- NOWOŒÆ: Rysowanie subtelnego nag³ówka ---
private static void DrawSectionHeader(Rect rect, GameObject obj)
{
// Rysujemy t³o
EditorGUI.DrawRect(rect, settings.sectionBackgroundColor);
string text = obj.name.Replace("#", "").Trim();
if (settings.sectionUpperCase) text = text.ToUpper();
GUIStyle style = new GUIStyle(EditorStyles.label)
{
alignment = TextAnchor.MiddleCenter, // Wyœrodkowanie!
fontSize = settings.sectionFontSize,
fontStyle = FontStyle.Bold,
normal = { textColor = settings.sectionTextColor }
};
// Dodajemy delikatne kreski obok tekstu (opcjonalnie, wygl¹da super)
// ------- TEKST -------
EditorGUI.LabelField(rect, text, style);
}
private static void DrawColoredHeader(Rect rect, GameObject obj)
{
string[] parts = obj.name.Split(new[] { '=' }, System.StringSplitOptions.RemoveEmptyEntries); string[] parts = obj.name.Split(new[] { '=' }, System.StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 1) return; if (parts.Length < 1) return;
string mainText = parts[0].Trim(); string mainText = parts[0].Trim();
string descriptionText = parts.Length > 1 ? parts[1].Trim() : ""; // Jeœli istnieje drugi `=`, traktujemy go jako opis string descriptionText = parts.Length > 1 ? parts[1].Trim() : "";
// Obs³uga identyfikatora koloru
int colorIdentifier; int colorIdentifier;
bool hasIdentifier = int.TryParse(parts[0].Trim(), out colorIdentifier); bool hasIdentifier = int.TryParse(parts[0].Trim(), out colorIdentifier);
if (hasIdentifier) if (hasIdentifier)
{ {
// Jeœli jest identyfikator, przypisujemy g³ówny tekst i opis
mainText = parts.Length > 1 ? parts[1].Trim() : parts[0].Trim(); mainText = parts.Length > 1 ? parts[1].Trim() : parts[0].Trim();
descriptionText = parts.Length > 2 ? parts[2].Trim() : ""; // Jeœli jest opis, przypisujemy go descriptionText = parts.Length > 2 ? parts[2].Trim() : "";
} }
Color backgroundColor = obj.activeSelf ? settings.defaultBackgroundColor : settings.defaultInactiveBackgroundColor; Color backgroundColor = obj.activeSelf ? settings.defaultBackgroundColor : settings.defaultInactiveBackgroundColor;
@@ -94,7 +126,6 @@ public static class CustomHierarchyDecorator
if (hasIdentifier) if (hasIdentifier)
{ {
// Sprawdzamy identyfikator koloru i przypisujemy odpowiednie kolory
ColorScheme scheme = settings.colorSchemes.FirstOrDefault(s => s.identifier == colorIdentifier); ColorScheme scheme = settings.colorSchemes.FirstOrDefault(s => s.identifier == colorIdentifier);
if (scheme != null) if (scheme != null)
{ {
@@ -104,58 +135,42 @@ public static class CustomHierarchyDecorator
} }
} }
// Rysujemy t³o dla obiektu
EditorGUI.DrawRect(rect, backgroundColor); EditorGUI.DrawRect(rect, backgroundColor);
// Styl dla g³ównego tekstu (wycentrowany)
GUIStyle mainTextStyle = new GUIStyle(EditorStyles.boldLabel) GUIStyle mainTextStyle = new GUIStyle(EditorStyles.boldLabel)
{ {
alignment = TextAnchor.MiddleLeft, // Wyrównanie do lewej strony alignment = TextAnchor.MiddleLeft,
fontStyle = FontStyle.Bold, fontStyle = FontStyle.Bold,
normal = { textColor = textColor }, normal = { textColor = textColor },
wordWrap = false // Wy³¹czenie zawijania tekstu wordWrap = false
}; };
Rect mainTextRect = new Rect(rect.x + settings.mainTextOffset, rect.y, rect.width - 10, rect.height); // Zmniejszamy szerokoϾ Rect mainTextRect = new Rect(rect.x + settings.mainTextOffset, rect.y, rect.width - 10, rect.height);
EditorGUI.LabelField(mainTextRect, new GUIContent(mainText), mainTextStyle); EditorGUI.LabelField(mainTextRect, new GUIContent(mainText), mainTextStyle);
// Jeœli istnieje opis, wyœwietlamy go mniejsz¹ czcionk¹ po prawej stronie
if (!string.IsNullOrEmpty(descriptionText)) if (!string.IsNullOrEmpty(descriptionText))
{ {
GUIStyle descriptionStyle = new GUIStyle(EditorStyles.label) GUIStyle descriptionStyle = new GUIStyle(EditorStyles.label)
{ {
alignment = TextAnchor.MiddleLeft, // Zmieniono na wyrównanie do lewej alignment = TextAnchor.MiddleLeft,
fontSize = settings.descriptionFontSize, // Sta³a czcionka fontSize = settings.descriptionFontSize,
normal = { textColor = descriptionTextColor }, normal = { textColor = descriptionTextColor },
wordWrap = false // Wy³¹czenie zawijania tekstu wordWrap = false
}; };
// 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; 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 Rect descriptionRect = new Rect(descriptionX, rect.y, rect.width - descriptionX, rect.height);
EditorGUI.LabelField(descriptionRect, new GUIContent(descriptionText), descriptionStyle); EditorGUI.LabelField(descriptionRect, new GUIContent(descriptionText), descriptionStyle);
} }
} }
// Funkcja monitoruj¹ca zmiany w hierarchii (np. zablokowanie dodawania dzieci do separatorów) private static void PreventRename(Rect rect)
private static void OnHierarchyChanged()
{ {
EditorApplication.delayCall += () => Event e = Event.current;
if (e != null && e.type == EventType.MouseDown && e.clickCount == 2 && rect.Contains(e.mousePosition))
{ {
GameObject[] cleanSeparators = Object.FindObjectsByType<GameObject>(FindObjectsInactive.Include, FindObjectsSortMode.None) GUIUtility.keyboardControl = 0;
.Where(obj => obj.name.Trim().StartsWith("= Clean")) // <-- ZMIANA TUTAJ e.Use();
.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}");
} }
} }
};
}
} }

View File

@@ -8,6 +8,7 @@ public class HeaderCreatorWindow : EditorWindow
private string objectName = "New GameObject"; private string objectName = "New GameObject";
private string headerDescription = ""; private string headerDescription = "";
private int selectedIdentifier = 1; private int selectedIdentifier = 1;
private bool resetTransform = true;
private static HierarchyDecoratorSettings settings; private static HierarchyDecoratorSettings settings;
private Vector2 scrollPosition; private Vector2 scrollPosition;
@@ -18,8 +19,7 @@ public class HeaderCreatorWindow : EditorWindow
public static void ShowWindow() public static void ShowWindow()
{ {
HeaderCreatorWindow window = GetWindow<HeaderCreatorWindow>(true, "Create Object"); HeaderCreatorWindow window = GetWindow<HeaderCreatorWindow>(true, "Create Object");
// ZMIANA: Zwiêkszamy minimaln¹ wysokoœæ okna, aby zmieœci³ siê nowy przycisk window.minSize = new Vector2(320, 400); // Jeszcze trochê wiêksze
window.minSize = new Vector2(320, 340);
} }
private void OnEnable() private void OnEnable()
@@ -28,7 +28,7 @@ public class HeaderCreatorWindow : EditorWindow
if (settings == null) if (settings == null)
{ {
Debug.LogError("HierarchyDecoratorSettings not found!"); Debug.LogError("Settings not found!");
Close(); Close();
return; return;
} }
@@ -48,118 +48,128 @@ public class HeaderCreatorWindow : EditorWindow
objectName = EditorGUILayout.TextField("Name", objectName); objectName = EditorGUILayout.TextField("Name", objectName);
EditorGUILayout.Space(10); EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Description (Optional)", EditorStyles.miniBoldLabel);
headerDescription = EditorGUILayout.TextField(headerDescription);
EditorGUILayout.LabelField("For Custom Header:", EditorStyles.miniBoldLabel); EditorGUILayout.Space(5);
headerDescription = EditorGUILayout.TextField("Description (Optional)", headerDescription); resetTransform = EditorGUILayout.ToggleLeft("Reset Transform (Pos 0, Scale 1)", resetTransform);
if (settings.colorSchemes.Count == 0) EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Type 1: Colored Header", EditorStyles.boldLabel);
if (settings.colorSchemes.Count > 0)
{ {
EditorGUILayout.HelpBox("No color schemes defined in HierarchyDecoratorSettings. You can only create a simple empty object.", MessageType.Warning);
}
else
{
EditorGUILayout.LabelField("Color Scheme", EditorStyles.boldLabel);
DrawColorSelectionGrid(); DrawColorSelectionGrid();
} EditorGUILayout.Space(2);
if (GUILayout.Button("Create Colored Header", GUILayout.Height(30)))
EditorGUILayout.Space();
GUI.enabled = settings.colorSchemes.Count > 0;
if (GUILayout.Button("Create Custom Header", GUILayout.Height(35)))
{ {
CreateHeaderObject(); CreateHeaderObject();
Close(); Close();
} }
GUI.enabled = true; }
EditorGUILayout.Space(5); EditorGUILayout.Space(10);
EditorGUILayout.LabelField("Type 2: Separators", EditorStyles.boldLabel);
if (GUILayout.Button("Create Simple Empty (using Name only)", GUILayout.Height(30))) // PRZYCISK SEKCJI (SUBTELNY TEKST)
GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f);
if (GUILayout.Button("Create Section Header (Subtle Text)", GUILayout.Height(25)))
{ {
CreateSimpleEmptyObject(); CreateSectionHeader(); // Nowa funkcja
Close(); Close();
} }
// ZMIANA: Dodajemy nowy przycisk do tworzenia separatora "= Clean" EditorGUILayout.Space(2);
EditorGUILayout.Space(10); // Dodajemy trochê wiêcej miejsca
// Ustawiamy inny kolor t³a dla tego specjalnego przycisku, aby siê wyró¿nia³ // PRZYCISK CZYSTEGO SEPARATORA
GUI.backgroundColor = new Color(0.4f, 0.4f, 0.45f); GUI.backgroundColor = new Color(0.4f, 0.4f, 0.45f);
if (GUILayout.Button("Create Clean Separator (Empty)", GUILayout.Height(25)))
if (GUILayout.Button("Create Clean Separator", GUILayout.Height(30)))
{ {
CreateCleanSeparator(); CreateCleanSeparator();
Close(); Close();
} }
// WA¯NE: Resetujemy kolor t³a do domyœlnego, aby nie wp³ywa³ na inne elementy GUI
GUI.backgroundColor = Color.white; GUI.backgroundColor = Color.white;
EditorGUILayout.Space(10);
if (GUILayout.Button("Create Simple Empty", GUILayout.Height(20)))
{
CreateSimpleEmptyObject();
Close();
}
} }
private void DrawColorSelectionGrid() private void DrawColorSelectionGrid()
{ {
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUILayout.Height(80)); // ... (bez zmian) ...
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUILayout.Height(60));
int columns = 5; int columns = 5;
int buttonsInRow = 0; int buttonsInRow = 0;
GUILayout.BeginHorizontal(); GUILayout.BeginHorizontal();
foreach (var scheme in settings.colorSchemes) foreach (var scheme in settings.colorSchemes)
{ {
GUIStyle buttonStyle = colorStyles[scheme.identifier]; GUIStyle buttonStyle = colorStyles[scheme.identifier];
string buttonText = scheme.identifier.ToString(); if (GUILayout.Button(scheme.identifier.ToString(), buttonStyle, GUILayout.MinWidth(40), GUILayout.Height(25)))
if (GUILayout.Button(buttonText, buttonStyle, GUILayout.MinWidth(40), GUILayout.Height(30)))
{ {
selectedIdentifier = scheme.identifier; selectedIdentifier = scheme.identifier;
} }
if (Event.current.type == EventType.Repaint && scheme.identifier == selectedIdentifier) if (Event.current.type == EventType.Repaint && scheme.identifier == selectedIdentifier)
{ {
Rect buttonRect = GUILayoutUtility.GetLastRect(); Rect buttonRect = GUILayoutUtility.GetLastRect();
EditorGUI.DrawRect(buttonRect, new Color(0.5f, 0.5f, 0.5f, 0.4f)); EditorGUI.DrawRect(buttonRect, new Color(0.5f, 0.5f, 0.5f, 0.4f));
} }
buttonsInRow++; buttonsInRow++;
if (buttonsInRow >= columns) if (buttonsInRow >= columns) { GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); buttonsInRow = 0; }
{
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
buttonsInRow = 0;
}
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
EditorGUILayout.EndScrollView(); EditorGUILayout.EndScrollView();
} }
private void ApplyTransformReset(GameObject obj)
{
if (resetTransform)
{
obj.transform.localPosition = Vector3.zero;
obj.transform.localRotation = Quaternion.identity;
obj.transform.localScale = Vector3.one;
}
}
private void CreateHeaderObject() private void CreateHeaderObject()
{ {
string finalName = $"{selectedIdentifier}={objectName.Trim()}"; string finalName = $"{selectedIdentifier}={objectName.Trim()}";
if (!string.IsNullOrEmpty(headerDescription.Trim())) if (!string.IsNullOrEmpty(headerDescription.Trim())) finalName += $"={headerDescription.Trim()}";
{ CreateObject(finalName, "Create Custom Header");
finalName += $"={headerDescription.Trim()}";
}
GameObject header = new GameObject(finalName);
Undo.RegisterCreatedObjectUndo(header, "Create Custom Header");
GameObjectUtility.SetParentAndAlign(header, Selection.activeObject as GameObject);
Selection.activeObject = header;
} }
private void CreateSimpleEmptyObject() private void CreateSimpleEmptyObject()
{ {
GameObject emptyObj = new GameObject(objectName); CreateObject(objectName, "Create Simple Empty");
Undo.RegisterCreatedObjectUndo(emptyObj, "Create Simple Empty Object");
GameObjectUtility.SetParentAndAlign(emptyObj, Selection.activeObject as GameObject);
Selection.activeObject = emptyObj;
} }
// ZMIANA: Nowa funkcja do tworzenia separatora "= Clean"
private void CreateCleanSeparator() private void CreateCleanSeparator()
{ {
// Nazwa jest sta³a i nie zale¿y od pól w oknie CreateObject("= Clean", "Create Clean Separator");
GameObject cleanSeparator = new GameObject("= Clean"); }
Undo.RegisterCreatedObjectUndo(cleanSeparator, "Create Clean Separator");
GameObjectUtility.SetParentAndAlign(cleanSeparator, Selection.activeObject as GameObject); // --- NOWA FUNKCJA: TWORZENIE SEKCJI # ---
Selection.activeObject = cleanSeparator; private void CreateSectionHeader()
{
// Tworzymy nazwê zaczynaj¹c¹ siê od #
string name = objectName.Trim();
if (string.IsNullOrEmpty(name)) name = "SECTION";
string finalName = $"# {name}";
CreateObject(finalName, "Create Section Header");
}
private void CreateObject(string name, string undoName)
{
GameObject obj = new GameObject(name);
Undo.RegisterCreatedObjectUndo(obj, undoName);
GameObjectUtility.SetParentAndAlign(obj, Selection.activeObject as GameObject);
ApplyTransformReset(obj);
Selection.activeObject = obj;
} }
private void InitializeButtonStyles() private void InitializeButtonStyles()

View File

@@ -12,6 +12,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: b2e58b4d6f89b3b4087182494e3cb126, type: 3} m_Script: {fileID: 11500000, guid: b2e58b4d6f89b3b4087182494e3cb126, type: 3}
m_Name: HierarchyDecoratorSettings m_Name: HierarchyDecoratorSettings
m_EditorClassIdentifier: m_EditorClassIdentifier:
showTreeLines: 1
treeLineColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.2}
defaultBackgroundColor: {r: 0.1, g: 0.1, b: 0.1, a: 1} defaultBackgroundColor: {r: 0.1, g: 0.1, b: 0.1, a: 1}
defaultInactiveBackgroundColor: {r: 0.19401923, g: 0.2522564, b: 0.3773585, a: 1} defaultInactiveBackgroundColor: {r: 0.19401923, g: 0.2522564, b: 0.3773585, a: 1}
defaultTextColor: {r: 1, g: 1, b: 1, a: 1} defaultTextColor: {r: 1, g: 1, b: 1, a: 1}
@@ -33,6 +35,10 @@ MonoBehaviour:
activeTextColor: {r: 1, g: 1, b: 1, a: 1} activeTextColor: {r: 1, g: 1, b: 1, a: 1}
inactiveTextColor: {r: 0.30588236, g: 0.41568628, b: 0.5568628, a: 0.98039216} inactiveTextColor: {r: 0.30588236, g: 0.41568628, b: 0.5568628, a: 0.98039216}
cleanBackgroundColor: {r: 0.21698111, g: 0.21698111, b: 0.21698111, a: 1} cleanBackgroundColor: {r: 0.21698111, g: 0.21698111, b: 0.21698111, a: 1}
sectionBackgroundColor: {r: 0.21568628, g: 0.21568628, b: 0.21568628, a: 1}
sectionTextColor: {r: 0.7, g: 0.7, b: 0.7, a: 0.6}
sectionFontSize: 11
sectionUpperCase: 1
descriptionTextColor: {r: 0.73344606, g: 0.7648177, b: 0.7735849, a: 1} descriptionTextColor: {r: 0.73344606, g: 0.7648177, b: 0.7735849, a: 1}
descriptionFontSize: 11 descriptionFontSize: 11
mainTextOffset: 50 mainTextOffset: 50

View File

@@ -4,7 +4,7 @@ using System.Collections.Generic;
[System.Serializable] [System.Serializable]
public class ColorScheme public class ColorScheme
{ {
public int identifier; // Numer, np. 1, 2, 3 itp. public int identifier;
public Color activeBackgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.5f); public Color activeBackgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.5f);
public Color inactiveBackgroundColor = new Color(0f, 0f, 0f, 0.3f); public Color inactiveBackgroundColor = new Color(0f, 0f, 0f, 0.3f);
public Color activeTextColor = Color.white; public Color activeTextColor = Color.white;
@@ -14,7 +14,11 @@ public class ColorScheme
[CreateAssetMenu(fileName = "HierarchyDecoratorSettings", menuName = "Settings/HierarchyDecoratorSettings")] [CreateAssetMenu(fileName = "HierarchyDecoratorSettings", menuName = "Settings/HierarchyDecoratorSettings")]
public class HierarchyDecoratorSettings : ScriptableObject public class HierarchyDecoratorSettings : ScriptableObject
{ {
[Header("Default Background Settings")] [Header("Global Settings")]
public bool showTreeLines = true; // Czy pokazywać linie drzewa
public Color treeLineColor = new Color(0.5f, 0.5f, 0.5f, 0.2f);
[Header("Default Header Settings")]
public Color defaultBackgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.5f); public Color defaultBackgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.5f);
public Color defaultInactiveBackgroundColor = new Color(0f, 0f, 0f, 0.3f); public Color defaultInactiveBackgroundColor = new Color(0f, 0f, 0f, 0.3f);
public Color defaultTextColor = Color.green; public Color defaultTextColor = Color.green;
@@ -23,21 +27,24 @@ public class HierarchyDecoratorSettings : ScriptableObject
[Header("Custom Color Schemes")] [Header("Custom Color Schemes")]
public List<ColorScheme> colorSchemes = new List<ColorScheme>(); public List<ColorScheme> colorSchemes = new List<ColorScheme>();
[Header("Clean Separator Settings")] [Header("Separator Styles")]
public Color cleanBackgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.5f); // Kolor tła dla separatora Clean public Color cleanBackgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.5f); // = Clean
[Header("Section Header Settings (# Name)")]
public Color sectionBackgroundColor = new Color(0.15f, 0.15f, 0.15f, 0.8f); // Tło dla #
public Color sectionTextColor = new Color(0.7f, 0.7f, 0.7f, 0.6f); // Subtelny tekst
public int sectionFontSize = 11;
public bool sectionUpperCase = true; // Czy zamieniać na wielkie litery
[Header("Description Settings")] [Header("Description Settings")]
public Color descriptionTextColor = Color.gray; // Kolor opisu public Color descriptionTextColor = Color.gray;
public int descriptionFontSize = 10; // Rozmiar czcionki opisu public int descriptionFontSize = 10;
public float mainTextOffset = 0.0f;
[Header("Position Settings")] public float descriptionOffset = 100.0f;
public float mainTextOffset = 0.0f; // Umożliwia dostosowanie przesunięcia głównego tekstu
public float descriptionOffset = 100.0f; // Umożliwia dostosowanie przesunięcia opisu
[ContextMenu("Update Hierarchy Display")] [ContextMenu("Update Hierarchy Display")]
public void UpdateHierarchyDisplay() public void UpdateHierarchyDisplay()
{ {
CustomHierarchyDecorator.UpdateSettings(this); CustomHierarchyDecorator.UpdateSettings(this);
Debug.Log("Hierarchy display settings updated.");
} }
} }

View File

@@ -6,21 +6,46 @@ using System.Linq;
public class MoveToWindow : EditorWindow public class MoveToWindow : EditorWindow
{ {
// ------------------------------------------------------------------------
// Core Variables
// ------------------------------------------------------------------------
private static List<GameObject> selectedObjects; private static List<GameObject> selectedObjects;
private static List<GameObject> topLevelObjects; private static List<GameObject> topLevelObjects;
private static HierarchyDecoratorSettings settings;
// ------------------------------------------------------------------------
// UI State Variables
// ------------------------------------------------------------------------
private Vector2 scrollPosition;
private string filterText = ""; private string filterText = "";
private bool isPinned = false; private bool isPinned = false;
private static HierarchyDecoratorSettings settings; private static Dictionary<Color, bool> colorFilters = new Dictionary<Color, bool>();
private Vector2 scrollPosition;
private Dictionary<Color, bool> colorFilters = new Dictionary<Color, bool>();
private bool showDefaultColor = true; private bool showDefaultColor = true;
// ------------------------------------------------------------------------
// Feature: Shortcut (Spacebar) - GLOBAL STATE
// ------------------------------------------------------------------------
// Must be static to be accessed by SceneView delegate
private static GameObject shortcutTarget = null;
// ------------------------------------------------------------------------
// Feature: Create New Group
// ------------------------------------------------------------------------
private bool showCreationSection = false;
private string newGroupName = "New Group";
private int selectedColorIdForCreation = 1;
private static bool resetPositionOnMove = false;
// ------------------------------------------------------------------------
// Menu Items & Initialization
// ------------------------------------------------------------------------
[MenuItem("Window/Move To...")] [MenuItem("Window/Move To...")]
public static void ShowWindow() public static void ShowWindow()
{ {
LoadSettings();
UpdateTopLevelObjects(); UpdateTopLevelObjects();
MoveToWindow window = GetWindow<MoveToWindow>("Move To..."); MoveToWindow window = GetWindow<MoveToWindow>("Move To...");
LoadSettings();
UpdateSelectedObjects(); UpdateSelectedObjects();
window.Show(); window.Show();
} }
@@ -28,24 +53,140 @@ public class MoveToWindow : EditorWindow
[MenuItem("GameObject/Move To...", false, -100)] [MenuItem("GameObject/Move To...", false, -100)]
private static void MoveToContextMenu(MenuCommand command) private static void MoveToContextMenu(MenuCommand command)
{ {
LoadSettings();
UpdateSelectedObjects(); UpdateSelectedObjects();
ShowWindow(); ShowWindow();
} }
private void OnEnable()
{
LoadSettings();
// Subscribe to Scene View updates to handle global shortcuts
SceneView.duringSceneGui -= OnSceneGUI; // Safety unsubscribe
SceneView.duringSceneGui += OnSceneGUI;
}
private void OnDisable()
{
// Unsubscribe to prevent errors when window is closed
SceneView.duringSceneGui -= OnSceneGUI;
}
// ------------------------------------------------------------------------
// Global Shortcut Handling (Scene View)
// ------------------------------------------------------------------------
private static void OnSceneGUI(SceneView sceneView)
{
Event e = Event.current;
// Detect Spacebar press in Scene View
if (e != null && e.type == EventType.KeyDown && e.keyCode == KeyCode.Space)
{
if (shortcutTarget != null)
{
// Refresh selection manually because OnGUI isn't running
UpdateSelectedObjects();
if (selectedObjects != null && selectedObjects.Count > 0)
{
MoveObjectsToTab(selectedObjects, shortcutTarget);
// Consume the event so Unity doesn't do default actions (like maximizing view)
e.Use();
}
}
}
}
// ------------------------------------------------------------------------
// Main GUI Loop (Window View)
// ------------------------------------------------------------------------
private void OnGUI() private void OnGUI()
{ {
// Handle shortcut inside the window as well
HandleLocalKeyboardShortcut();
if (settings == null) LoadSettings();
if (topLevelObjects == null) UpdateTopLevelObjects();
EditorGUILayout.BeginHorizontal();
GUILayout.Space(10);
EditorGUILayout.BeginVertical();
{
GUILayout.Space(10);
DrawHeader(); DrawHeader();
GUILayout.Space(10);
DrawControls(); DrawControls();
DrawCreationSection();
DrawHideColorsSection(); DrawHideColorsSection();
DrawTabsList();
// Info Box about Shortcut (Active state)
if (shortcutTarget != null)
{
GUI.backgroundColor = new Color(0.8f, 1f, 0.8f);
EditorGUILayout.HelpBox($"ACTIVE: Press SPACE in Scene View to move objects to: {shortcutTarget.name}", MessageType.Info);
GUI.backgroundColor = Color.white;
} }
DrawTabsList();
DrawFooter();
GUILayout.Space(10);
}
EditorGUILayout.EndVertical();
GUILayout.Space(10);
EditorGUILayout.EndHorizontal();
}
// ------------------------------------------------------------------------
// Input Handling (Local Window)
// ------------------------------------------------------------------------
private void HandleLocalKeyboardShortcut()
{
Event e = Event.current;
if (e.type == EventType.KeyDown && e.keyCode == KeyCode.Space)
{
if (shortcutTarget != null)
{
UpdateSelectedObjects(); // Fix: Refresh selection before moving
if (selectedObjects != null && selectedObjects.Count > 0)
{
MoveObjectsToTab(selectedObjects, shortcutTarget);
e.Use();
Repaint();
}
}
}
}
// ------------------------------------------------------------------------
// Draw Methods
// ------------------------------------------------------------------------
private void DrawHeader() private void DrawHeader()
{ {
GUILayout.Label("Select a tab to move the selected objects:", new GUIStyle(EditorStyles.boldLabel) { alignment = TextAnchor.MiddleCenter }); GUILayout.Label("Select a tab to move the selected objects:", new GUIStyle(EditorStyles.boldLabel) { alignment = TextAnchor.MiddleCenter });
EditorGUILayout.BeginHorizontal();
isPinned = EditorGUILayout.Toggle("Pin Window", isPinned); isPinned = EditorGUILayout.Toggle("Pin Window", isPinned);
GUILayout.FlexibleSpace();
if (GUILayout.Button(EditorGUIUtility.IconContent("d_SettingsIcon"), GUILayout.Width(25), GUILayout.Height(19)))
{
Selection.activeObject = settings;
}
EditorGUILayout.EndHorizontal();
filterText = EditorGUILayout.TextField("Filter tabs", filterText); filterText = EditorGUILayout.TextField("Filter tabs", filterText);
GUILayout.Space(10);
} }
private void DrawControls() private void DrawControls()
@@ -53,38 +194,35 @@ public class MoveToWindow : EditorWindow
EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace(); GUILayout.FlexibleSpace();
if (GUILayout.Button("Enable All", GUILayout.Width(100))) if (GUILayout.Button("Enable All", GUILayout.Width(100))) SetAllTabsActiveState(true);
{ if (GUILayout.Button("Disable All", GUILayout.Width(100))) SetAllTabsActiveState(false);
SetAllTabsActiveState(true); if (GUILayout.Button("Collapse All", GUILayout.Width(100))) CollapseAllInHierarchy();
}
if (GUILayout.Button("Disable All", GUILayout.Width(100)))
{
SetAllTabsActiveState(false);
}
if (GUILayout.Button("Collapse All", GUILayout.Width(100)))
{
CollapseAllInHierarchy();
}
GUILayout.FlexibleSpace(); GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
GUILayout.Space(10); GUILayout.Space(5);
} }
private void DrawHideColorsSection() private void DrawHideColorsSection()
{ {
GUILayout.Space(5);
GUILayout.Label("----------------------------------------------------------", EditorStyles.centeredGreyMiniLabel); GUILayout.Label("----------------------------------------------------------", EditorStyles.centeredGreyMiniLabel);
GUILayout.Label("Hide Colors", new GUIStyle(EditorStyles.boldLabel) { alignment = TextAnchor.MiddleCenter }); GUILayout.Label("Hide Colors", new GUIStyle(EditorStyles.boldLabel) { alignment = TextAnchor.MiddleCenter });
EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace(); GUILayout.FlexibleSpace();
var keys = colorFilters.Keys.ToList();
try try
{ {
showDefaultColor = EditorGUILayout.ToggleLeft(new GUIContent(" ", MakeColorIcon(settings.defaultBackgroundColor)), showDefaultColor, GUILayout.Width(30)); if (settings != null)
foreach (var colorEntry in colorFilters.Keys.ToList())
{ {
colorFilters[colorEntry] = EditorGUILayout.ToggleLeft(new GUIContent(" ", MakeColorIcon(colorEntry)), colorFilters[colorEntry], GUILayout.Width(30)); showDefaultColor = EditorGUILayout.ToggleLeft(new GUIContent(" ", MakeColorIcon(settings.defaultBackgroundColor)), showDefaultColor, GUILayout.Width(35));
GUILayout.Space(5); }
foreach (var colorEntry in keys)
{
colorFilters[colorEntry] = EditorGUILayout.ToggleLeft(new GUIContent(" ", MakeColorIcon(colorEntry)), colorFilters[colorEntry], GUILayout.Width(35));
} }
} }
finally finally
@@ -94,18 +232,115 @@ public class MoveToWindow : EditorWindow
} }
GUILayout.Label("----------------------------------------------------------", EditorStyles.centeredGreyMiniLabel); GUILayout.Label("----------------------------------------------------------", EditorStyles.centeredGreyMiniLabel);
// --- NEW HELP TEXT (BLUE) ---
GUIStyle helpStyle = new GUIStyle(EditorStyles.miniLabel);
helpStyle.alignment = TextAnchor.MiddleCenter;
helpStyle.normal.textColor = new Color(0.4f, 0.7f, 1f); // Nice Blue Color
helpStyle.wordWrap = true;
GUILayout.Label("Check the box to set the [SPACE] shortcut target. Press Space to move selected objects.", helpStyle);
// ----------------------------
GUILayout.Space(10); GUILayout.Space(10);
} }
private void DrawCreationSection()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
showCreationSection = EditorGUILayout.Foldout(showCreationSection, "Create New Group", true);
if (showCreationSection)
{
GUILayout.Space(5);
EditorGUILayout.BeginHorizontal();
GUILayout.Label("Name:", GUILayout.Width(45));
newGroupName = EditorGUILayout.TextField(newGroupName);
EditorGUILayout.EndHorizontal();
GUILayout.Space(5);
GUILayout.Label("Pick Color:", EditorStyles.miniBoldLabel);
DrawColorSelectionGrid();
GUILayout.Space(5);
EditorGUILayout.BeginHorizontal();
resetPositionOnMove = EditorGUILayout.ToggleLeft("Reset Position (0,0,0)", resetPositionOnMove, GUILayout.Width(150));
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
GUILayout.Space(5);
Color originalBg = GUI.backgroundColor;
GUI.backgroundColor = new Color(0.6f, 0.9f, 0.6f);
if (GUILayout.Button("Create & Move Objects", GUILayout.Height(25)))
{
CreateAndMove();
}
GUI.backgroundColor = originalBg;
GUILayout.Space(5);
}
EditorGUILayout.EndVertical();
GUILayout.Space(10);
}
private void DrawColorSelectionGrid()
{
if (settings == null || settings.colorSchemes.Count == 0) return;
int columns = 8;
int buttonsInRow = 0;
GUILayout.BeginHorizontal();
foreach (var scheme in settings.colorSchemes)
{
Rect rect = GUILayoutUtility.GetRect(30, 20);
if (GUI.Button(rect, GUIContent.none, GUIStyle.none))
{
selectedColorIdForCreation = scheme.identifier;
}
EditorGUI.DrawRect(rect, scheme.activeBackgroundColor);
if (selectedColorIdForCreation == scheme.identifier)
{
DrawOutline(rect, 2, Color.white);
}
else
{
DrawOutline(rect, 1, new Color(0, 0, 0, 0.3f));
}
buttonsInRow++;
if (buttonsInRow >= columns)
{
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
buttonsInRow = 0;
}
GUILayout.Space(4);
}
GUILayout.EndHorizontal();
}
private void DrawTabsList() private void DrawTabsList()
{ {
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
if (topLevelObjects != null)
{
foreach (var obj in topLevelObjects) foreach (var obj in topLevelObjects)
{ {
Color tabColor = GetTabColor(obj); if (obj == null) continue;
if (!showDefaultColor && tabColor == settings.defaultBackgroundColor) Color tabColor = CalculateColorForObject(obj);
if (!showDefaultColor && settings != null && tabColor == settings.defaultBackgroundColor)
continue; continue;
if (colorFilters.ContainsKey(tabColor) && colorFilters[tabColor] == false) if (colorFilters.ContainsKey(tabColor) && colorFilters[tabColor] == false)
@@ -121,6 +356,7 @@ public class MoveToWindow : EditorWindow
DrawTabItem(obj, cleanName, tabColor); DrawTabItem(obj, cleanName, tabColor);
} }
}
EditorGUILayout.EndScrollView(); EditorGUILayout.EndScrollView();
} }
@@ -128,60 +364,195 @@ public class MoveToWindow : EditorWindow
private void DrawTabItem(GameObject obj, string cleanName, Color tabColor) private void DrawTabItem(GameObject obj, string cleanName, Color tabColor)
{ {
EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
// 1. Active Toggle
bool isActive = obj.activeSelf; bool isActive = obj.activeSelf;
bool newActiveState = EditorGUILayout.Toggle(isActive, GUILayout.Width(20)); bool newActiveState = EditorGUILayout.Toggle(isActive, GUILayout.Width(20));
if (newActiveState != isActive) if (newActiveState != isActive) obj.SetActive(newActiveState);
{
obj.SetActive(newActiveState);
}
GUILayout.Space(5);
// 2. Color Indicator
GUIStyle colorStyle = new GUIStyle(GUI.skin.box) GUIStyle colorStyle = new GUIStyle(GUI.skin.box)
{ {
normal = { background = MakeTex(1, 1, tabColor) }, normal = { background = MakeTex(1, 1, tabColor) },
margin = new RectOffset(0, 5, 4, 4), margin = new RectOffset(0, 0, 4, 4),
fixedWidth = 15, fixedWidth = 15,
fixedHeight = 15 fixedHeight = 15
}; };
GUILayout.Box(GUIContent.none, colorStyle); GUILayout.Box(GUIContent.none, colorStyle);
GUILayout.Space(10); GUILayout.Space(10);
// 3. Main Button (Folder Name)
// ZMIANA: Kolor tekstu zale¿ny od aktywnoœci obiektu
GUIStyle tabButtonStyle = new GUIStyle(GUI.skin.button) GUIStyle tabButtonStyle = new GUIStyle(GUI.skin.button)
{ {
alignment = TextAnchor.MiddleCenter, 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)) } normal = {
background = MakeTex(1, 1, obj.activeSelf ? new Color(0.25f, 0.25f, 0.25f) : new Color(0.18f, 0.18f, 0.18f)),
textColor = obj.activeSelf ? new Color(0.9f, 0.9f, 0.9f) : new Color(0.5f, 0.5f, 0.5f)
},
hover = {
background = MakeTex(1, 1, new Color(0.3f, 0.3f, 0.3f)),
textColor = Color.white
}
}; };
if (GUILayout.Button(cleanName, tabButtonStyle, GUILayout.Width(250))) // Zwiêkszono szerokoœæ przycisku do 250 if (GUILayout.Button(cleanName, tabButtonStyle, GUILayout.Height(22), GUILayout.MinWidth(200)))
{ {
UpdateSelectedObjects(); // Ensure fresh selection
MoveObjectsToTab(selectedObjects, obj); MoveObjectsToTab(selectedObjects, obj);
if (!isPinned) Close();
}
if (!isPinned) GUILayout.Space(10);
// 4. Shortcut Toggle
bool isShortcutTarget = (shortcutTarget == obj);
bool newShortcutState = EditorGUILayout.Toggle(isShortcutTarget, GUILayout.Width(20));
if (newShortcutState != isShortcutTarget)
{ {
Close(); if (newShortcutState) shortcutTarget = obj;
} else shortcutTarget = null;
} }
GUILayout.Space(20); if (isShortcutTarget)
{
GUIStyle spaceLabelStyle = new GUIStyle(EditorStyles.miniLabel)
{
// ZMIANA TUTAJ:
// Zamiast Color.green wpisz np. Color.cyan (jasny b³êkit)
// lub w³asny kolor: new Color(0.4f, 0.7f, 1f)
normal = { textColor = new Color(0.4f, 0.7f, 1f) },
fontStyle = FontStyle.Bold,
alignment = TextAnchor.MiddleLeft
};
GUILayout.Label("[SPACE]", spaceLabelStyle, GUILayout.Width(50));
}
else
{
GUILayout.Space(54);
}
// 5. Show In Hierarchy Button
GUIStyle showInHierarchyStyle = new GUIStyle(GUI.skin.button) GUIStyle showInHierarchyStyle = new GUIStyle(GUI.skin.button)
{ {
alignment = TextAnchor.MiddleCenter, alignment = TextAnchor.MiddleCenter,
normal = { textColor = Color.gray, background = MakeTex(1, 1, new Color(0.1f, 0.1f, 0.1f)) }, normal = { textColor = new Color(0.8f, 0.8f, 0.8f) },
hover = { textColor = Color.white },
fontSize = 10,
fontStyle = FontStyle.Italic fontStyle = FontStyle.Italic
}; };
if (GUILayout.Button("Show in Hierarchy", showInHierarchyStyle, GUILayout.Width(120))) if (GUILayout.Button("Show", showInHierarchyStyle, GUILayout.Width(45), GUILayout.Height(22)))
{ {
EditorGUIUtility.PingObject(obj); EditorGUIUtility.PingObject(obj);
} }
EditorGUILayout.EndHorizontal();
GUILayout.Space(6);
}
private void DrawFooter()
{
GUILayout.Space(10);
Color oldColor = GUI.backgroundColor;
GUI.backgroundColor = new Color(0.8f, 0.7f, 0.7f);
GUIStyle rootBtnStyle = new GUIStyle(GUI.skin.button);
rootBtnStyle.fontStyle = FontStyle.Bold;
rootBtnStyle.fontSize = 11;
if (GUILayout.Button("Move to Root (Unparent)", rootBtnStyle, GUILayout.Height(25)))
{
MoveToRoot();
}
GUI.backgroundColor = oldColor;
GUILayout.Space(5);
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
string status = (selectedObjects != null && selectedObjects.Count > 0)
? $"{selectedObjects.Count} objects selected"
: "No objects selected";
GUILayout.Label(status, EditorStyles.centeredGreyMiniLabel);
GUILayout.FlexibleSpace(); GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
GUILayout.Space(5);
} }
// ------------------------------------------------------------------------
// Logic Methods
// ------------------------------------------------------------------------
private void CreateAndMove()
{
if (string.IsNullOrEmpty(newGroupName)) return;
string finalName = $"{selectedColorIdForCreation}={newGroupName.Trim()}";
GameObject header = new GameObject(finalName);
Undo.RegisterCreatedObjectUndo(header, "Create Group");
if (Selection.activeGameObject != null && !selectedObjects.Contains(Selection.activeGameObject))
{
GameObjectUtility.SetParentAndAlign(header, Selection.activeGameObject);
}
UpdateTopLevelObjects();
UpdateSelectedObjects();
MoveObjectsToTab(selectedObjects, header);
newGroupName = "New Group";
GUI.FocusControl(null);
Repaint();
}
private void MoveToRoot()
{
UpdateSelectedObjects();
if (selectedObjects == null) return;
foreach (var obj in selectedObjects)
{
if (obj != null)
{
Undo.SetTransformParent(obj.transform, null, "Move to Root");
if (resetPositionOnMove)
{
Undo.RecordObject(obj.transform, "Zero Position");
obj.transform.position = Vector3.zero;
}
}
}
}
private static void MoveObjectsToTab(List<GameObject> objects, GameObject targetTab)
{
if (objects == null || targetTab == null) return;
foreach (var obj in objects)
{
if (obj != null)
{
Undo.SetTransformParent(obj.transform, targetTab.transform, "Move objects to folder");
if (resetPositionOnMove)
{
Undo.RecordObject(obj.transform, "Zero Position");
obj.transform.localPosition = Vector3.zero;
obj.transform.localRotation = Quaternion.identity;
}
}
}
}
// ------------------------------------------------------------------------
// Helper Methods & Updating
// ------------------------------------------------------------------------
private void Update() private void Update()
{ {
if (isPinned) if (isPinned)
@@ -194,10 +565,12 @@ public class MoveToWindow : EditorWindow
private static void LoadSettings() private static void LoadSettings()
{ {
if (settings != null) return;
settings = AssetDatabase.LoadAssetAtPath<HierarchyDecoratorSettings>("Assets/Scripts/Editor/HierarchyDecoratorSettings.asset"); settings = AssetDatabase.LoadAssetAtPath<HierarchyDecoratorSettings>("Assets/Scripts/Editor/HierarchyDecoratorSettings.asset");
if (settings == null) if (settings == null)
{ {
Debug.LogWarning("HierarchyDecoratorSettings not found! Please create one in Assets/Scripts/Editor folder or check the path."); settings = ScriptableObject.CreateInstance<HierarchyDecoratorSettings>();
settings.defaultBackgroundColor = Color.gray;
} }
} }
@@ -208,12 +581,23 @@ public class MoveToWindow : EditorWindow
private static void UpdateTopLevelObjects() private static void UpdateTopLevelObjects()
{ {
if (settings == null) LoadSettings();
topLevelObjects = new List<GameObject>(); topLevelObjects = new List<GameObject>();
foreach (GameObject obj in Resources.FindObjectsOfTypeAll<GameObject>()) foreach (GameObject obj in Resources.FindObjectsOfTypeAll<GameObject>())
{ {
if (HasColorInHierarchy(obj) && !obj.name.Contains("= Clean")) if (obj.hideFlags == HideFlags.None && HasColorInHierarchy(obj) && !obj.name.Contains("= Clean"))
{ {
topLevelObjects.Add(obj); topLevelObjects.Add(obj);
Color color = CalculateColorForObject(obj);
if (color != settings.defaultBackgroundColor)
{
if (!colorFilters.ContainsKey(color))
{
colorFilters[color] = true;
}
}
} }
} }
topLevelObjects = topLevelObjects.OrderBy(obj => GetHierarchyDepth(obj)).ThenBy(obj => obj.transform.GetSiblingIndex()).ToList(); topLevelObjects = topLevelObjects.OrderBy(obj => GetHierarchyDepth(obj)).ThenBy(obj => obj.transform.GetSiblingIndex()).ToList();
@@ -221,6 +605,7 @@ public class MoveToWindow : EditorWindow
private static int GetHierarchyDepth(GameObject obj) private static int GetHierarchyDepth(GameObject obj)
{ {
if (obj == null) return 0;
int depth = 0; int depth = 0;
Transform current = obj.transform; Transform current = obj.transform;
while (current.parent != null) while (current.parent != null)
@@ -235,7 +620,7 @@ public class MoveToWindow : EditorWindow
{ {
foreach (var obj in topLevelObjects) foreach (var obj in topLevelObjects)
{ {
obj.SetActive(isActive); if (obj != null) obj.SetActive(isActive);
} }
} }
@@ -243,20 +628,21 @@ public class MoveToWindow : EditorWindow
{ {
foreach (GameObject obj in topLevelObjects) foreach (GameObject obj in topLevelObjects)
{ {
if (PrefabUtility.IsAnyPrefabInstanceRoot(obj) || obj.transform.childCount > 0) if (obj != null && obj.transform.childCount > 0)
{ {
bool state = obj.activeSelf;
obj.SetActive(false); obj.SetActive(false);
obj.SetActive(true); obj.SetActive(state);
} }
} }
} }
private static bool HasColorInHierarchy(GameObject obj) private static bool HasColorInHierarchy(GameObject obj)
{ {
return obj.name.Contains("="); return obj != null && obj.name.Contains("=");
} }
private Color GetTabColor(GameObject obj) private static Color CalculateColorForObject(GameObject obj)
{ {
Color color = settings != null ? settings.defaultBackgroundColor : Color.gray; Color color = settings != null ? settings.defaultBackgroundColor : Color.gray;
@@ -270,16 +656,20 @@ public class MoveToWindow : EditorWindow
if (scheme != null) if (scheme != null)
{ {
color = obj.activeSelf ? scheme.activeBackgroundColor : scheme.inactiveBackgroundColor; color = obj.activeSelf ? scheme.activeBackgroundColor : scheme.inactiveBackgroundColor;
if (!colorFilters.ContainsKey(color))
{
colorFilters[color] = true;
}
} }
} }
} }
return color; return color;
} }
private void DrawOutline(Rect rect, float size, Color color)
{
EditorGUI.DrawRect(new Rect(rect.x, rect.y, rect.width, size), color);
EditorGUI.DrawRect(new Rect(rect.x, rect.y + rect.height - size, rect.width, size), color);
EditorGUI.DrawRect(new Rect(rect.x, rect.y, size, rect.height), color);
EditorGUI.DrawRect(new Rect(rect.x + rect.width - size, rect.y, size, rect.height), color);
}
private Texture2D MakeTex(int width, int height, Color col) private Texture2D MakeTex(int width, int height, Color col)
{ {
Color[] pix = new Color[width * height]; Color[] pix = new Color[width * height];
@@ -295,12 +685,4 @@ public class MoveToWindow : EditorWindow
{ {
return MakeTex(12, 12, 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");
}
}
} }