源战役客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

411 line
17 KiB

  1. #if UNITY_EDITOR
  2. using UnityEngine;
  3. using UnityEditor;
  4. using System.Linq;
  5. using System.Collections.Generic;
  6. using UnityEngine.UI;
  7. namespace U3DExtends
  8. {
  9. public class UILayoutTool : MonoBehaviour
  10. {
  11. public static void ResortAllLayout()
  12. {
  13. GameObject testUI = GameObject.Find(Configure.UITestNodeName);
  14. if (testUI != null)
  15. {
  16. LayoutInfo[] layouts = testUI.GetComponentsInChildren<LayoutInfo>();
  17. if (layouts.Length > 0)
  18. {
  19. SceneView.lastActiveSceneView.MoveToView(layouts[0].transform);
  20. RectTransform first_trans = layouts[0].transform as RectTransform;
  21. Vector2 startPos = new Vector2(first_trans.sizeDelta.x*first_trans.localScale.x/2, -first_trans.sizeDelta.y * first_trans.localScale.y/2);
  22. int index = 0;
  23. foreach (var item in layouts)
  24. {
  25. int row = index / 5;
  26. int col = index % 5;
  27. RectTransform rectTrans = item.transform as RectTransform;
  28. Vector3 pos = new Vector3((rectTrans.sizeDelta.x*rectTrans.localScale.x) * col + startPos.x, (-rectTrans.sizeDelta.y * rectTrans.localScale.y) * row + startPos.y, 0);
  29. item.transform.localPosition = pos;
  30. index++;
  31. }
  32. }
  33. }
  34. }
  35. public static void OptimizeBatchForMenu()
  36. {
  37. OptimizeBatch(Selection.activeTransform);
  38. }
  39. public static void OptimizeBatch(Transform trans)
  40. {
  41. if (trans == null)
  42. return;
  43. Dictionary<string, List<Transform>> imageGroup = new Dictionary<string, List<Transform>>();
  44. Dictionary<string, List<Transform>> textGroup = new Dictionary<string, List<Transform>>();
  45. Dictionary<string, List<Transform>> tmpGroup = new Dictionary<string, List<Transform>>();
  46. List<List<Transform>> sortedImgageGroup = new List<List<Transform>>();
  47. List<List<Transform>> sortedTextGroup = new List<List<Transform>>();
  48. List<List<Transform>> sortedTmpGroup = new List<List<Transform>>();
  49. for (int i = 0; i < trans.childCount; i++)
  50. {
  51. Transform child = trans.GetChild(i);
  52. Texture cur_texture = null;
  53. Image img = child.GetComponent<Image>();
  54. if (img != null)
  55. {
  56. cur_texture = img.mainTexture;
  57. }
  58. else
  59. {
  60. RawImage rimg = child.GetComponent<RawImage>();
  61. if (rimg != null)
  62. cur_texture = rimg.mainTexture;
  63. }
  64. if (cur_texture != null)
  65. {
  66. string cur_path = AssetDatabase.GetAssetPath(cur_texture);
  67. TextureImporter importer = AssetImporter.GetAtPath(cur_path) as TextureImporter;
  68. //Debug.Log("cur_path : " + cur_path + " importer:"+(importer!=null).ToString());
  69. if (importer != null)
  70. {
  71. string atlas = importer.spritePackingTag;
  72. //Debug.Log("atlas : " + atlas);
  73. if (atlas != "")
  74. {
  75. if (!imageGroup.ContainsKey(atlas))
  76. {
  77. List<Transform> list = new List<Transform>();
  78. sortedImgageGroup.Add(list);
  79. imageGroup.Add(atlas, list);
  80. }
  81. imageGroup[atlas].Add(child);
  82. }
  83. }
  84. }
  85. else
  86. {
  87. Text text = child.GetComponent<Text>();
  88. TMPro.TextMeshProUGUI tmp = child.GetComponent<TMPro.TextMeshProUGUI>();
  89. if (text != null)
  90. {
  91. string fontName = text.font.name;
  92. //Debug.Log("fontName : " + fontName);
  93. if (!textGroup.ContainsKey(fontName))
  94. {
  95. List<Transform> list = new List<Transform>();
  96. sortedTextGroup.Add(list);
  97. textGroup.Add(fontName, list);
  98. }
  99. textGroup[fontName].Add(child);
  100. }
  101. else if (tmp != null)
  102. {
  103. string fontName = tmp.font.name + "_tmp";
  104. if (!tmpGroup.ContainsKey(fontName))
  105. {
  106. List<Transform> list = new List<Transform>();
  107. sortedTmpGroup.Add(list);
  108. tmpGroup.Add(fontName, list);
  109. }
  110. tmpGroup[fontName].Add(child);
  111. }
  112. }
  113. OptimizeBatch(child);
  114. }
  115. //同一图集的Image间层级顺序继续保留,不同图集的顺序就按每组第一张的来
  116. for (int i = sortedImgageGroup.Count - 1; i >= 0; i--)
  117. {
  118. List<Transform> children = sortedImgageGroup[i];
  119. for (int j = children.Count - 1; j >= 0; j--)
  120. {
  121. children[j].SetAsFirstSibling();
  122. }
  123. }
  124. foreach (var item in sortedTextGroup)
  125. {
  126. List<Transform> children = item;
  127. for (int i = 0; i < children.Count; i++)
  128. {
  129. children[i].SetAsLastSibling();
  130. }
  131. }
  132. foreach (var item in sortedTmpGroup)
  133. {
  134. List<Transform> children = item;
  135. for (int i = 0; i < children.Count; i++)
  136. {
  137. children[i].SetAsLastSibling();
  138. }
  139. }
  140. }
  141. public static void ShowAllSelectedWidgets()
  142. {
  143. foreach (var item in Selection.gameObjects)
  144. {
  145. item.SetActive(true);
  146. }
  147. }
  148. public static void HideAllSelectedWidgets()
  149. {
  150. foreach (var item in Selection.gameObjects)
  151. {
  152. item.SetActive(false);
  153. }
  154. }
  155. //[MenuItem("UIEditor/Operate/解除")]
  156. public static void UnGroup()
  157. {
  158. if (Selection.gameObjects == null || Selection.gameObjects.Length <= 0)
  159. {
  160. EditorUtility.DisplayDialog("Error", "当前没有选中节点", "Ok");
  161. return;
  162. }
  163. if (Selection.gameObjects.Length > 1)
  164. {
  165. EditorUtility.DisplayDialog("Error", "只能同时解除一个Box", "Ok");
  166. return;
  167. }
  168. GameObject target = Selection.activeGameObject;
  169. Transform new_parent = target.transform.parent;
  170. if (target.transform.childCount > 0)
  171. {
  172. Transform[] child_ui = target.transform.GetComponentsInChildren<Transform>(true);
  173. foreach (var item in child_ui)
  174. {
  175. //不是自己的子节点或是自己的话就跳过
  176. if (item.transform.parent != target.transform || item.transform == target.transform)
  177. continue;
  178. item.transform.SetParent(new_parent, true);
  179. }
  180. Undo.DestroyObjectImmediate(target);
  181. //GameObject.DestroyImmediate(target);
  182. }
  183. else
  184. {
  185. EditorUtility.DisplayDialog("Error", "选择对象容器控件", "Ok");
  186. }
  187. }
  188. //[MenuItem("UIEditor/Operate/组合")]
  189. public static void MakeGroup()
  190. {
  191. if (Selection.gameObjects == null || Selection.gameObjects.Length <= 0)
  192. {
  193. EditorUtility.DisplayDialog("Error", "当前没有选中节点", "Ok");
  194. return;
  195. }
  196. //先判断选中的节点是不是挂在同个父节点上的
  197. Transform parent = Selection.gameObjects[0].transform.parent;
  198. foreach (var item in Selection.gameObjects)
  199. {
  200. if (item.transform.parent != parent)
  201. {
  202. EditorUtility.DisplayDialog("Error", "不能跨容器组合", "Ok");
  203. return;
  204. }
  205. }
  206. GameObject box = new GameObject("container", typeof(RectTransform));
  207. Undo.IncrementCurrentGroup();
  208. int group_index = Undo.GetCurrentGroup();
  209. Undo.SetCurrentGroupName("Make Group");
  210. Undo.RegisterCreatedObjectUndo(box, "create group object");
  211. RectTransform rectTrans = box.GetComponent<RectTransform>();
  212. if (rectTrans != null)
  213. {
  214. Vector2 left_top_pos = new Vector2(99999, -99999);
  215. Vector2 right_bottom_pos = new Vector2(-99999, 99999);
  216. foreach (var item in Selection.gameObjects)
  217. {
  218. Bounds bound = UIEditorHelper.GetBounds(item);
  219. Vector3 boundMin = item.transform.parent.InverseTransformPoint(bound.min);
  220. Vector3 boundMax = item.transform.parent.InverseTransformPoint(bound.max);
  221. //Debug.Log("bound : " + boundMin.ToString() + " max:" + boundMax.ToString());
  222. if (boundMin.x < left_top_pos.x)
  223. left_top_pos.x = boundMin.x;
  224. if (boundMax.y > left_top_pos.y)
  225. left_top_pos.y = boundMax.y;
  226. if (boundMax.x > right_bottom_pos.x)
  227. right_bottom_pos.x = boundMax.x;
  228. if (boundMin.y < right_bottom_pos.y)
  229. right_bottom_pos.y = boundMin.y;
  230. }
  231. rectTrans.SetParent(parent);
  232. rectTrans.sizeDelta = new Vector2(right_bottom_pos.x - left_top_pos.x, left_top_pos.y - right_bottom_pos.y);
  233. left_top_pos.x += rectTrans.sizeDelta.x/2;
  234. left_top_pos.y -= rectTrans.sizeDelta.y/2;
  235. rectTrans.localPosition = left_top_pos;
  236. rectTrans.localScale = Vector3.one;
  237. //需要先生成好Box和设置好它的坐标和大小才可以把选中的节点挂进来,注意要先排好序,不然层次就乱了
  238. GameObject[] sorted_objs = Selection.gameObjects.OrderBy(x => x.transform.GetSiblingIndex()).ToArray();
  239. for (int i = 0; i < sorted_objs.Length; i++)
  240. {
  241. Undo.SetTransformParent(sorted_objs[i].transform, rectTrans, "move item to group");
  242. }
  243. }
  244. Selection.activeGameObject = box;
  245. Undo.CollapseUndoOperations(group_index);
  246. }
  247. }
  248. public class PriorityTool
  249. {
  250. // [MenuItem("UIEditor/层次/最里层 " + Configure.ShortCut.MoveNodeTop)]
  251. public static void MoveToTopWidget()
  252. {
  253. Transform curSelect = Selection.activeTransform;
  254. if (curSelect != null)
  255. {
  256. curSelect.SetAsFirstSibling();
  257. }
  258. }
  259. // [MenuItem("UIEditor/层次/最外层 " + Configure.ShortCut.MoveNodeBottom)]
  260. public static void MoveToBottomWidget()
  261. {
  262. Transform curSelect = Selection.activeTransform;
  263. if (curSelect != null)
  264. {
  265. curSelect.SetAsLastSibling();
  266. }
  267. }
  268. // [MenuItem("UIEditor/层次/往里挤 " + Configure.ShortCut.MoveNodeUp)]
  269. public static void MoveUpWidget()
  270. {
  271. Transform curSelect = Selection.activeTransform;
  272. if (curSelect != null)
  273. {
  274. int curIndex = curSelect.GetSiblingIndex();
  275. if (curIndex > 0)
  276. curSelect.SetSiblingIndex(curIndex - 1);
  277. }
  278. }
  279. // [MenuItem("UIEditor/层次/往外挤 " + Configure.ShortCut.MoveNodeDown)]
  280. public static void MoveDownWidget()
  281. {
  282. Transform curSelect = Selection.activeTransform;
  283. if (curSelect != null)
  284. {
  285. int curIndex = curSelect.GetSiblingIndex();
  286. int child_num = curSelect.parent.childCount;
  287. if (curIndex < child_num - 1)
  288. curSelect.SetSiblingIndex(curIndex + 1);
  289. }
  290. }
  291. }
  292. public class AlignTool
  293. {
  294. // [MenuItem("UIEditor/对齐/左对齐 ←")]
  295. internal static void AlignInHorziontalLeft()
  296. {
  297. float x = Mathf.Min(Selection.gameObjects.Select(obj => obj.transform.localPosition.x).ToArray());
  298. foreach (GameObject gameObject in Selection.gameObjects)
  299. {
  300. gameObject.transform.localPosition = new Vector2(x,
  301. gameObject.transform.localPosition.y);
  302. }
  303. }
  304. // [MenuItem("UIEditor/对齐/右对齐 →")]
  305. public static void AlignInHorziontalRight()
  306. {
  307. float x = Mathf.Max(Selection.gameObjects.Select(obj => obj.transform.localPosition.x +
  308. ((RectTransform)obj.transform).sizeDelta.x).ToArray());
  309. foreach (GameObject gameObject in Selection.gameObjects)
  310. {
  311. gameObject.transform.localPosition = new Vector3(x -
  312. ((RectTransform)gameObject.transform).sizeDelta.x, gameObject.transform.localPosition.y);
  313. }
  314. }
  315. // [MenuItem("UIEditor/对齐/上对齐 ↑")]
  316. public static void AlignInVerticalUp()
  317. {
  318. float y = Mathf.Max(Selection.gameObjects.Select(obj => obj.transform.localPosition.y).ToArray());
  319. foreach (GameObject gameObject in Selection.gameObjects)
  320. {
  321. gameObject.transform.localPosition = new Vector3(gameObject.transform.localPosition.x, y);
  322. }
  323. }
  324. // [MenuItem("UIEditor/对齐/下对齐 ↓")]
  325. public static void AlignInVerticalDown()
  326. {
  327. float y = Mathf.Min(Selection.gameObjects.Select(obj => obj.transform.localPosition.y -
  328. ((RectTransform)obj.transform).sizeDelta.y).ToArray());
  329. foreach (GameObject gameObject in Selection.gameObjects)
  330. {
  331. gameObject.transform.localPosition = new Vector3(gameObject.transform.localPosition.x, y + ((RectTransform)gameObject.transform).sizeDelta.y);
  332. }
  333. }
  334. // [MenuItem("UIEditor/对齐/水平均匀 |||")]
  335. public static void UniformDistributionInHorziontal()
  336. {
  337. int count = Selection.gameObjects.Length;
  338. float firstX = Mathf.Min(Selection.gameObjects.Select(obj => obj.transform.localPosition.x).ToArray());
  339. float lastX = Mathf.Max(Selection.gameObjects.Select(obj => obj.transform.localPosition.x).ToArray());
  340. float distance = (lastX - firstX) / (count - 1);
  341. var objects = Selection.gameObjects.ToList();
  342. objects.Sort((x, y) => (int)(x.transform.localPosition.x - y.transform.localPosition.x));
  343. for (int i = 0; i < count; i++)
  344. {
  345. objects[i].transform.localPosition = new Vector3(firstX + i * distance, objects[i].transform.localPosition.y);
  346. }
  347. }
  348. // [MenuItem("UIEditor/对齐/垂直均匀 ☰")]
  349. public static void UniformDistributionInVertical()
  350. {
  351. int count = Selection.gameObjects.Length;
  352. float firstY = Mathf.Min(Selection.gameObjects.Select(obj => obj.transform.localPosition.y).ToArray());
  353. float lastY = Mathf.Max(Selection.gameObjects.Select(obj => obj.transform.localPosition.y).ToArray());
  354. float distance = (lastY - firstY) / (count - 1);
  355. var objects = Selection.gameObjects.ToList();
  356. objects.Sort((x, y) => (int)(x.transform.localPosition.y - y.transform.localPosition.y));
  357. for (int i = 0; i < count; i++)
  358. {
  359. objects[i].transform.localPosition = new Vector3(objects[i].transform.localPosition.x, firstY + i * distance);
  360. }
  361. }
  362. // [MenuItem("UIEditor/对齐/一样大 ■")]
  363. public static void ResizeMax()
  364. {
  365. var height = Mathf.Max(Selection.gameObjects.Select(obj => ((RectTransform)obj.transform).sizeDelta.y).ToArray());
  366. var width = Mathf.Max(Selection.gameObjects.Select(obj => ((RectTransform)obj.transform).sizeDelta.x).ToArray());
  367. foreach (GameObject gameObject in Selection.gameObjects)
  368. {
  369. ((RectTransform)gameObject.transform).sizeDelta = new Vector2(width, height);
  370. }
  371. }
  372. // [MenuItem("UIEditor/对齐/一样小 ●")]
  373. public static void ResizeMin()
  374. {
  375. var height = Mathf.Min(Selection.gameObjects.Select(obj => ((RectTransform)obj.transform).sizeDelta.y).ToArray());
  376. var width = Mathf.Min(Selection.gameObjects.Select(obj => ((RectTransform)obj.transform).sizeDelta.x).ToArray());
  377. foreach (GameObject gameObject in Selection.gameObjects)
  378. {
  379. ((RectTransform)gameObject.transform).sizeDelta = new Vector2(width, height);
  380. }
  381. }
  382. }
  383. }
  384. #endif