├── Homebrew
└── DecorateFoldout
│ ├── Editor
│ ├── Resources
│ │ ├── IN foldout focus-6510.png
│ │ ├── IN foldout focus on-5718.png
│ │ ├── IN foldout focus-6510.png.meta
│ │ └── IN foldout focus on-5718.png.meta
│ └── EditorOverride.cs
│ └── Attributes
│ └── FoldAttribute.cs
├── .gitignore
├── LICENSE
└── README.md
/Homebrew/DecorateFoldout/Editor/Resources/IN foldout focus-6510.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PixeyeHQ/InspectorFoldoutGroup/HEAD/Homebrew/DecorateFoldout/Editor/Resources/IN foldout focus-6510.png
--------------------------------------------------------------------------------
/Homebrew/DecorateFoldout/Editor/Resources/IN foldout focus on-5718.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PixeyeHQ/InspectorFoldoutGroup/HEAD/Homebrew/DecorateFoldout/Editor/Resources/IN foldout focus on-5718.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | [Ll]ibrary/
2 | [Tt]emp/
3 | [Oo]bj/
4 | [Bb]uild/
5 | [Bb]uilds/
6 | Assets/AssetStoreTools*
7 |
8 | # Visual Studio cache directory
9 | .vs/
10 |
11 | # Autogenerated VS/MD/Consulo solution and project files
12 | ExportedObj/
13 | .consulo/
14 | *.csproj
15 | *.unityproj
16 | *.sln
17 | *.suo
18 | *.tmp
19 | *.user
20 | *.userprefs
21 | *.pidb
22 | *.booproj
23 | *.svd
24 | *.pdb
25 | *.opendb
26 |
27 | # Unity3D generated meta files
28 | *.pidb.meta
29 | *.pdb.meta
30 |
31 | # Unity3D Generated File On Crash Reports
32 | sysinfo.txt
33 |
34 | # Builds
35 | *.apk
36 | *.unitypackage
37 |
--------------------------------------------------------------------------------
/Homebrew/DecorateFoldout/Attributes/FoldAttribute.cs:
--------------------------------------------------------------------------------
1 | // Project : UNITY FOLDOUT
2 | // Contacts : Pix - ask@pixeye.games
3 |
4 |
5 | using UnityEngine;
6 |
7 | namespace Pixeye.Unity
8 | {
9 | public class FoldoutAttribute : PropertyAttribute
10 | {
11 | public string name;
12 | public bool foldEverything;
13 |
14 | /// Adds the property to the specified foldout group.
15 | /// Name of the foldout group.
16 | /// Toggle to put all properties to the specified group
17 | public FoldoutAttribute(string name, bool foldEverything = false)
18 | {
19 | this.foldEverything = foldEverything;
20 | this.name = name;
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Dimitry
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/dimmpixeye/InspectorFoldoutGroup/blob/master/LICENSE)
2 | [](https://discord.gg/ukhzx83)
3 | # InspectorFoldoutGroup
4 | Group variables in Unity 3d inspector with style!
5 |
6 | [](https://gyazo.com/9f18eab9dfb123d928aecf7daa3e01da)
7 |
8 | [](https://gyazo.com/4e6566c2fca783e4cd557f95713a4ab5)
9 |
10 | ## How to use
11 |
12 | Put attribute before variable and you are done !
13 |
14 | ```csharp
15 | [Foldout("DESIRED_NAME")]
16 | ```
17 |
18 | ```csharp
19 | public class Player : MonoBehaviour
20 | {
21 | [Foldout("Setup")] public Transform selfTransform;
22 |
23 | [Foldout("Data")] public int HP;
24 | [Foldout("Data")] public int AT;
25 |
26 | }
27 | ```
28 |
29 | You don't need to write [Foldout] attribute each time! Instead, you can add "true" bool check afther naming to put all properties to the specified group
30 | ```csharp
31 | public class Player : MonoBehaviour
32 | {
33 | [Foldout("DATA OBJECT", true)]
34 | public int hp;
35 | public int attack = 20;
36 | [SerializeField]
37 | private GameObject self;
38 |
39 | [Foldout("DATA ATTACK")]
40 | public int AT;
41 |
42 | }
43 | ```
44 | [](https://gyazo.com/2ce500e63fd604de8098aece2fa354fa)
45 |
46 |
47 | ## Other content
48 | * [Tag filters](https://github.com/dimmpixeye/Unity3d-Tags-Filters) - an extension to add foldable groups to the inspector.
49 | * [ACTORS](https://github.com/dimmpixeye/Actors-Unity3d-Framework) - Unity3d data-driven framework I'm currently working on.
50 |
51 |
--------------------------------------------------------------------------------
/Homebrew/DecorateFoldout/Editor/Resources/IN foldout focus-6510.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 795626f49ade9024a86e0c1a58aa004b
3 | TextureImporter:
4 | fileIDToRecycleName: {}
5 | externalObjects: {}
6 | serializedVersion: 5
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | grayScaleToAlpha: 0
25 | generateCubemap: 6
26 | cubemapConvolution: 0
27 | seamlessCubemap: 0
28 | textureFormat: 1
29 | maxTextureSize: 2048
30 | textureSettings:
31 | serializedVersion: 2
32 | filterMode: 0
33 | aniso: -1
34 | mipBias: -1
35 | wrapU: 1
36 | wrapV: 1
37 | wrapW: -1
38 | nPOTScale: 0
39 | lightmap: 0
40 | compressionQuality: 50
41 | spriteMode: 1
42 | spriteExtrude: 1
43 | spriteMeshType: 1
44 | alignment: 0
45 | spritePivot: {x: 0.5, y: 0.5}
46 | spritePixelsToUnits: 100
47 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
48 | spriteGenerateFallbackPhysicsShape: 1
49 | alphaUsage: 1
50 | alphaIsTransparency: 1
51 | spriteTessellationDetail: -1
52 | textureType: 8
53 | textureShape: 1
54 | singleChannelComponent: 0
55 | maxTextureSizeSet: 0
56 | compressionQualitySet: 0
57 | textureFormatSet: 0
58 | platformSettings:
59 | - serializedVersion: 2
60 | buildTarget: DefaultTexturePlatform
61 | maxTextureSize: 2048
62 | resizeAlgorithm: 0
63 | textureFormat: -1
64 | textureCompression: 1
65 | compressionQuality: 50
66 | crunchedCompression: 0
67 | allowsAlphaSplitting: 0
68 | overridden: 0
69 | androidETC2FallbackOverride: 0
70 | - serializedVersion: 2
71 | buildTarget: Standalone
72 | maxTextureSize: 2048
73 | resizeAlgorithm: 0
74 | textureFormat: -1
75 | textureCompression: 1
76 | compressionQuality: 50
77 | crunchedCompression: 0
78 | allowsAlphaSplitting: 0
79 | overridden: 0
80 | androidETC2FallbackOverride: 0
81 | - serializedVersion: 2
82 | buildTarget: WebGL
83 | maxTextureSize: 2048
84 | resizeAlgorithm: 0
85 | textureFormat: -1
86 | textureCompression: 1
87 | compressionQuality: 50
88 | crunchedCompression: 0
89 | allowsAlphaSplitting: 0
90 | overridden: 0
91 | androidETC2FallbackOverride: 0
92 | spriteSheet:
93 | serializedVersion: 2
94 | sprites: []
95 | outline: []
96 | physicsShape: []
97 | bones: []
98 | spriteID:
99 | vertices: []
100 | indices:
101 | edges: []
102 | weights: []
103 | spritePackingTag:
104 | userData:
105 | assetBundleName:
106 | assetBundleVariant:
107 |
--------------------------------------------------------------------------------
/Homebrew/DecorateFoldout/Editor/Resources/IN foldout focus on-5718.png.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 07896d08487bbb049b494e9e216360ad
3 | TextureImporter:
4 | fileIDToRecycleName: {}
5 | externalObjects: {}
6 | serializedVersion: 5
7 | mipmaps:
8 | mipMapMode: 0
9 | enableMipMap: 0
10 | sRGBTexture: 1
11 | linearTexture: 0
12 | fadeOut: 0
13 | borderMipMap: 0
14 | mipMapsPreserveCoverage: 0
15 | alphaTestReferenceValue: 0.5
16 | mipMapFadeDistanceStart: 1
17 | mipMapFadeDistanceEnd: 3
18 | bumpmap:
19 | convertToNormalMap: 0
20 | externalNormalMap: 0
21 | heightScale: 0.25
22 | normalMapFilter: 0
23 | isReadable: 0
24 | grayScaleToAlpha: 0
25 | generateCubemap: 6
26 | cubemapConvolution: 0
27 | seamlessCubemap: 0
28 | textureFormat: 1
29 | maxTextureSize: 2048
30 | textureSettings:
31 | serializedVersion: 2
32 | filterMode: 0
33 | aniso: -1
34 | mipBias: -1
35 | wrapU: 1
36 | wrapV: 1
37 | wrapW: -1
38 | nPOTScale: 0
39 | lightmap: 0
40 | compressionQuality: 50
41 | spriteMode: 1
42 | spriteExtrude: 1
43 | spriteMeshType: 1
44 | alignment: 0
45 | spritePivot: {x: 0.5, y: 0.5}
46 | spritePixelsToUnits: 100
47 | spriteBorder: {x: 0, y: 0, z: 0, w: 0}
48 | spriteGenerateFallbackPhysicsShape: 1
49 | alphaUsage: 1
50 | alphaIsTransparency: 1
51 | spriteTessellationDetail: -1
52 | textureType: 8
53 | textureShape: 1
54 | singleChannelComponent: 0
55 | maxTextureSizeSet: 0
56 | compressionQualitySet: 0
57 | textureFormatSet: 0
58 | platformSettings:
59 | - serializedVersion: 2
60 | buildTarget: DefaultTexturePlatform
61 | maxTextureSize: 2048
62 | resizeAlgorithm: 0
63 | textureFormat: -1
64 | textureCompression: 1
65 | compressionQuality: 50
66 | crunchedCompression: 0
67 | allowsAlphaSplitting: 0
68 | overridden: 0
69 | androidETC2FallbackOverride: 0
70 | - serializedVersion: 2
71 | buildTarget: Standalone
72 | maxTextureSize: 2048
73 | resizeAlgorithm: 0
74 | textureFormat: -1
75 | textureCompression: 1
76 | compressionQuality: 50
77 | crunchedCompression: 0
78 | allowsAlphaSplitting: 0
79 | overridden: 0
80 | androidETC2FallbackOverride: 0
81 | - serializedVersion: 2
82 | buildTarget: WebGL
83 | maxTextureSize: 2048
84 | resizeAlgorithm: 0
85 | textureFormat: -1
86 | textureCompression: 1
87 | compressionQuality: 50
88 | crunchedCompression: 0
89 | allowsAlphaSplitting: 0
90 | overridden: 0
91 | androidETC2FallbackOverride: 0
92 | spriteSheet:
93 | serializedVersion: 2
94 | sprites: []
95 | outline: []
96 | physicsShape: []
97 | bones: []
98 | spriteID:
99 | vertices: []
100 | indices:
101 | edges: []
102 | weights: []
103 | spritePackingTag:
104 | userData:
105 | assetBundleName:
106 | assetBundleVariant:
107 |
--------------------------------------------------------------------------------
/Homebrew/DecorateFoldout/Editor/EditorOverride.cs:
--------------------------------------------------------------------------------
1 | // Project : UNITY FOLDOUT
2 | // Contacts : Pix - ask@pixeye.games
3 |
4 | using Homebrew;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Reflection;
9 | using UnityEditor;
10 | using UnityEngine;
11 | using Object = UnityEngine.Object;
12 |
13 |
14 | namespace Pixeye.Unity
15 | {
16 | [CustomEditor(typeof(Object), true, isFallback = true)]
17 | [CanEditMultipleObjects]
18 | public class EditorOverride : Editor
19 | {
20 | //===============================//
21 | // Members
22 | //===============================//
23 |
24 |
25 | Dictionary cacheFolds = new Dictionary();
26 | List props = new List();
27 | List methods = new List();
28 | bool initialized;
29 |
30 |
31 | //===============================//
32 | // Logic
33 | //===============================//
34 |
35 |
36 | void OnEnable()
37 | {
38 | initialized = false;
39 | }
40 |
41 |
42 | void OnDisable()
43 | {
44 | //if (Application.wantsToQuit)
45 | //if (applicationIsQuitting) return;
46 | // if (Toolbox.isQuittingOrChangingScene()) return;
47 | if (target != null)
48 | foreach (var c in cacheFolds)
49 | {
50 | EditorPrefs.SetBool(string.Format($"{c.Value.atr.name}{c.Value.props[0].name}{target.GetInstanceID()}"), c.Value.expanded);
51 | c.Value.Dispose();
52 | }
53 | }
54 |
55 |
56 | public override bool RequiresConstantRepaint()
57 | {
58 | return EditorFramework.needToRepaint;
59 | }
60 |
61 | public override void OnInspectorGUI()
62 | {
63 | serializedObject.Update();
64 |
65 |
66 | Setup();
67 |
68 | if (props.Count == 0)
69 | {
70 | DrawDefaultInspector();
71 | return;
72 | }
73 |
74 | Header();
75 | Body();
76 |
77 | serializedObject.ApplyModifiedProperties();
78 |
79 | void Header()
80 | {
81 | using (new EditorGUI.DisabledScope("m_Script" == props[0].propertyPath))
82 | {
83 | EditorGUILayout.Space();
84 | EditorGUILayout.PropertyField(props[0], true);
85 | EditorGUILayout.Space();
86 | }
87 | }
88 |
89 | void Body()
90 | {
91 | foreach (var pair in cacheFolds)
92 | {
93 | this.UseVerticalLayout(() => Foldout(pair.Value), StyleFramework.box);
94 | EditorGUI.indentLevel = 0;
95 | }
96 |
97 | EditorGUILayout.Space();
98 |
99 | for (var i = 1; i < props.Count; i++)
100 | {
101 | // if (props[i].isArray)
102 | // {
103 | // DrawPropertySortableArray(props[i]);
104 | // }
105 | // else
106 | // {
107 | EditorGUILayout.PropertyField(props[i], true);
108 | //}
109 | }
110 |
111 | EditorGUILayout.Space();
112 |
113 | if (methods == null) return;
114 | foreach (MethodInfo memberInfo in methods)
115 | {
116 | this.UseButton(memberInfo);
117 | }
118 | }
119 |
120 | void Foldout(CacheFoldProp cache)
121 | {
122 | cache.expanded = EditorGUILayout.Foldout(cache.expanded, cache.atr.name, true,
123 | StyleFramework.foldout);
124 |
125 | if (cache.expanded)
126 | {
127 | EditorGUI.indentLevel = 1;
128 |
129 | for (int i = 0; i < cache.props.Count; i++)
130 | {
131 | this.UseVerticalLayout(() => Child(i), StyleFramework.boxChild);
132 | }
133 | }
134 |
135 | void Child(int i)
136 | {
137 | // if (cache.props[i].isArray)
138 | // {
139 | // DrawPropertySortableArray(cache.props[i]);
140 | // }
141 | // else
142 | // {
143 | EditorGUILayout.PropertyField(cache.props[i], new GUIContent(ObjectNames.NicifyVariableName(cache.props[i].name)), true);
144 | //}
145 | }
146 | }
147 |
148 | void Setup()
149 | {
150 | EditorFramework.currentEvent = Event.current;
151 | if (!initialized)
152 | {
153 | // SetupButtons();
154 |
155 | List objectFields;
156 | FoldoutAttribute prevFold = default;
157 |
158 | var length = EditorTypes.Get(target, out objectFields);
159 |
160 | for (var i = 0; i < length; i++)
161 | {
162 | #region FOLDERS
163 |
164 | var fold = Attribute.GetCustomAttribute(objectFields[i], typeof(FoldoutAttribute)) as FoldoutAttribute;
165 | CacheFoldProp c;
166 | if (fold == null)
167 | {
168 | if (prevFold != null && prevFold.foldEverything)
169 | {
170 | if (!cacheFolds.TryGetValue(prevFold.name, out c))
171 | {
172 | cacheFolds.Add(prevFold.name, new CacheFoldProp {atr = prevFold, types = new HashSet {objectFields[i].Name}});
173 | }
174 | else
175 | {
176 | c.types.Add(objectFields[i].Name);
177 | }
178 | }
179 |
180 | continue;
181 | }
182 |
183 | prevFold = fold;
184 |
185 | if (!cacheFolds.TryGetValue(fold.name, out c))
186 | {
187 | var expanded = EditorPrefs.GetBool(string.Format($"{fold.name}{objectFields[i].Name}{target.GetInstanceID()}"), false);
188 | cacheFolds.Add(fold.name, new CacheFoldProp {atr = fold, types = new HashSet {objectFields[i].Name}, expanded = expanded});
189 | }
190 | else c.types.Add(objectFields[i].Name);
191 |
192 | #endregion
193 | }
194 |
195 | var property = serializedObject.GetIterator();
196 | var next = property.NextVisible(true);
197 | if (next)
198 | {
199 | do
200 | {
201 | HandleFoldProp(property);
202 | } while (property.NextVisible(false));
203 | }
204 |
205 | initialized = true;
206 | }
207 | }
208 |
209 | // void SetupButtons()
210 | // {
211 | // var members = GetButtonMembers(target);
212 | //
213 | // foreach (var memberInfo in members)
214 | // {
215 | // var method = memberInfo as MethodInfo;
216 | // if (method == null)
217 | // {
218 | // continue;
219 | // }
220 | //
221 | // if (method.GetParameters().Length > 0)
222 | // {
223 | // continue;
224 | // }
225 | //
226 | // if (methods == null) methods = new List();
227 | // methods.Add(method);
228 | // }
229 | // }
230 | }
231 |
232 | public void HandleFoldProp(SerializedProperty prop)
233 | {
234 | bool shouldBeFolded = false;
235 |
236 | foreach (var pair in cacheFolds)
237 | {
238 | if (pair.Value.types.Contains(prop.name))
239 | {
240 | var pr = prop.Copy();
241 | shouldBeFolded = true;
242 | pair.Value.props.Add(pr);
243 |
244 | break;
245 | }
246 | }
247 |
248 | if (shouldBeFolded == false)
249 | {
250 | var pr = prop.Copy();
251 | props.Add(pr);
252 | }
253 | }
254 |
255 | // IEnumerable GetButtonMembers(object target)
256 | // {
257 | // return target.GetType()
258 | // .GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic)
259 | // .Where(CheckButtonAttribute);
260 | // }
261 |
262 | // bool CheckButtonAttribute(MemberInfo memberInfo)
263 | // {
264 | // return Attribute.IsDefined(memberInfo, typeof(ButtonAttribute));
265 | // }
266 |
267 | class CacheFoldProp
268 | {
269 | public HashSet types = new HashSet();
270 | public List props = new List();
271 | public FoldoutAttribute atr;
272 | public bool expanded;
273 |
274 | public void Dispose()
275 | {
276 | props.Clear();
277 | types.Clear();
278 | atr = null;
279 | }
280 | }
281 | }
282 |
283 | static class ditorUIHelper
284 | {
285 | public static void UseVerticalLayout(this Editor e, Action action, GUIStyle style)
286 | {
287 | EditorGUILayout.BeginVertical(style);
288 | action();
289 | EditorGUILayout.EndVertical();
290 | }
291 |
292 | public static void UseButton(this Editor e, MethodInfo m)
293 | {
294 | if (GUILayout.Button(m.Name))
295 | {
296 | m.Invoke(e.target, null);
297 | }
298 | }
299 | }
300 |
301 |
302 | static class StyleFramework
303 | {
304 | public static GUIStyle box;
305 | public static GUIStyle boxChild;
306 | public static GUIStyle foldout;
307 | public static GUIStyle button;
308 | public static GUIStyle text;
309 |
310 | static StyleFramework()
311 | {
312 | bool pro = EditorGUIUtility.isProSkin;
313 |
314 | var uiTex_in = Resources.Load("IN foldout focus-6510");
315 | var uiTex_in_on = Resources.Load("IN foldout focus on-5718");
316 |
317 | var c_on = pro ? Color.white : new Color(51 / 255f, 102 / 255f, 204 / 255f, 1);
318 |
319 | button = new GUIStyle(EditorStyles.miniButton);
320 | button.font = Font.CreateDynamicFontFromOSFont(new[] {"Terminus (TTF) for Windows", "Calibri"}, 17);
321 |
322 | text = new GUIStyle(EditorStyles.label);
323 | text.richText = true;
324 | text.contentOffset = new Vector2(0, 5);
325 | text.font = Font.CreateDynamicFontFromOSFont(new[] {"Terminus (TTF) for Windows", "Calibri"}, 14);
326 |
327 | foldout = new GUIStyle(EditorStyles.foldout);
328 |
329 | foldout.overflow = new RectOffset(-10, 0, 3, 0);
330 | foldout.padding = new RectOffset(25, 0, -3, 0);
331 |
332 | foldout.active.textColor = c_on;
333 | foldout.active.background = uiTex_in;
334 | foldout.onActive.textColor = c_on;
335 | foldout.onActive.background = uiTex_in_on;
336 |
337 | foldout.focused.textColor = c_on;
338 | foldout.focused.background = uiTex_in;
339 | foldout.onFocused.textColor = c_on;
340 | foldout.onFocused.background = uiTex_in_on;
341 |
342 | foldout.hover.textColor = c_on;
343 | foldout.hover.background = uiTex_in;
344 |
345 | foldout.onHover.textColor = c_on;
346 | foldout.onHover.background = uiTex_in_on;
347 |
348 | box = new GUIStyle(GUI.skin.box);
349 | box.padding = new RectOffset(10, 0, 10, 0);
350 |
351 | boxChild = new GUIStyle(GUI.skin.box);
352 | boxChild.active.textColor = c_on;
353 | boxChild.active.background = uiTex_in;
354 | boxChild.onActive.textColor = c_on;
355 | boxChild.onActive.background = uiTex_in_on;
356 |
357 | boxChild.focused.textColor = c_on;
358 | boxChild.focused.background = uiTex_in;
359 | boxChild.onFocused.textColor = c_on;
360 | boxChild.onFocused.background = uiTex_in_on;
361 |
362 | EditorStyles.foldout.active.textColor = c_on;
363 | EditorStyles.foldout.active.background = uiTex_in;
364 | EditorStyles.foldout.onActive.textColor = c_on;
365 | EditorStyles.foldout.onActive.background = uiTex_in_on;
366 |
367 | EditorStyles.foldout.focused.textColor = c_on;
368 | EditorStyles.foldout.focused.background = uiTex_in;
369 | EditorStyles.foldout.onFocused.textColor = c_on;
370 | EditorStyles.foldout.onFocused.background = uiTex_in_on;
371 |
372 | EditorStyles.foldout.hover.textColor = c_on;
373 | EditorStyles.foldout.hover.background = uiTex_in;
374 |
375 | EditorStyles.foldout.onHover.textColor = c_on;
376 | EditorStyles.foldout.onHover.background = uiTex_in_on;
377 | }
378 |
379 | public static string FirstLetterToUpperCase(this string s)
380 | {
381 | if (string.IsNullOrEmpty(s))
382 | return string.Empty;
383 |
384 | var a = s.ToCharArray();
385 | a[0] = char.ToUpper(a[0]);
386 | return new string(a);
387 | }
388 |
389 | public static IList GetTypeTree(this Type t)
390 | {
391 | var types = new List();
392 | while (t.BaseType != null)
393 | {
394 | types.Add(t);
395 | t = t.BaseType;
396 | }
397 |
398 | return types;
399 | }
400 | }
401 |
402 | static class EditorTypes
403 | {
404 | public static Dictionary> fields = new Dictionary>(FastComparable.Default);
405 |
406 | public static int Get(Object target, out List objectFields)
407 | {
408 | var t = target.GetType();
409 | var hash = t.GetHashCode();
410 |
411 | if (!fields.TryGetValue(hash, out objectFields))
412 | {
413 | var typeTree = t.GetTypeTree();
414 | objectFields = target.GetType()
415 | .GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic)
416 | .OrderByDescending(x => typeTree.IndexOf(x.DeclaringType))
417 | .ToList();
418 | fields.Add(hash, objectFields);
419 | }
420 |
421 | return objectFields.Count;
422 | }
423 | }
424 |
425 |
426 | class FastComparable : IEqualityComparer
427 | {
428 | public static FastComparable Default = new FastComparable();
429 |
430 | public bool Equals(int x, int y)
431 | {
432 | return x == y;
433 | }
434 |
435 | public int GetHashCode(int obj)
436 | {
437 | return obj.GetHashCode();
438 | }
439 | }
440 |
441 |
442 | [InitializeOnLoad]
443 | public static class EditorFramework
444 | {
445 | internal static bool needToRepaint;
446 |
447 | internal static Event currentEvent;
448 | internal static float t;
449 |
450 | static EditorFramework()
451 | {
452 | EditorApplication.update += Updating;
453 | }
454 |
455 |
456 | static void Updating()
457 | {
458 | CheckMouse();
459 |
460 | if (needToRepaint)
461 | {
462 | t += Time.deltaTime;
463 |
464 | if (t >= 0.3f)
465 | {
466 | t -= 0.3f;
467 | needToRepaint = false;
468 | }
469 | }
470 | }
471 |
472 | static void CheckMouse()
473 | {
474 | var ev = currentEvent;
475 | if (ev == null) return;
476 |
477 | if (ev.type == EventType.MouseMove)
478 | needToRepaint = true;
479 | }
480 | }
481 | }
482 |
--------------------------------------------------------------------------------