界面:

image.png

实现功能介绍:

①将Prefab的名称修改成指定的名称(包括子级的名称)
②将新生成的Prefab创建到指定路径下

使用方法:

① AssetDatabase.GetAssetPath(Object assetObject)获取文件路径
②文件获取路径(针对到后缀名)
image.png

  1. private static string FilePath()//文件路径获取
  2. {
  3. string[] guids = Selection.assetGUIDs;
  4. if (guids.Length < 0)
  5. return null;
  6. for (int i = 0; i < guids.Length; i++)
  7. {
  8. assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
  9. }
  10. return assetPath;
  11. }

③ PrefabUtility.SaveAsPrefabAsset(GameObject instanceRoot,string assetPath)
实例化物体保存为Prefab
④ 实例化物体获取子级 GetChild() 以及相关操作
⑤OnGUI()相关语句
⑥using System.IO;下的Path获取文件名称

代码:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System.IO;
  6. public class PrefabModifyAndMove : EditorWindow
  7. {
  8. static int currentMode = 0;
  9. enum Mode{
  10. CopyAndMove,
  11. ModifyAndMove
  12. }
  13. //声明数据并预填写
  14. static string inputParentPrefab = null;
  15. static string inputCloth = "Cloth";
  16. static string inputHair = "Hair";
  17. static string inputBody = "Body";
  18. static string inputFace = "Face";
  19. string outputMessage = "已成功复制并修改数据,点击确定自动关闭窗口";
  20. static string destPath = "Assets/Game/";
  21. private static string assetPath;//文件源路径
  22. [MenuItem("Assets/修改角色Prefab及其子对象名称并移动到指定文件夹", false, 1)]
  23. private static void ShowWindow()
  24. {
  25. FilePath();
  26. string assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
  27. string Filename = Path.GetFileNameWithoutExtension(assetPath);
  28. inputParentPrefab = Filename;
  29. if (assetPath.EndsWith(".prefab"))
  30. {
  31. //----------编辑器窗口区---------
  32. PrefabModifyAndMove window = GetWindow<PrefabModifyAndMove>("自定义窗口");
  33. //窗口大小,不可修改宽高
  34. Vector2 windowSize = new Vector2(300, 180);
  35. window.maxSize = windowSize;
  36. window.minSize = windowSize;
  37. //显示窗口
  38. window.Show();
  39. }
  40. else { Debug.Log("您未选择相应的Prefab资源"); }
  41. }
  42. //------------------------窗口编写-------------------------
  43. private void OnGUI() //纯GUI逻辑
  44. {
  45. GUILayout.BeginArea(new Rect(0, 0, 300, 300));//区域开始
  46. //GUIStyle
  47. GUIStyle centerStyle = new GUIStyle();
  48. centerStyle.fontSize = 16;//字体大小
  49. centerStyle.normal.textColor = Color.white;//颜色
  50. centerStyle.alignment = TextAnchor.MiddleCenter;//显示居中
  51. GUILayout.Label("无需修改数据请勿填数据", centerStyle);
  52. //局部字体样式
  53. int size = GUI.skin.label.fontSize;
  54. GUI.skin.label.fontSize = 18;
  55. GUI.skin.label.fontSize = size;
  56. //全局字体样式
  57. GUI.skin.label.fontSize = 14;
  58. //填写参数列表
  59. GUILayout.Space(2);
  60. EditorGUILayout.BeginHorizontal();//垂直布局开始
  61. GUILayout.Label("预制体名称:",GUILayout.Width(80));
  62. inputParentPrefab = GUILayout.TextField(inputParentPrefab,GUILayout.Width(200));
  63. EditorGUILayout.EndHorizontal();//垂直布局结束
  64. GUILayout.Space(2);
  65. EditorGUILayout.BeginHorizontal();
  66. GUILayout.Label("Cloth:", GUILayout.Width(80));
  67. inputCloth = GUILayout.TextField(inputCloth, GUILayout.Width(200));
  68. EditorGUILayout.EndHorizontal();
  69. GUILayout.Space(2);
  70. EditorGUILayout.BeginHorizontal();
  71. GUILayout.Label("Hair:", GUILayout.Width(80));
  72. inputHair = GUILayout.TextField(inputHair, GUILayout.Width(200));
  73. EditorGUILayout.EndHorizontal();
  74. GUILayout.Space(2);
  75. EditorGUILayout.BeginHorizontal();
  76. GUILayout.Label("Body:", GUILayout.Width(80));
  77. inputBody = GUILayout.TextField(inputBody, GUILayout.Width(200));
  78. EditorGUILayout.EndHorizontal();
  79. GUILayout.Space(2);
  80. EditorGUILayout.BeginHorizontal();
  81. GUILayout.Label("Face:", GUILayout.Width(80));
  82. inputFace = GUILayout.TextField(inputFace, GUILayout.Width(200));
  83. EditorGUILayout.EndHorizontal();
  84. GUILayout.Space(2);
  85. //指定新路径
  86. EditorGUILayout.BeginHorizontal();
  87. GUILayout.Label("指定路径:", GUILayout.Width(70));
  88. destPath = GUILayout.TextField(destPath, GUILayout.Width(210));
  89. EditorGUILayout.EndHorizontal();
  90. //输出确定信息
  91. EditorGUILayout.BeginHorizontal();
  92. if(GUILayout.Button("保持原名称", GUILayout.Width(145))) //纯复制 + 移动
  93. {
  94. if (EditorUtility.DisplayDialog("结果通知:", "未改变任何状态,点击确定关闭窗口", "确定"))
  95. {
  96. currentMode = 0;
  97. ChangeData();
  98. this.Close();
  99. }
  100. }
  101. if (GUILayout.Button(new GUIContent("确定"),GUILayout.Width(145))) //改名 + 移动
  102. {
  103. if (EditorUtility.DisplayDialog("结果通知:", outputMessage, "确定"))
  104. {
  105. currentMode = 1;
  106. ChangeData();
  107. this.Close();
  108. }
  109. }
  110. EditorGUILayout.EndHorizontal();
  111. GUILayout.EndArea();//区域结束
  112. }
  113. private static string FilePath()//文件路径获取
  114. {
  115. string[] guids = Selection.assetGUIDs;
  116. if (guids.Length < 0)
  117. return null;
  118. for (int i = 0; i < guids.Length; i++)
  119. {
  120. assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
  121. }
  122. Debug.Log(assetPath);
  123. return assetPath;
  124. }
  125. private static void ChangeData()
  126. {
  127. //--------------正式开始对数据进行修改-----------------
  128. GameObject o = PrefabUtility.InstantiatePrefab(Selection.activeObject as GameObject) as GameObject;
  129. if (currentMode.Equals((int)Mode.CopyAndMove))//纯复制逻辑
  130. {
  131. o.name = o.name;
  132. }
  133. else if(currentMode.Equals((int)Mode.ModifyAndMove))//修改 + 移动逻辑
  134. {
  135. //修改父集信息--------需要自定义或者指定路径
  136. if (inputParentPrefab != null && JudgeSpace(inputParentPrefab))
  137. {
  138. o.name = inputParentPrefab;
  139. }
  140. else { o.name = o.name; }
  141. //修改子集信息-------自定义或者指定路径
  142. for (int i = 0; i < o.transform.childCount; i++)
  143. {
  144. if (o.transform.GetChild(i).GetComponent<SkinnedMeshRenderer>() != null)
  145. {
  146. if (o.transform.GetChild(i).GetComponent<SkinnedMeshRenderer>().sharedMaterial.shader.name == "Character/Character")
  147. {
  148. if (inputCloth != null && JudgeSpace(inputCloth))
  149. {
  150. o.transform.GetChild(i).name = inputCloth;
  151. }
  152. else { o.transform.GetChild(i).name = "Cloth"; }
  153. }
  154. else if (o.transform.GetChild(i).GetComponent<SkinnedMeshRenderer>().sharedMaterial.shader.name == "Character/Character_Hair")
  155. {
  156. if (inputHair != null && JudgeSpace(inputHair))
  157. {
  158. o.transform.GetChild(i).name = inputHair;
  159. }
  160. else { o.transform.GetChild(i).name = "Hair"; }
  161. }
  162. else if (o.transform.GetChild(i).GetComponent<SkinnedMeshRenderer>().sharedMaterial.shader.name == "Character/Actor_Skin")
  163. {
  164. if (inputBody != null && JudgeSpace(inputBody))
  165. {
  166. o.transform.GetChild(i).name = inputBody;
  167. }
  168. else { o.transform.GetChild(i).name = "Body"; }
  169. }
  170. else if (o.transform.GetChild(i).GetComponent<SkinnedMeshRenderer>().sharedMaterial.shader.name == "Character/Character_Skin")
  171. {
  172. if (inputFace != null && JudgeSpace(inputFace))
  173. {
  174. o.transform.GetChild(i).name = inputFace;
  175. }
  176. else { o.transform.GetChild(i).name = "Face"; }
  177. }
  178. else { Debug.LogFormat("{0}没有SkinnedMeshRenderer组件", o.transform.GetChild(i)); }
  179. }
  180. }
  181. }
  182. //实例化物体保存为Prefab
  183. PrefabUtility.SaveAsPrefabAsset(o, (destPath + o.name + ".Prefab"));
  184. //实例化后场景留存物体->销毁
  185. //初始化静态变量
  186. inputParentPrefab = null;
  187. inputCloth = "Cloth";
  188. inputHair = "Hair";
  189. inputBody = "Body";
  190. inputFace = "Face";
  191. Object.DestroyImmediate(o);
  192. }
  193. private static bool JudgeSpace(string str)//判断空格
  194. {
  195. string strc = str;
  196. if (strc.Trim() == "")
  197. {
  198. return false;
  199. }
  200. else return true;
  201. }
  202. }