Skip to content

Commit 22d275b

Browse files
authored
Merge pull request #17 from SolidAlloy/prefab-support
Customizable folder stripping features
2 parents 47c9807 + fa82d60 commit 22d275b

29 files changed

+1115
-16
lines changed

Editor/FolderEditorUtils.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace UnityHierarchyFolders.Editor
99
{
1010
public static class FolderEditorUtils
1111
{
12-
private const string _actionName = "Create Heirarchy Folder %#&N";
12+
private const string _actionName = "Create Hierarchy Folder %#&N";
1313

1414
/// <summary>Add new folder "prefab".</summary>
1515
/// <param name="command">Menu command information.</param>
@@ -30,9 +30,11 @@ public class FolderOnBuild : IProcessSceneWithReport
3030

3131
public void OnProcessScene(Scene scene, BuildReport report)
3232
{
33+
var strippingMode = report == null ? StripSettings.PlayMode : StripSettings.Build;
34+
3335
foreach (var folder in Object.FindObjectsOfType<Folder>())
3436
{
35-
folder.Flatten();
37+
folder.Flatten(strippingMode, StripSettings.CapitalizeName);
3638
}
3739
}
3840
}

Editor/Icon Handling.meta

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+172
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#if UNITY_2019_1_OR_NEWER
2+
using System;
3+
using System.Collections;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Reflection;
7+
using UnityEditor;
8+
using UnityEditor.IMGUI.Controls;
9+
using UnityEngine;
10+
using UnityHierarchyFolders.Runtime;
11+
using Object = UnityEngine.Object;
12+
13+
namespace UnityHierarchyFolders.Editor
14+
{
15+
public static class HierarchyFolderIcon
16+
{
17+
#if UNITY_2020_1_OR_NEWER
18+
private const string _openedFolderPrefix = "FolderOpened";
19+
#else
20+
private const string _openedFolderPrefix = "OpenedFolder";
21+
#endif
22+
private const string _closedFolderPrefix = "Folder";
23+
24+
private static Texture2D _openFolderTexture;
25+
private static Texture2D _closedFolderTexture;
26+
private static Texture2D _openFolderSelectedTexture;
27+
private static Texture2D _closedFolderSelectedTexture;
28+
29+
private static bool _isInitialized;
30+
private static bool _hasProcessedFrame = true;
31+
32+
// Reflected members
33+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Special naming scheme")]
34+
private static PropertyInfo prop_sceneHierarchy;
35+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Special naming scheme")]
36+
private static PropertyInfo prop_treeView;
37+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Special naming scheme")]
38+
private static PropertyInfo prop_data;
39+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Special naming scheme")]
40+
private static PropertyInfo prop_selectedIcon;
41+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Special naming scheme")]
42+
private static PropertyInfo prop_objectPPTR;
43+
44+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Special naming scheme")]
45+
private static MethodInfo meth_getRows;
46+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Special naming scheme")]
47+
private static MethodInfo meth_isExpanded;
48+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Special naming scheme")]
49+
private static MethodInfo meth_getAllSceneHierarchyWindows;
50+
51+
private static (Texture2D open, Texture2D closed)[] _coloredFolderIcons;
52+
public static (Texture2D open, Texture2D closed) ColoredFolderIcons(int i) => _coloredFolderIcons[i];
53+
54+
public static int IconColumnCount => IconColors.GetLength(0);
55+
public static int IconRowCount => IconColors.GetLength(1);
56+
57+
private static readonly Color[,] IconColors = {
58+
{new Color(0.09f, 0.57f, 0.82f), new Color(0.05f, 0.34f, 0.48f),},
59+
{new Color(0.09f, 0.67f, 0.67f), new Color(0.05f, 0.42f, 0.42f),},
60+
{new Color(0.23f, 0.73f, 0.36f), new Color(0.15f, 0.41f, 0.22f),},
61+
{new Color(0.55f, 0.35f, 0.71f), new Color(0.35f, 0.24f, 0.44f),},
62+
{new Color(0.78f, 0.27f, 0.55f), new Color(0.52f, 0.15f, 0.35f),},
63+
{new Color(0.80f, 0.66f, 0.10f), new Color(0.56f, 0.46f, 0.02f),},
64+
{new Color(0.91f, 0.49f, 0.13f), new Color(0.62f, 0.33f, 0.07f),},
65+
{new Color(0.91f, 0.30f, 0.24f), new Color(0.77f, 0.15f, 0.09f),},
66+
{new Color(0.35f, 0.49f, 0.63f), new Color(0.24f, 0.33f, 0.42f),},
67+
};
68+
69+
[InitializeOnLoadMethod]
70+
private static void Startup()
71+
{
72+
EditorApplication.update += ResetFolderIcons;
73+
EditorApplication.hierarchyWindowItemOnGUI += RefreshFolderIcons;
74+
}
75+
76+
private static void InitIfNeeded()
77+
{
78+
if (_isInitialized) { return; }
79+
80+
_openFolderTexture = (Texture2D)EditorGUIUtility.IconContent($"{_openedFolderPrefix} Icon").image;
81+
_closedFolderTexture = (Texture2D)EditorGUIUtility.IconContent($"{_closedFolderPrefix} Icon").image;
82+
83+
// We could use the actual white folder icons but I prefer the look of the tinted white folder icon
84+
// To use the actual white version:
85+
// texture = (Texture2D) EditorGUIUtility.IconContent($"{OpenedFolderPrefix | ClosedFolderPrefix} On Icon").image;
86+
_openFolderSelectedTexture = TextureHelper.GetWhiteTexture(_openFolderTexture, $"{_openedFolderPrefix} Icon White");
87+
_closedFolderSelectedTexture = TextureHelper.GetWhiteTexture(_closedFolderTexture, $"{_closedFolderPrefix} Icon White");
88+
89+
_coloredFolderIcons = new (Texture2D, Texture2D)[] { (_openFolderTexture, _closedFolderTexture) };
90+
91+
for (int row = 0; row < IconRowCount; row++)
92+
{
93+
for (int column = 0; column < IconColumnCount; column++)
94+
{
95+
int index = 1 + column + row * IconColumnCount;
96+
var color = IconColors[column, row];
97+
98+
var openFolderIcon = TextureHelper.GetTintedTexture(_openFolderSelectedTexture,
99+
color, $"{_openFolderSelectedTexture.name} {index}");
100+
var closedFolderIcon = TextureHelper.GetTintedTexture(_closedFolderSelectedTexture,
101+
color, $"{_closedFolderSelectedTexture.name} {index}");
102+
103+
ArrayUtility.Add(ref _coloredFolderIcons, (openFolderIcon, closedFolderIcon));
104+
}
105+
}
106+
107+
// reflection
108+
109+
const BindingFlags BindingAll = BindingFlags.Public
110+
| BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
111+
112+
var assembly = typeof(SceneView).Assembly;
113+
114+
var type_sceneHierarchyWindow = assembly.GetType("UnityEditor.SceneHierarchyWindow");
115+
meth_getAllSceneHierarchyWindows = type_sceneHierarchyWindow.GetMethod("GetAllSceneHierarchyWindows", BindingAll);
116+
prop_sceneHierarchy = type_sceneHierarchyWindow.GetProperty("sceneHierarchy");
117+
118+
var type_sceneHierarchy = assembly.GetType("UnityEditor.SceneHierarchy");
119+
prop_treeView = type_sceneHierarchy.GetProperty("treeView", BindingAll);
120+
121+
var type_treeViewController = assembly.GetType("UnityEditor.IMGUI.Controls.TreeViewController");
122+
prop_data = type_treeViewController.GetProperty("data", BindingAll);
123+
124+
var type_iTreeViewDataSource = assembly.GetType("UnityEditor.IMGUI.Controls.ITreeViewDataSource");
125+
meth_getRows = type_iTreeViewDataSource.GetMethod("GetRows");
126+
meth_isExpanded = type_iTreeViewDataSource.GetMethod("IsExpanded", new Type[] { typeof(TreeViewItem) });
127+
128+
var type_gameObjectTreeViewItem = assembly.GetType("UnityEditor.GameObjectTreeViewItem");
129+
prop_selectedIcon = type_gameObjectTreeViewItem.GetProperty("selectedIcon", BindingAll);
130+
prop_objectPPTR = type_gameObjectTreeViewItem.GetProperty("objectPPTR", BindingAll);
131+
132+
_isInitialized = true;
133+
}
134+
135+
private static void ResetFolderIcons()
136+
{
137+
InitIfNeeded();
138+
_hasProcessedFrame = false;
139+
}
140+
141+
private static void RefreshFolderIcons(int instanceid, Rect selectionrect)
142+
{
143+
if (_hasProcessedFrame) { return; }
144+
145+
_hasProcessedFrame = true;
146+
147+
var windows = ((IEnumerable)meth_getAllSceneHierarchyWindows.Invoke(null, Array.Empty<object>())).Cast<EditorWindow>().ToList();
148+
foreach (var window in windows)
149+
{
150+
object sceneHierarchy = prop_sceneHierarchy.GetValue(window);
151+
object treeView = prop_treeView.GetValue(sceneHierarchy);
152+
object data = prop_data.GetValue(treeView);
153+
154+
var rows = (IList<TreeViewItem>)meth_getRows.Invoke(data, Array.Empty<object>());
155+
foreach (var item in rows)
156+
{
157+
var itemObject = (Object)prop_objectPPTR.GetValue(item);
158+
if (!Folder.TryGetIconIndex(itemObject, out int colorIndex)) { continue; }
159+
160+
bool isExpanded = (bool)meth_isExpanded.Invoke(data, new object[] { item });
161+
162+
var icons = ColoredFolderIcons(Mathf.Clamp(colorIndex, 0, _coloredFolderIcons.Length - 1));
163+
164+
item.icon = isExpanded ? icons.open : icons.closed;
165+
166+
prop_selectedIcon.SetValue(item, isExpanded ? _openFolderSelectedTexture : _closedFolderSelectedTexture);
167+
}
168+
}
169+
}
170+
}
171+
}
172+
#endif

Editor/Icon Handling/HierarchyFolderIcon.cs.meta

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Shader "UI/Replace color" {
2+
3+
Properties
4+
{
5+
_Color ("Replace Color", Color) = (1,1,1)
6+
_MainTex ("Texture", 2D) = "white"
7+
}
8+
9+
SubShader
10+
{
11+
Pass
12+
{
13+
SetTexture [_MainTex]
14+
{
15+
ConstantColor [_Color]
16+
combine constant + texture, texture
17+
}
18+
}
19+
}
20+
21+
}

Editor/Icon Handling/ReplaceColor Shader.shader.meta

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)