VoiceEditor.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. using System.Collections.Generic;
  2. using System.IO;
  3. using UnityEditor;
  4. using UnityEngine;
  5. using WS;
  6. ///<summary>语音预制件创建</summary>
  7. public class VoiceEditor : EditorWindow
  8. {
  9. [MenuItem("Tools/Framework/自动生成语音预制件")]
  10. public static void ShowVoice()
  11. {
  12. VoiceEditor window = EditorWindow.GetWindow<VoiceEditor>("生成语音预制件");
  13. window.Show();
  14. }
  15. ///<summary>加载路径</summary>
  16. private string loadpath = "Assets/GameResources/Audio/";
  17. ///<summary>保存路径</summary>
  18. private string savepath = "Assets/Resources/Audio/";
  19. ///<summary>识别不同的后缀名</summary>
  20. private string[] suffix = new string[] { "*.mp3", "*.wav", "*.ogg" };
  21. ///<summary>配置文件</summary>
  22. private List<ResourcePath> Config = new List<ResourcePath>();
  23. ///<summary>滑杆</summary>
  24. private Vector2 pos;
  25. ///<summary>路径</summary>
  26. private string path;
  27. private void OnEnable()
  28. {
  29. path = $"{Application.dataPath}/Resources/Config/Framework/VoiceConfig.txt";
  30. if (ConfigHelper.ConfigExists(path))
  31. {
  32. Config = ConfigHelper.FileLoadConfig<List<ResourcePath>>(path);
  33. }
  34. }
  35. private void OnGUI()
  36. {
  37. EditorGUILayout.BeginHorizontal();
  38. GUILayout.Label("");
  39. GUILayout.Label("只支持 mp3、wav、ogg 格式,如有其它格式请在 VoiceEditor 脚本的 suffix 参数增加", GUILayout.Width(500));
  40. GUILayout.Label("");
  41. EditorGUILayout.EndHorizontal();
  42. EditorGUILayout.BeginHorizontal();
  43. GUILayout.Label("读取路径:", GUILayout.Width(65));
  44. loadpath = EditorGUILayout.TextField(loadpath);
  45. EditorGUILayout.EndHorizontal();
  46. EditorGUILayout.BeginHorizontal();
  47. GUILayout.Label($"保存路径:", GUILayout.Width(65));
  48. EditorGUILayout.TextField(savepath);
  49. EditorGUILayout.EndHorizontal();
  50. EditorGUILayout.BeginHorizontal();
  51. GUILayout.Label("");
  52. if (GUILayout.Button("生成预制件", GUILayout.Width(100)))
  53. {
  54. //所有的语音文件
  55. List<string> allfilepath = new List<string>();
  56. for (int i = 0; i < suffix.Length; i++)
  57. {
  58. string[] temp = Directory.GetFiles(loadpath, suffix[i], SearchOption.AllDirectories);
  59. allfilepath.AddRange(temp);
  60. }
  61. //已经处理为预制件的语音
  62. List<string> allprefabpath = new List<string>();
  63. string[] temp_1 = Directory.GetFiles(savepath, "*.prefab", SearchOption.AllDirectories);
  64. allprefabpath.AddRange(temp_1);
  65. ToSetString(allfilepath);
  66. ToSetString(allprefabpath);
  67. //文件名称
  68. List<string> filenames = new List<string>();
  69. for (int i = 0; i < allfilepath.Count; i++)
  70. {
  71. FileInfo fi = new FileInfo(allfilepath[i]);
  72. filenames.Add(fi.Name.Replace(fi.Extension, ""));
  73. }
  74. //删除 语音已经被删除 的语音预制件
  75. for (int i = allprefabpath.Count - 1; i >= 0; i--)
  76. {
  77. FileInfo fi = new FileInfo(allprefabpath[i]);
  78. string prefabname = fi.Name.Replace(fi.Extension, "");
  79. if (!IsExists(filenames, prefabname))
  80. {
  81. AssetDatabase.DeleteAsset(allprefabpath[i]);
  82. allprefabpath.Remove(allprefabpath[i]);
  83. AssetDatabase.SaveAssets();
  84. AssetDatabase.Refresh();
  85. int index = Config.FindIndex(v => v.Name == prefabname);
  86. Config.RemoveAt(index);
  87. }
  88. else
  89. allprefabpath[i] = fi.Name.Replace(fi.Extension, "");
  90. }
  91. //删除都没有的
  92. for (int i = Config.Count - 1; i >= 0; i--)
  93. {
  94. if (!IsExists(filenames, Config[i].Name))
  95. {
  96. Config.Remove(Config[i]);
  97. }
  98. }
  99. //创建预制件
  100. for (int i = 0; i < allfilepath.Count; i++)
  101. {
  102. FileInfo fi = new FileInfo(allfilepath[i]);
  103. var filename = fi.Name.Replace(fi.Extension, "");
  104. if (Config.Exists(v => v.Name == filename))//已存在
  105. continue;
  106. AudioClip clip = AssetDatabase.LoadAssetAtPath<AudioClip>(allfilepath[i]);
  107. if (null != clip)
  108. {
  109. if (IsExists(allprefabpath, filename))//已经创建预制件,跳过该步骤
  110. continue;
  111. GameObject go = new GameObject();
  112. go.name = filename;
  113. AudioSource source = go.AddComponent<AudioSource>();
  114. source.playOnAwake = false;
  115. source.clip = clip;
  116. string filepath = allfilepath[i].Replace(loadpath, "").Replace(fi.Name, "");
  117. if (string.IsNullOrEmpty(filepath))
  118. filepath = savepath;
  119. else
  120. filepath = $"{savepath}/{filepath}";
  121. if (!Directory.Exists(filepath))
  122. Directory.CreateDirectory(filepath);
  123. filepath = $"{filepath}/{filename}.prefab";
  124. GameObject savego = PrefabUtility.SaveAsPrefabAsset(go, filepath);
  125. GameObject.DestroyImmediate(go);
  126. EditorUtility.SetDirty(savego);
  127. Resources.UnloadAsset(clip);
  128. AssetDatabase.SaveAssets();
  129. AssetDatabase.Refresh();
  130. ResourcePath data = new ResourcePath();
  131. data.Name = filename;
  132. data.Path = filepath.Replace("Assets/Resources/", "").Replace(".prefab", "").Replace("//", "/");
  133. Config.Add(data);
  134. }
  135. }
  136. ConfigHelper.SaveConfig(Config, path);
  137. DeleteEmptyFolders(savepath);
  138. AssetDatabase.SaveAssets();
  139. AssetDatabase.Refresh();
  140. }
  141. GUILayout.Label("");
  142. EditorGUILayout.EndHorizontal();
  143. GUILayout.Label("");
  144. pos = EditorGUILayout.BeginScrollView(pos);
  145. for (int i = 0; i < Config.Count; i++)
  146. {
  147. EditorGUILayout.BeginHorizontal();
  148. GUILayout.Label("Voice 名称", GUILayout.Width(70));
  149. GUILayout.Label(Config[i].Name, GUILayout.Width(200));
  150. GUILayout.Label("Voice 路径", GUILayout.Width(70));
  151. GUILayout.Label(Config[i].Path);
  152. EditorGUILayout.EndHorizontal();
  153. }
  154. EditorGUILayout.EndScrollView();
  155. }
  156. ///<summary>集合中是否存在</summary>
  157. private bool IsExists(List<string> list, string str)
  158. {
  159. return list.Exists(s => s == str);
  160. }
  161. ///<summary>删除空文件夹</summary>
  162. private void DeleteEmptyFolders(string path)
  163. {
  164. var dir = new DirectoryInfo(path);
  165. var subdirs = dir.GetDirectories("*.*", SearchOption.AllDirectories);
  166. foreach (var subdir in subdirs)
  167. {
  168. if (!Directory.Exists(subdir.FullName)) continue;
  169. var subFiles = subdir.GetFileSystemInfos("*.*", SearchOption.AllDirectories);
  170. var findFile = false;
  171. foreach (var sub in subFiles)
  172. {
  173. findFile = (sub.Attributes & FileAttributes.Directory) == 0;
  174. if (findFile) break;
  175. }
  176. if (!findFile) subdir.Delete(true);
  177. }
  178. }
  179. ///<summary>转意符</summary>
  180. private void ToSetString(List<string> list)
  181. {
  182. for (int i = 0; i < list.Count; i++)
  183. {
  184. list[i] = list[i].Replace(@"\", "/");
  185. }
  186. }
  187. }