using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; using UnityEngine; // ReSharper disable Unity.PerformanceCriticalCodeInvocation namespace Stary.Evo.StoryEditor.Editor { public class GraphCreateWindow : EditorWindow { private int _selectedIndex; private string _scriptName = "graph"; private bool _showTip; private string _tip; private string[] _options = Array.Empty(); private Dictionary _paths = new(); [MenuItem("Evo/剧本编辑器/创建剧本")] private static void Open() { // 打开一个浮动窗口 GetWindow( "创建配置" ) ; } private void OnEnable() { minSize = maxSize = new Vector2(300, 200); _options = GetPackages(); } private void OnGUI() { GUILayout.Space(15); EditorGUILayout.BeginHorizontal(); GUILayout.Space(10); EditorGUILayout.BeginVertical(); // Package选项 EditorGUILayout.LabelField( "请选择剧本所在的Package:" , EditorStyles.boldLabel ) ; var newIndex = EditorGUILayout.Popup( _selectedIndex , _options ) ; _selectedIndex = newIndex; GUILayout.Space(15); EditorGUILayout.LabelField( "请输入剧本名称" , EditorStyles.boldLabel ) ; var newName = EditorGUILayout.TextField(_scriptName); if (_scriptName != newName) { _scriptName = newName; _showTip = false; } if (_showTip) { GUIStyle redBold = new GUIStyle(EditorStyles.boldLabel) { normal = { textColor = Color.red } }; EditorGUILayout.LabelField(_tip, redBold) ; } GUILayout.Space(15); // 创建按钮 if (GUILayout.Button("创建剧本")) { try { CreateScriptGraph(_options[newIndex]); } catch (Exception e) { Debug.LogException(e); } } EditorGUILayout.EndVertical(); GUILayout.Space(10); EditorGUILayout.EndHorizontal(); } /// /// 获取所有Module Package /// private string[] GetPackages() { // 查找Modules目录 List modules = new(); GetDirectoryPaths(Application.dataPath, modules, "Modules"); if (modules.Count == 0) { Debug.LogError("未找到任何Modules目录"); return Array.Empty(); } // 查找package List packages = new(); GetDirectoryPaths(modules[0], packages, "com."); if (packages.Count == 0) { Debug.LogError("未找到任何Package"); return Array.Empty(); } // 记录Package地址并返回选项 _paths.Clear(); packages.ForEach(path => _paths.Add(Path.GetFileName(path), path)); return _paths.Keys.ToArray(); } /// /// 获取符合条件的目录 /// /// 查找起始目录 /// 查找结果 /// 筛选条件(title) /// 筛选条件(tail) private static void GetDirectoryPaths(string root, List result, string title = null, string tail = null) { foreach (var dir in Directory.GetDirectories(root)) { // ReSharper disable once ReplaceWithSingleAssignment.True var check = true; // 匹配文件头 if (!string.IsNullOrEmpty(title) && !Path.GetFileName(dir).StartsWith(title)) { check = false; } // 匹配文件尾 if (!string.IsNullOrEmpty(tail) && !Path.GetFileName(dir).EndsWith(tail)) { check = false; } if(check) result.Add(dir.Replace('\\', '/')); // 继续往下找 GetDirectoryPaths(dir, result, title); } } /// /// 创建剧本 /// /// 包体ID private void CreateScriptGraph(string packageID) { // 检查剧本名称是否有效 if (string.IsNullOrEmpty(_scriptName)) { _tip = "剧本名称不能为空"; _showTip = true; return; } if (_paths.TryGetValue(packageID, out var path)) { // 包体目录排空 var graphDir = Path.Combine(path, "Main","Res","Graphs"); if (!Directory.Exists(graphDir)) Directory.CreateDirectory(graphDir); // 检查资源存在性 var graphPath = Path.Combine(graphDir, $"{_scriptName}.asset").Replace(Application.dataPath, "").Replace('\\', '/'); graphPath = graphPath[1..]; var graphFilePath = Path.Combine("Assets", graphPath); var existAsset = AssetDatabase.LoadAssetAtPath(graphFilePath); if (existAsset) { _tip = "该名称的剧本已存在"; _showTip = true; return; } // 创建剧本图表 var graph = CreateInstance(); graph.packageID = packageID; graph.graphPath = graphPath; AssetDatabase.CreateAsset(graph, graphFilePath); } else { Debug.LogError($"未记录Package路径:{packageID}"); } } } }