├── .gitattributes
├── .gitignore
├── Common
├── BetterList.cs
├── BetterList.cs.meta
├── CommonHelper.cs
├── CommonHelper.cs.meta
├── ContextMenu.cs
├── ContextMenu.cs.meta
├── Decorate.cs
├── Decorate.cs.meta
├── LayoutInfo.cs
├── LayoutInfo.cs.meta
├── PathSaver.cs
├── PathSaver.cs.meta
├── ReloadLayoutOnExitGame.cs
├── ReloadLayoutOnExitGame.cs.meta
├── ReopenLayoutOnExitGame.cs
├── ReopenLayoutOnExitGame.cs.meta
├── UIEditorHelper.cs
├── UIEditorHelper.cs.meta
├── UILayoutTool.cs
└── UILayoutTool.cs.meta
├── Configure.cs
├── Editor
├── CustomInspectors.cs
├── CustomInspectors.cs.meta
├── FindReferences.cs
├── FindReferences.cs.meta
├── PrefabWin.cs
├── PrefabWin.cs.meta
├── SceneEditor.cs
└── SceneEditor.cs.meta
├── README.md
└── Res
├── Canvas.prefab
├── Canvas.prefab.meta
├── Decorate.prefab
├── Decorate.prefab.meta
├── Preview.meta
└── Preview
└── _.gitkeep
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /[Ll]ibrary/
2 | /[Tt]emp/
3 | /[Oo]bj/
4 | /[Bb]uild/
5 | /[Bb]uilds/
6 | /Assets/Resources*
7 | Assets/UIEditor/Res/Preview/
8 | /Assets/AssetStoreTools*
9 |
10 |
11 | # Visual Studio 2015 cache directory
12 | /.vs/
13 |
14 | # Autogenerated VS/MD/Consulo solution and project files
15 | ExportedObj/
16 | .consulo/
17 | *.csproj
18 | *.unityproj
19 | *.sln
20 | *.suo
21 | *.tmp
22 | *.user
23 | *.userprefs
24 | *.pidb
25 | *.booproj
26 | *.svd
27 | *.pdb
28 |
29 | # Unity3D generated meta files
30 | *.pidb.meta
31 |
32 | # Unity3D Generated File On Crash Reports
33 | sysinfo.txt
34 |
35 | # Builds
36 | *.apk
37 | *.unitypackage
38 |
--------------------------------------------------------------------------------
/Common/BetterList.cs:
--------------------------------------------------------------------------------
1 | //-------------------------------------------------
2 | // NGUI: Next-Gen UI kit
3 | // Copyright © 2011-2017 Tasharen Entertainment Inc
4 | //-------------------------------------------------
5 |
6 | using UnityEngine;
7 | using System.Collections.Generic;
8 | using System.Diagnostics;
9 |
10 | ///
11 | /// This improved version of the System.Collections.Generic.List that doesn't release the buffer on Clear(),
12 | /// resulting in better performance and less garbage collection.
13 | /// PRO: BetterList performs faster than List when you Add and Remove items (although slower if you remove from the beginning).
14 | /// CON: BetterList performs worse when sorting the list. If your operations involve sorting, use the standard List instead.
15 | ///
16 |
17 | public class BetterList
18 | {
19 | #if UNITY_FLASH
20 |
21 | List mList = new List();
22 |
23 | ///
24 | /// Direct access to the buffer. Note that you should not use its 'Length' parameter, but instead use BetterList.size.
25 | ///
26 |
27 | public T this[int i]
28 | {
29 | get { return mList[i]; }
30 | set { mList[i] = value; }
31 | }
32 |
33 | ///
34 | /// Compatibility with the non-flash syntax.
35 | ///
36 |
37 | public List buffer { get { return mList; } }
38 |
39 | ///
40 | /// Direct access to the buffer's size. Note that it's only public for speed and efficiency. You shouldn't modify it.
41 | ///
42 |
43 | public int size { get { return mList.Count; } }
44 |
45 | ///
46 | /// For 'foreach' functionality.
47 | ///
48 |
49 | public IEnumerator GetEnumerator () { return mList.GetEnumerator(); }
50 |
51 | ///
52 | /// Clear the array by resetting its size to zero. Note that the memory is not actually released.
53 | ///
54 |
55 | public void Clear () { mList.Clear(); }
56 |
57 | ///
58 | /// Clear the array and release the used memory.
59 | ///
60 |
61 | public void Release () { mList.Clear(); }
62 |
63 | ///
64 | /// Add the specified item to the end of the list.
65 | ///
66 |
67 | public void Add (T item) { mList.Add(item); }
68 |
69 | ///
70 | /// Insert an item at the specified index, pushing the entries back.
71 | ///
72 |
73 | public void Insert (int index, T item)
74 | {
75 | if (index > -1 && index < mList.Count) mList.Insert(index, item);
76 | else mList.Add(item);
77 | }
78 |
79 | ///
80 | /// Returns 'true' if the specified item is within the list.
81 | ///
82 |
83 | public bool Contains (T item) { return mList.Contains(item); }
84 |
85 | ///
86 | /// Return the index of the specified item.
87 | ///
88 |
89 | public int IndexOf (T item) { return mList.IndexOf(item); }
90 |
91 | ///
92 | /// Remove the specified item from the list. Note that RemoveAt() is faster and is advisable if you already know the index.
93 | ///
94 |
95 | public bool Remove (T item) { return mList.Remove(item); }
96 |
97 | ///
98 | /// Remove an item at the specified index.
99 | ///
100 |
101 | public void RemoveAt (int index) { mList.RemoveAt(index); }
102 |
103 | ///
104 | /// Remove an item from the end.
105 | ///
106 |
107 | public T Pop ()
108 | {
109 | if (buffer != null && size != 0)
110 | {
111 | T val = buffer[mList.Count - 1];
112 | mList.RemoveAt(mList.Count - 1);
113 | return val;
114 | }
115 | return default(T);
116 | }
117 |
118 | ///
119 | /// Mimic List's ToArray() functionality, except that in this case the list is resized to match the current size.
120 | ///
121 |
122 | public T[] ToArray () { return mList.ToArray(); }
123 |
124 | ///
125 | /// List.Sort equivalent.
126 | ///
127 |
128 | public void Sort (System.Comparison comparer) { mList.Sort(comparer); }
129 |
130 | #else
131 |
132 | ///
133 | /// Direct access to the buffer. Note that you should not use its 'Length' parameter, but instead use BetterList.size.
134 | ///
135 |
136 | public T[] buffer;
137 |
138 | ///
139 | /// Direct access to the buffer's size. Note that it's only public for speed and efficiency. You shouldn't modify it.
140 | ///
141 |
142 | public int size = 0;
143 |
144 | ///
145 | /// For 'foreach' functionality.
146 | ///
147 |
148 | [DebuggerHidden]
149 | [DebuggerStepThrough]
150 | public IEnumerator GetEnumerator ()
151 | {
152 | if (buffer != null)
153 | {
154 | for (int i = 0; i < size; ++i)
155 | {
156 | yield return buffer[i];
157 | }
158 | }
159 | }
160 |
161 | ///
162 | /// Convenience function. I recommend using .buffer instead.
163 | ///
164 |
165 | [DebuggerHidden]
166 | public T this[int i]
167 | {
168 | get { return buffer[i]; }
169 | set { buffer[i] = value; }
170 | }
171 |
172 | ///
173 | /// Helper function that expands the size of the array, maintaining the content.
174 | ///
175 |
176 | void AllocateMore ()
177 | {
178 | T[] newList = (buffer != null) ? new T[Mathf.Max(buffer.Length << 1, 32)] : new T[32];
179 | if (buffer != null && size > 0) buffer.CopyTo(newList, 0);
180 | buffer = newList;
181 | }
182 |
183 | ///
184 | /// Trim the unnecessary memory, resizing the buffer to be of 'Length' size.
185 | /// Call this function only if you are sure that the buffer won't need to resize anytime soon.
186 | ///
187 |
188 | void Trim ()
189 | {
190 | if (size > 0)
191 | {
192 | if (size < buffer.Length)
193 | {
194 | T[] newList = new T[size];
195 | for (int i = 0; i < size; ++i) newList[i] = buffer[i];
196 | buffer = newList;
197 | }
198 | }
199 | else buffer = null;
200 | }
201 |
202 | ///
203 | /// Clear the array by resetting its size to zero. Note that the memory is not actually released.
204 | ///
205 |
206 | public void Clear () { size = 0; }
207 |
208 | ///
209 | /// Clear the array and release the used memory.
210 | ///
211 |
212 | public void Release () { size = 0; buffer = null; }
213 |
214 | ///
215 | /// Add the specified item to the end of the list.
216 | ///
217 |
218 | public void Add (T item)
219 | {
220 | if (buffer == null || size == buffer.Length) AllocateMore();
221 | buffer[size++] = item;
222 | }
223 |
224 | ///
225 | /// Insert an item at the specified index, pushing the entries back.
226 | ///
227 |
228 | public void Insert (int index, T item)
229 | {
230 | if (buffer == null || size == buffer.Length) AllocateMore();
231 |
232 | if (index > -1 && index < size)
233 | {
234 | for (int i = size; i > index; --i) buffer[i] = buffer[i - 1];
235 | buffer[index] = item;
236 | ++size;
237 | }
238 | else Add(item);
239 | }
240 |
241 | ///
242 | /// Returns 'true' if the specified item is within the list.
243 | ///
244 |
245 | public bool Contains (T item)
246 | {
247 | if (buffer == null) return false;
248 | for (int i = 0; i < size; ++i) if (buffer[i].Equals(item)) return true;
249 | return false;
250 | }
251 |
252 | ///
253 | /// Return the index of the specified item.
254 | ///
255 |
256 | public int IndexOf (T item)
257 | {
258 | if (buffer == null) return -1;
259 | for (int i = 0; i < size; ++i) if (buffer[i].Equals(item)) return i;
260 | return -1;
261 | }
262 |
263 | ///
264 | /// Remove the specified item from the list. Note that RemoveAt() is faster and is advisable if you already know the index.
265 | ///
266 |
267 | public bool Remove (T item)
268 | {
269 | if (buffer != null)
270 | {
271 | EqualityComparer comp = EqualityComparer.Default;
272 |
273 | for (int i = 0; i < size; ++i)
274 | {
275 | if (comp.Equals(buffer[i], item))
276 | {
277 | --size;
278 | buffer[i] = default(T);
279 | for (int b = i; b < size; ++b) buffer[b] = buffer[b + 1];
280 | buffer[size] = default(T);
281 | return true;
282 | }
283 | }
284 | }
285 | return false;
286 | }
287 |
288 | ///
289 | /// Remove an item at the specified index.
290 | ///
291 |
292 | public void RemoveAt (int index)
293 | {
294 | if (buffer != null && index > -1 && index < size)
295 | {
296 | --size;
297 | buffer[index] = default(T);
298 | for (int b = index; b < size; ++b) buffer[b] = buffer[b + 1];
299 | buffer[size] = default(T);
300 | }
301 | }
302 |
303 | ///
304 | /// Remove an item from the end.
305 | ///
306 |
307 | public T Pop ()
308 | {
309 | if (buffer != null && size != 0)
310 | {
311 | T val = buffer[--size];
312 | buffer[size] = default(T);
313 | return val;
314 | }
315 | return default(T);
316 | }
317 |
318 | ///
319 | /// Mimic List's ToArray() functionality, except that in this case the list is resized to match the current size.
320 | ///
321 |
322 | public T[] ToArray () { Trim(); return buffer; }
323 |
324 | //class Comparer : System.Collections.IComparer
325 | //{
326 | // public System.Comparison func;
327 | // public int Compare (object x, object y) { return func((T)x, (T)y); }
328 | //}
329 |
330 | //Comparer mComp = new Comparer();
331 |
332 | ///
333 | /// List.Sort equivalent. Doing Array.Sort causes GC allocations.
334 | ///
335 |
336 | //public void Sort (System.Comparison comparer)
337 | //{
338 | // if (size > 0)
339 | // {
340 | // mComp.func = comparer;
341 | // System.Array.Sort(buffer, 0, size, mComp);
342 | // }
343 | //}
344 |
345 | ///
346 | /// List.Sort equivalent. Manual sorting causes no GC allocations.
347 | ///
348 |
349 | [DebuggerHidden]
350 | [DebuggerStepThrough]
351 | public void Sort (CompareFunc comparer)
352 | {
353 | int start = 0;
354 | int max = size - 1;
355 | bool changed = true;
356 |
357 | while (changed)
358 | {
359 | changed = false;
360 |
361 | for (int i = start; i < max; ++i)
362 | {
363 | // Compare the two values
364 | if (comparer(buffer[i], buffer[i + 1]) > 0)
365 | {
366 | // Swap the values
367 | T temp = buffer[i];
368 | buffer[i] = buffer[i + 1];
369 | buffer[i + 1] = temp;
370 | changed = true;
371 | }
372 | else if (!changed)
373 | {
374 | // Nothing has changed -- we can start here next time
375 | start = (i == 0) ? 0 : i - 1;
376 | }
377 | }
378 | }
379 | }
380 |
381 | ///
382 | /// Comparison function should return -1 if left is less than right, 1 if left is greater than right, and 0 if they match.
383 | ///
384 |
385 | public delegate int CompareFunc (T left, T right);
386 | #endif
387 | }
388 |
--------------------------------------------------------------------------------
/Common/BetterList.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7c80989c78df03344839803db8983eb9
3 | timeCreated: 1520392679
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Common/CommonHelper.cs:
--------------------------------------------------------------------------------
1 | #if UNITY_EDITOR
2 | using UnityEngine;
3 | using System.Diagnostics;
4 | using System;
5 |
6 | namespace U3DExtends {
7 | public class CommonHelper {
8 | //生成parent下的唯一控件名
9 | public static string GenerateUniqueName(GameObject parent, string type)
10 | {
11 | var widgets = parent.GetComponentsInChildren();
12 | int test_num = 1;
13 | string test_name = type+"_"+test_num;
14 | RectTransform uiBase = null;
15 | int prevent_death_count = 0;//防止死循环
16 | do {
17 | test_name = type+"_"+test_num;
18 | uiBase = System.Array.Find(widgets, p => p.gameObject.name==test_name);
19 | test_num = test_num + UnityEngine.Random.Range(1, (prevent_death_count+1)*2);
20 | if (prevent_death_count++ >= 100)
21 | break;
22 | } while (uiBase != null);
23 |
24 | return test_name;
25 | }
26 |
27 | static public bool IsPointInRect(Vector3 mouse_abs_pos, RectTransform trans)
28 | {
29 | if (trans != null)
30 | {
31 | float l_t_x = trans.position.x;
32 | float l_t_y = trans.position.y;
33 | float r_b_x = l_t_x + trans.sizeDelta.x;
34 | float r_b_y = l_t_y - trans.sizeDelta.y;
35 | if (mouse_abs_pos.x >= l_t_x && mouse_abs_pos.y <= l_t_y && mouse_abs_pos.x <= r_b_x && mouse_abs_pos.y >= r_b_y)
36 | {
37 | return true;
38 | }
39 | }
40 | return false;
41 | }
42 |
43 | public static Color StringToColor(string hexString)
44 | {
45 | int start_index = 2;
46 | if (hexString.Length == 8)
47 | start_index = 2;
48 | else if (hexString.Length == 6)
49 | start_index = 0;
50 | byte r = byte.Parse(hexString.Substring(start_index, 2), System.Globalization.NumberStyles.HexNumber);
51 | byte g = byte.Parse(hexString.Substring(start_index+2, 2), System.Globalization.NumberStyles.HexNumber);
52 | byte b = byte.Parse(hexString.Substring(start_index+4, 2), System.Globalization.NumberStyles.HexNumber);
53 | return new Color(r / 255.0f, g / 255.0f, b / 255.0f);
54 | }
55 |
56 | public static string ColorToString(Color color)
57 | {
58 | string hexString = "";
59 | string color_hex = "00";
60 | color_hex = String.Format("{0:x}", (int)Mathf.Floor(color.r * 255));
61 | if (color_hex.Length < 2)
62 | color_hex = "0" + color_hex;
63 | hexString = hexString + color_hex;
64 | color_hex = String.Format("{0:x}", (int)Mathf.Floor(color.g * 255));
65 | if (color_hex.Length < 2)
66 | color_hex = "0" + color_hex;
67 | hexString = hexString + color_hex;
68 | color_hex = String.Format("{0:x}", (int)Mathf.Floor(color.b * 255));
69 | if (color_hex.Length < 2)
70 | color_hex = "0" + color_hex;
71 | hexString = hexString + color_hex;
72 | //UnityEngine.Debug.Log("hexString :" + hexString);
73 | return hexString;
74 | }
75 |
76 | public static Process ProcessCommand(string command, string argument)
77 | {
78 | UnityEngine.Debug.Log(string.Format("command : {0} argument{1}", command, argument));
79 | ProcessStartInfo start = new ProcessStartInfo(command);
80 | start.Arguments = argument;
81 | start.CreateNoWindow = true;
82 | start.ErrorDialog = true;
83 | start.UseShellExecute = false;
84 |
85 | if (start.UseShellExecute)
86 | {
87 | start.RedirectStandardOutput = false;
88 | start.RedirectStandardError = false;
89 | start.RedirectStandardInput = false;
90 | }
91 | else
92 | {
93 | start.RedirectStandardOutput = true;
94 | start.RedirectStandardError = true;
95 | start.RedirectStandardInput = true;
96 | start.StandardOutputEncoding = System.Text.UTF8Encoding.UTF8;
97 | start.StandardErrorEncoding = System.Text.UTF8Encoding.UTF8;
98 | }
99 |
100 | Process p = Process.Start(start);
101 | //string output = p.StandardOutput.ReadToEnd();
102 | //p.WaitForExit();
103 | return p;
104 | }
105 |
106 | //获取文件名
107 | public static string GetFileNameByPath(string path)
108 | {
109 | path = path.Replace("\\", "/");
110 | int last_gang_index = path.LastIndexOf("/");
111 | if (last_gang_index == -1)
112 | return "";
113 | last_gang_index++;
114 | string name = path.Substring(last_gang_index, path.Length - last_gang_index);
115 | int last_dot_index = name.LastIndexOf('.');
116 | if (last_dot_index == -1)
117 | return "";
118 | name = name.Substring(0, last_dot_index);
119 | return name;
120 | }
121 |
122 | //获取文件类型后缀
123 | public static string GetFileTypeSuffixByPath(string path)
124 | {
125 | path = path.Replace("\\", "/");
126 | int last_dot_index = path.LastIndexOf('.');
127 | if (last_dot_index == -1)
128 | return "";
129 | last_dot_index++;
130 | string type_str = path.Substring(last_dot_index, path.Length - last_dot_index);
131 | return type_str;
132 | }
133 | }
134 | }
135 | #endif
--------------------------------------------------------------------------------
/Common/CommonHelper.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c451c114c4e790f4ebc16668e49140c1
3 | timeCreated: 1520392679
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Common/ContextMenu.cs:
--------------------------------------------------------------------------------
1 | #if UNITY_EDITOR
2 | using UnityEngine;
3 | using UnityEditor;
4 | using System.Collections.Generic;
5 |
6 | namespace U3DExtends {
7 | static public class ContextMenu
8 | {
9 | static List mEntries = new List();
10 | static GenericMenu mMenu;
11 |
12 | static public void AddItem(string item, bool isChecked, GenericMenu.MenuFunction callback)
13 | {
14 | if (callback != null)
15 | {
16 | if (mMenu == null) mMenu = new GenericMenu();
17 | int count = 0;
18 |
19 | for (int i = 0; i < mEntries.Count; ++i)
20 | {
21 | string str = mEntries[i];
22 | if (str == item) ++count;
23 | }
24 | mEntries.Add(item);
25 |
26 | if (count > 0) item += " [" + count + "]";
27 | mMenu.AddItem(new GUIContent(item), isChecked, callback);
28 | }
29 | else AddDisabledItem(item);
30 | }
31 |
32 | static public void AddItemWithArge(string item, bool isChecked, GenericMenu.MenuFunction2 callback, object arge)
33 | {
34 | if (callback != null)
35 | {
36 | if (mMenu == null) mMenu = new GenericMenu();
37 | int count = 0;
38 |
39 | for (int i = 0; i < mEntries.Count; ++i)
40 | {
41 | string str = mEntries[i];
42 | if (str == item) ++count;
43 | }
44 | mEntries.Add(item);
45 |
46 | if (count > 0) item += " [" + count + "]";
47 | mMenu.AddItem(new GUIContent(item), isChecked, callback, arge);
48 | }
49 | else AddDisabledItem(item);
50 | }
51 |
52 | static public void Show()
53 | {
54 | if (mMenu != null)
55 | {
56 | mMenu.ShowAsContext();
57 | mMenu = null;
58 | mEntries.Clear();
59 | }
60 | }
61 |
62 | //增加几种对齐菜单
63 | static public void AddAlignMenu()
64 | {
65 | AddItem("对齐/左对齐 ←", false, AlignTool.AlignInHorziontalLeft);
66 | AddItem("对齐/右对齐 →", false, AlignTool.AlignInHorziontalRight);
67 | AddItem("对齐/上对齐 ↑", false, AlignTool.AlignInVerticalUp);
68 | AddItem("对齐/下对齐 ↓", false, AlignTool.AlignInVerticalDown);
69 | AddItem("对齐/水平均匀 |||", false, AlignTool.UniformDistributionInHorziontal);
70 | AddItem("对齐/垂直均匀 ☰", false, AlignTool.UniformDistributionInVertical);
71 | AddItem("对齐/一样大 ■", false, AlignTool.ResizeMax);
72 | AddItem("对齐/一样小 ●", false, AlignTool.ResizeMin);
73 | }
74 |
75 | //增加层次菜单
76 | static public void AddPriorityMenu()
77 | {
78 | AddItem("层次/最里层 ↑↑↑", false, PriorityTool.MoveToTopWidget);
79 | AddItem("层次/最外层 ↓↓↓", false, PriorityTool.MoveToBottomWidget);
80 | AddItem("层次/往里挤 ↑", false, PriorityTool.MoveUpWidget);
81 | AddItem("层次/往外挤 ↓", false, PriorityTool.MoveDownWidget);
82 | }
83 |
84 | //增加UI控件菜单
85 | static public void AddUIMenu()
86 | {
87 | AddItem("添加控件/Empty", false, UIEditorHelper.CreateEmptyObj);
88 | AddItem("添加控件/Image", false, UIEditorHelper.CreateImageObj);
89 | AddItem("添加控件/RawImage", false, UIEditorHelper.CreateRawImageObj);
90 | AddItem("添加控件/Button", false, UIEditorHelper.CreateButtonObj);
91 | AddItem("添加控件/Text", false, UIEditorHelper.CreateTextObj);
92 | AddItem("添加控件/HScroll", false, UIEditorHelper.CreateHScrollViewObj);
93 | AddItem("添加控件/VScroll", false, UIEditorHelper.CreateVScrollViewObj);
94 | }
95 |
96 | //增加UI组件菜单
97 | static public void AddUIComponentMenu()
98 | {
99 | AddItem("添加组件/Image", false, UIEditorHelper.AddImageComponent);
100 | //AddItem("添加组件/RawImage", false, UIEditorHelper.CreateRawImageObj);
101 | //AddItem("添加组件/Button", false, UIEditorHelper.CreateButtonObj);
102 | //AddItem("添加组件/Text", false, UIEditorHelper.CreateTextObj);
103 | AddItem("添加组件/HLayout", false, UIEditorHelper.AddHorizontalLayoutComponent);
104 | AddItem("添加组件/VLayout", false, UIEditorHelper.AddVerticalLayoutComponent);
105 | AddItem("添加组件/GridLayout", false, UIEditorHelper.AddGridLayoutGroupComponent);
106 |
107 | }
108 |
109 | //增加显示隐藏菜单
110 | static public void AddShowOrHideMenu()
111 | {
112 | bool hasHideWidget = false;
113 | foreach (var item in Selection.gameObjects)
114 | {
115 | if (!item.activeSelf)
116 | {
117 | hasHideWidget = true;
118 | break;
119 | }
120 | }
121 | if (hasHideWidget)
122 | AddItem("显示", false, UILayoutTool.ShowAllSelectedWidgets);
123 | else
124 | AddItem("隐藏", false, UILayoutTool.HideAllSelectedWidgets);
125 | }
126 |
127 | static public void AddCommonItems(GameObject[] targets)
128 | {
129 | if (targets == null || targets.Length <= 0)
130 | {
131 | AddItem("新建", false, UIEditorHelper.CreatNewLayoutForMenu);
132 | AddItem("打开界面", false, UIEditorHelper.LoadLayout);
133 | AddItem("打开文件夹", false, UIEditorHelper.LoadLayoutWithFolder);
134 | }
135 | if (targets != null && targets.Length > 0)
136 | {
137 | AddItem("保存", false, UIEditorHelper.SaveLayoutForMenu);
138 | AddItem("另存为", false, UIEditorHelper.SaveAnotherLayoutContextMenu);
139 | AddItem("重新加载", false, UIEditorHelper.ReLoadLayoutForMenu);
140 |
141 | AddSeparator("///");
142 | AddItem("复制选中控件名", false, UIEditorHelper.CopySelectWidgetName);
143 |
144 | //如果选中超过1个节点的话
145 | if (targets.Length > 1)
146 | {
147 | AddAlignMenu();
148 | AddItem("同流合污", false, UILayoutTool.MakeGroup);
149 | }
150 | AddSeparator("///");
151 | if (targets.Length == 1)
152 | {
153 | AddUIMenu();
154 | AddUIComponentMenu();
155 | AddPriorityMenu();
156 |
157 | if (UIEditorHelper.IsNodeCanDivide(targets[0]))
158 | AddItem("分道扬镖", false, UILayoutTool.UnGroup);
159 | Decorate uiBase = targets[0].GetComponent();
160 | if (uiBase != null)
161 | {
162 | if (uiBase.gameObject.hideFlags == HideFlags.NotEditable)
163 | {
164 | AddItem("解锁", false, UIEditorHelper.UnLockWidget);
165 | }
166 | else
167 | {
168 | AddItem("锁定", false, UIEditorHelper.LockWidget);
169 | }
170 | }
171 | }
172 |
173 | AddShowOrHideMenu();
174 |
175 | AddSeparator("///");
176 |
177 | AddItem("添加参考图", false, UIEditorHelper.CreateDecorate);
178 | if (targets.Length == 1 && targets[0].transform.childCount > 0)
179 | AddItem("优化层级", false, UILayoutTool.OptimizeBatchForMenu);
180 |
181 | }
182 | AddItem("排序所有界面", false, UILayoutTool.ResortAllLayout);
183 | AddItem("清空界面", false, UIEditorHelper.ClearAllCanvas);
184 | }
185 |
186 | static public void AddSeparator(string path)
187 | {
188 | if (mMenu == null) mMenu = new GenericMenu();
189 |
190 | if (Application.platform != RuntimePlatform.OSXEditor)
191 | mMenu.AddSeparator(path);
192 | }
193 |
194 | static public void AddDisabledItem(string item)
195 | {
196 | if (mMenu == null) mMenu = new GenericMenu();
197 | mMenu.AddDisabledItem(new GUIContent(item));
198 | }
199 | }
200 | }
201 | #endif
--------------------------------------------------------------------------------
/Common/ContextMenu.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6fe4cd445ce309344932a7f21c4e0e4e
3 | timeCreated: 1520818956
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Common/Decorate.cs:
--------------------------------------------------------------------------------
1 | #if UNITY_EDITOR
2 | using UnityEngine;
3 | using UnityEngine.UI;
4 |
5 | namespace U3DExtends
6 | {
7 | [RequireComponent(typeof(RectTransform))]
8 | [ExecuteInEditMode]
9 | public class Decorate : MonoBehaviour
10 | {
11 | string spr_path = "";
12 | [SerializeField]
13 | [HideInInspector]
14 | private Image _image;
15 |
16 | Vector3 _lastPos = new Vector3(-1, -1);
17 | Vector2 _lastSize = Vector2.zero;
18 |
19 | public string SprPath
20 | {
21 | get { return spr_path; }
22 | set
23 | {
24 | LoadSpr(value);
25 | }
26 | }
27 |
28 | public void LoadSpr(string path)
29 | {
30 | InitComponent();
31 | if (spr_path != path)
32 | {
33 | spr_path = path;
34 | _image.sprite = UIEditorHelper.LoadSpriteInLocal(path);
35 | _image.SetNativeSize();
36 | gameObject.name = CommonHelper.GetFileNameByPath(path);
37 | //Debug.Log("_image.sprite :" + (_image.sprite != null).ToString());
38 | }
39 | }
40 |
41 | protected void Start()
42 | {
43 | InitComponent();
44 | }
45 |
46 | protected void InitComponent()
47 | {
48 | if (_image == null)
49 | _image = GetComponent();
50 | }
51 |
52 | public bool IsChangedTrans()
53 | {
54 | RectTransform curTrans = transform as RectTransform;
55 | if (curTrans.localPosition == _lastPos && curTrans.sizeDelta == _lastSize)
56 | return false;
57 | else
58 | return true;
59 | }
60 |
61 | public void SaveTrans()
62 | {
63 | RectTransform rectTrans = transform as RectTransform;
64 | _lastPos = rectTrans.localPosition;
65 | _lastSize = rectTrans.sizeDelta;
66 | }
67 |
68 | }
69 | }
70 | #endif
--------------------------------------------------------------------------------
/Common/Decorate.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 533a76e193efebc48ab9061535a0b110
3 | timeCreated: 1521105297
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Common/LayoutInfo.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuhaopen/UGUI-Editor/3144f295379d0f7e7c2f1dd1492657bc128bb5f9/Common/LayoutInfo.cs
--------------------------------------------------------------------------------
/Common/LayoutInfo.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 85543a2dadd029c42a60f1b3eb371827
3 | timeCreated: 1531211532
4 | licenseType: Pro
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/Common/PathSaver.cs:
--------------------------------------------------------------------------------
1 | #if UNITY_EDITOR
2 | using UnityEditor;
3 |
4 | //路径保存器,记录上次打开的路径,不同项目的不同用处路径都分开保存
5 | namespace U3DExtends
6 | {
7 | public enum PathType {
8 | //OpenLayout,//打开布局时默认打开的文件夹路径//和Save用同个会方便点
9 | SaveLayout,//保存布局时默认打开的文件夹路径
10 | OpenDecorate,//选择参考图时默认打开的文件夹路径
11 | PrefabTool,//Prefab界面用的
12 | }
13 | public class PathSaver {
14 | private volatile static PathSaver _instance = null;
15 | private static readonly object lockHelper = new object();
16 | private PathSaver() { }
17 | public static PathSaver GetInstance()
18 | {
19 | if(_instance == null)
20 | {
21 | lock(lockHelper)
22 | {
23 | if(_instance == null)
24 | _instance = new PathSaver();
25 | }
26 | }
27 | return _instance;
28 | }
29 |
30 | public string GeDefaultPath(PathType type)
31 | {
32 | return "";
33 | }
34 |
35 | public string GetLastPath(PathType type)
36 | {
37 | return EditorPrefs.GetString("PathSaver_" + U3DExtends.Configure.ProjectUUID + "_" + type.ToString(), GeDefaultPath(type));
38 | }
39 |
40 | public void SetLastPath(PathType type, string path)
41 | {
42 | if (path == "")
43 | return;
44 | path = System.IO.Path.GetDirectoryName(path);
45 | EditorPrefs.SetString("PathSaver_" + U3DExtends.Configure.ProjectUUID + "_" + type.ToString(), path);
46 | }
47 |
48 | }
49 | }
50 | #endif
--------------------------------------------------------------------------------
/Common/PathSaver.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5a399f9e8d9b3ec48ae81f9a2c031840
3 | timeCreated: 1520819465
4 | licenseType: Pro
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Common/ReloadLayoutOnExitGame.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liuhaopen/UGUI-Editor/3144f295379d0f7e7c2f1dd1492657bc128bb5f9/Common/ReloadLayoutOnExitGame.cs
--------------------------------------------------------------------------------
/Common/ReloadLayoutOnExitGame.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3e567ee5ac5ca9b4897ca6ca15bb480b
3 | timeCreated: 1531359091
4 | licenseType: Pro
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/Common/ReopenLayoutOnExitGame.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 |
4 | namespace U3DExtends
5 | {
6 | public class ReopenLayoutOnExitGame : MonoBehaviour
7 | {
8 | #if UNITY_EDITOR
9 | // class ReopenInfo
10 | // {
11 | // string path;
12 | // Vector3 pos;
13 | // }
14 | private static ReopenLayoutOnExitGame Instance;
15 |
16 | private static Dictionary layout_open_in_playmode = new Dictionary();
17 | private bool isRunningGame = false;
18 |
19 | public static void RecordOpenLayout(string path, Vector3 pos)
20 | {
21 | Debug.Log("record : "+path+" pos:"+pos.ToString());
22 | if (Instance != null && Instance.isRunningGame && path!="")
23 | {
24 | layout_open_in_playmode.Add(path, pos);
25 | }
26 | }
27 |
28 | private void Start()
29 | {
30 | Instance = this;
31 | // hadSaveOnRunTime = false;
32 | Debug.Log("Start");
33 | isRunningGame = true;
34 | }
35 |
36 | private void OnDisable() {
37 | // Debug.Log("disable");
38 | Instance = null;
39 | }
40 |
41 | private void OnTransformChildrenChanged() {
42 | Debug.Log("OnTransformChildrenChanged");
43 | List wait_delete_key = new List();
44 | foreach (var item in layout_open_in_playmode)
45 | {
46 | bool had_find = false;
47 | for (int i = 0; i < transform.childCount; i++)
48 | {
49 | LayoutInfo info = transform.GetChild(i).GetComponent();
50 | if (info && info.LayoutPath == item.Key)
51 | {
52 | had_find = true;
53 | break;
54 | }
55 | }
56 | if (!had_find)
57 | {
58 | wait_delete_key.Add(item.Key);
59 | }
60 | }
61 | foreach (var item in wait_delete_key)
62 | {
63 | layout_open_in_playmode.Remove(item);
64 | }
65 | }
66 |
67 | private void OnApplicationQuit()
68 | {
69 | Debug.Log("OnApplicationQuit");
70 | isRunningGame = false;
71 | if (layout_open_in_playmode.Count>0 && U3DExtends.Configure.ReloadLayoutOnExitGame)
72 | {
73 | System.Action p = null;
74 | p = new System.Action((UnityEditor.PlayModeStateChange c) => {
75 | foreach (var item in layout_open_in_playmode)
76 | {
77 | // Debug.Log("item.Key : "+item.Key);
78 | Transform layout = UIEditorHelper.LoadLayoutByPath(item.Key);
79 | if (layout != null)
80 | {
81 | layout.localPosition = item.Value;
82 | }
83 | }
84 | layout_open_in_playmode.Clear();
85 | UnityEditor.EditorApplication.playModeStateChanged -= p;
86 | });
87 | UnityEditor.EditorApplication.playModeStateChanged += p;
88 | }
89 | }
90 | #endif
91 | }
92 | }
--------------------------------------------------------------------------------
/Common/ReopenLayoutOnExitGame.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: eae15c9b8c4e77d46bf3ff140ad806f7
3 | timeCreated: 1540622474
4 | licenseType: Free
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/Common/UIEditorHelper.cs:
--------------------------------------------------------------------------------
1 | #if UNITY_EDITOR
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Reflection;
5 | using UnityEditor;
6 | using UnityEngine;
7 | using UnityEngine.UI;
8 |
9 | namespace U3DExtends
10 | {
11 | public static class UIEditorHelper
12 | {
13 | public static void SetImageByPath(string assetPath, Image image, bool isNativeSize = true)
14 | {
15 | Object newImg = UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath, typeof(Sprite));
16 | Undo.RecordObject(image, "Change Image");//有了这句才可以用ctrl+z撤消此赋值操作
17 | image.sprite = newImg as Sprite;
18 | if (isNativeSize)
19 | image.SetNativeSize();
20 | EditorUtility.SetDirty(image);
21 | }
22 |
23 | [MenuItem("Edit/Copy Names " + Configure.ShortCut.CopyNodesName, false, 2)]
24 | public static void CopySelectWidgetName()
25 | {
26 | string result = "";
27 | foreach (var item in Selection.gameObjects)
28 | {
29 | string item_name = item.name;
30 | Transform root_trans = item.transform.parent;
31 | while (root_trans != null && root_trans.GetComponent() == null)
32 | {
33 | if (root_trans.parent != null && root_trans.parent.GetComponent() == null)
34 | item_name = root_trans.name + "/" + item_name;
35 | else
36 | break;
37 | root_trans = root_trans.parent;
38 | }
39 | result = result + "\"" + item_name + "\",";
40 | }
41 |
42 | //复制到系统全局的粘贴板上
43 | GUIUtility.systemCopyBuffer = result;
44 | Debug.Log("Copy Nodes Name Succeed!");
45 | }
46 |
47 | public static Transform GetRootLayout(Transform trans)
48 | {
49 | Transform result = null;
50 | Canvas canvas = trans.GetComponentInParent