Files
Cielonos/Assets/Scripts/MainGame/Base/StaticAttributeClassGenerationWindow.cs
SoulliesOfficial f26f9fd374 爆更
2026-03-20 12:07:44 -04:00

110 lines
4.0 KiB
C#

using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using Sirenix.OdinInspector;
using UnityEditor;
using UnityEngine;
#if UNITY_EDITOR
using Sirenix.OdinInspector.Editor;
namespace SLSUtilities.General
{
public class DictionaryCodeGeneratorWindow : OdinEditorWindow
{
// 临时持有目标字典的引用
private SerializedDictionary<string, string> _targetDict;
[Title("代码生成设置")]
[LabelText("类名")]
public string ClassName = "AttributeKeys";
[LabelText("命名空间")]
public string NamespaceName = "Cielonos.Generated";
[FolderPath, LabelText("保存路径")]
public string SavePath = "Assets/Scripts/Generated";
// 静态打开方法
public static void Open(SerializedDictionary<string, string> targetDict,
string className, string nameSpaceName, string savePath = "Assets/Scripts/Generated")
{
var window = GetWindow<DictionaryCodeGeneratorWindow>();
window.titleContent = new GUIContent("常量生成器");
window._targetDict = targetDict;
window.ClassName = className; // 设置默认类名
window.NamespaceName = nameSpaceName; // 设置默认命名空间
window.SavePath = savePath; // 设置默认保存路径
window.Show();
}
[Button("生成代码 (Generate)", ButtonSizes.Large), PropertyOrder(10)]
[GUIColor(0.4f, 0.8f, 0.4f)]
public void Generate()
{
if (_targetDict == null)
{
Debug.LogError("字典引用丢失,请重新打开窗口。");
return;
}
StringBuilder sb = new StringBuilder();
// 1. 生成头部
sb.AppendLine("// ========================================================");
sb.AppendLine($"// Auto-generated from SerializedDictionary: {ClassName}");
sb.AppendLine("// ========================================================");
sb.AppendLine("");
if (!string.IsNullOrEmpty(NamespaceName))
{
sb.AppendLine($"namespace {NamespaceName}");
sb.AppendLine("{");
}
string indent = string.IsNullOrEmpty(NamespaceName) ? "" : " ";
sb.AppendLine($"{indent}public static class {ClassName}");
sb.AppendLine($"{indent}{{");
// 2. 遍历字典内容
// SerializedDictionary 实现了 IEnumerable<KeyValuePair<string, string>>
foreach (var kvp in _targetDict)
{
string key = kvp.Key;
string desc = kvp.Value;
// 简单的变量名过滤 (只保留字母数字下划线)
string varName = Regex.Replace(key, "[^a-zA-Z0-9_]", "");
// 修正:变量名不能以数字开头
if (varName.Length > 0 && char.IsDigit(varName[0]))
varName = "_" + varName;
if (string.IsNullOrEmpty(varName)) continue;
// 添加注释
if (!string.IsNullOrEmpty(desc))
{
sb.AppendLine($"{indent} /// <summary> {desc.Replace("\n", " ")} </summary>");
}
// 添加常量定义
sb.AppendLine($"{indent} public const string {varName} = \"{key}\";");
}
sb.AppendLine($"{indent}}}");
if (!string.IsNullOrEmpty(NamespaceName)) sb.AppendLine("}");
// 3. 写入文件
if (!Directory.Exists(SavePath)) Directory.CreateDirectory(SavePath);
string fullPath = Path.Combine(SavePath, $"{ClassName}.cs");
File.WriteAllText(fullPath, sb.ToString(), Encoding.UTF8);
AssetDatabase.Refresh();
ShowNotification(new GUIContent("生成成功!"));
Debug.Log($"[CodeGenerator] 文件已生成: {fullPath}");
}
}
}
#endif