using TFramework; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.Text; using System.IO; using System; using System.Reflection; using System.Linq; namespace TFramework { public class CreateScriptEdit : EditorWindow { private string _scriptName; string ScriptName { get => _scriptName; set { if (_scriptName == value) return; _scriptName = value; WritScript(); } } private bool _isUserNamespace; bool IsUserNamespace { get => _isUserNamespace; set { if (_isUserNamespace == value) return; _isUserNamespace = value; WritScript(); } } private string _namespce; string Namespce { get => _namespce; set { if (_namespce == value) return; _namespce = value; WritScript(); } } private bool _isInheritMonon; bool IsInheritMono { get => _isInheritMonon; set { if (_isInheritMonon == value) return; _isInheritMonon = value; WritScript(); } } private string _scriptDes; string ScriptDes { get => _scriptDes; set { if (_scriptDes == value) return; _scriptDes = value; WritScript(); } } [SerializeField] private StringBuilder _script = new StringBuilder(); [SerializeField] private DesTempData _tempData; [SerializeField] private UserData _userData; [SerializeField] private Dictionary desFiledDic = new Dictionary(); [SerializeField] private List _keys = new List(); const string TEMPDATAPATH = "Assets/TFramework/Editor/CreateScript/DesTemp/DesTempData.asset"; const string USERDATAPATH = "Assets/TFramework/Editor/UserInfo/UserData.asset"; private Dictionary classTypeDic = new Dictionary { {"类","class" }, {"结构体","struct" }, {"枚举","enum" }, {"接口","interface" } }; private string classType = string.Empty; string ClassType { get => classType; set { if (classType == value) return; classType = value; IsInheritMono = (IsInheritMono && classType == "类"); InheritClass = "None"; GetAllType(); WritScript(); } } DesTempData TempData { get { _tempData = _tempData ?? AssetDatabase.LoadAssetAtPath(TEMPDATAPATH); if (_tempData == null) CreateTempData(); return _tempData; } } UserData User { get { _userData = _userData ?? AssetDatabase.LoadAssetAtPath(USERDATAPATH); if (_userData == null) CreateUserData(); return _userData; } } private void CreateUserData() { _userData = CreateInstance(); AssetDatabase.CreateAsset(_userData, USERDATAPATH); AssetDatabase.Refresh(); _userData = AssetDatabase.LoadAssetAtPath(USERDATAPATH); } List selecteMenu = new List(); int _selecteTemp = 0; int SelecteTemp { get => _selecteTemp; set { if (_selecteTemp == value) return; _selecteTemp = value; FiedGather(); WritScript(); } } GenericMenu classTypeMenu; GenericMenu inheritClassMenu; GenericMenu citeMenu; List _allType = new List(); private string _inheritClass; string InheritClass { get => _inheritClass; set { if (_inheritClass == value) return; _inheritClass = value; WritScript(); } } private static readonly HashSet IntegerTypes = new HashSet { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong) }; private static HashSet Cites = new HashSet(); public static void OpenWin() { CreateScriptEdit win = GetWindow(); win.minSize = new Vector2(450, 200); win.titleContent.text = "创建脚本"; win.titleContent.image = EditorGUIUtility.IconContent("cs Script Icon").image; } private void OnEnable() { RefreshTemp(); Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies(); foreach (var ab in assemblys) foreach (var type in ab.GetTypes()) if (type.IsPublic) _allType.Add(type); GetAllCite(); IsInheritMono = true; IsUserNamespace = true; ClassType = "类"; InheritClass = "None"; GetClassType(); } void GetClassType() { classTypeMenu = new GenericMenu(); foreach (var item in classTypeDic) { classTypeMenu.AddItem(new GUIContent(item.Key), ClassType.Equals(item.Key), () => { ClassType = item.Key; }); } } void GetAllType() { inheritClassMenu = new GenericMenu(); inheritClassMenu.AddItem(new GUIContent("None"), InheritClass.Equals("None"), () => InheritClass = "None"); foreach (var type in _allType) { if(ClassType=="类"&&(type.IsInterface || type.IsClass)) inheritClassMenu.AddItem(new GUIContent(type.FullName.Replace('.', '/')), InheritClass.Equals(type.FullName), () => InheritClass = type.FullName); else if((ClassType == "接口"|| ClassType == "结构体")&& type.IsInterface) inheritClassMenu.AddItem(new GUIContent(type.FullName.Replace('.', '/')), InheritClass.Equals(type.FullName), () => InheritClass = type.FullName); else if(ClassType == "枚举"&& IntegerTypes.Contains(type)) inheritClassMenu.AddItem(new GUIContent(type.FullName.Replace('.', '/')), InheritClass.Equals(type.FullName), () => InheritClass = type.FullName); } } void GetAllCite() { citeMenu = new GenericMenu(); foreach (var type in _allType.GroupBy(p => p.Namespace)) { if (string.IsNullOrEmpty(type.Key)) continue; bool isG = Cites.Contains(type.Key); citeMenu.AddItem(new GUIContent(type.Key.Replace('.', '/')+'#'), isG , () => { if (Cites.Contains(type.Key)) Cites.Remove(type.Key); else Cites.Add(type.Key); WritScript(); }); } } void RefreshTemp() { selecteMenu.Clear(); selecteMenu.Add("None"); TempData.desTempInfos.ForEach(p => { selecteMenu.Add(p.m_name); }); } private void CreateTempData() { _tempData = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(_tempData, TEMPDATAPATH); AssetDatabase.Refresh(); _tempData = AssetDatabase.LoadAssetAtPath(TEMPDATAPATH); } void FiedGather() { ScriptDes = string.Empty; desFiledDic.Clear(); _keys.Clear(); if (SelecteTemp <= 0) return; string str = TempData.desTempInfos.Find(p => p.m_name == selecteMenu[SelecteTemp]).m_des; ScriptDes = str.Replace("+", ""); str = str.Remove(0,str.IndexOf("+")); str = str.Remove(str.LastIndexOf(":")); //Debug.Log(str); string[] strs = str.Split("\n"); string key = string.Empty; for (int i = 0; i < strs.Length; i++) { key = string.Empty; for (int j = 0; j < strs[i].Length; j++) { if (strs[i][j] != '+'&& strs[i][j] != ':' && strs[i][j] != ':'&&strs[i][j]!=' ') key += strs[i][j]; if (strs[i][j] == ':'|| strs[i][j] == ':') break; } if(!string.IsNullOrEmpty(key)) { desFiledDic.Add(key, ""); _keys.Add(key); } } } private void OnGUI() { using(new EditorGUILayout.HorizontalScope()) { DrawLeft(); DrawRight(); } } void DrawLeft() { using (new EditorGUILayout.VerticalScope(GUILayout.Width(200))) { using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("脚本名"); ScriptName = EditorGUILayout.TextField(ScriptName); } using(new EditorGUILayout.HorizontalScope()) { GUILayout.Label("脚本类型"); if(GUILayout.Button(classType,EditorStyles.popup)) { GetClassType(); classTypeMenu.ShowAsContext(); } } GUI.enabled = classType == "类"; using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("继承Mono"); IsInheritMono = EditorGUILayout.Toggle(IsInheritMono); } GUI.enabled = true; using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("脚本引用"); if (GUILayout.Button("管理引用", EditorStyles.popup)) { GetAllCite(); citeMenu.ShowAsContext(); } } if (!IsInheritMono) { using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("继承父类"); if (GUILayout.Button(_inheritClass, EditorStyles.popup)) { GetAllType(); inheritClassMenu.ShowAsContext(); } } } using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("使用命名空间"); IsUserNamespace = EditorGUILayout.Toggle(IsUserNamespace); } if (IsUserNamespace) { using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("命名空间"); Namespce = EditorGUILayout.TextField(Namespce); } } using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("脚本描述"); SelecteTemp = EditorGUILayout.Popup(SelecteTemp,selecteMenu.ToArray()); if(GUILayout.Button("新建")) { NewDesTemp.Open(TempData, RefreshTemp); } } if(_keys.Count>0) { for (int i = 0; i < _keys.Count; i++) { string value = string.Empty; int j = i; using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label(_keys[i],GUILayout.ExpandWidth(false)); value = EditorGUILayout.TextField(desFiledDic[_keys[i]]); switch (_keys[i]) { case "文件": value = ScriptName+".cs"; break; case "日期": value = DateTime.Now.ToString("U"); break; case "UnityVersion": case "Unity版本": value = Application.unityVersion; break; case "作者": value = User.m_name; break; case "邮箱": value = User.m_email; break; default: break; } if(value != desFiledDic[_keys[j]]) { ScriptDes = ScriptDes.Replace($"?{j}{desFiledDic[_keys[j]]}", $"?{j}{value}"); desFiledDic[_keys[j]] = value; } } } } GUI.color = Color.green; if (GUILayout.Button("创建")) { CreateScript(); } GUI.color = Color.white; } } void DrawRight() { using (new EditorGUILayout.VerticalScope("Box")) { EditorGUILayout.LabelField("预览:"); GUI.enabled = false; EditorGUILayout.TextArea(_script.ToString()); GUI.enabled = true; } } private void WritScript() { _script.Clear(); if (SelecteTemp > 0) { string des = ScriptDes; for (int i = 0; i < _keys.Count; i++) { des = des.Replace($"?{i}", ""); } _script.Append(des); _script.Append("\n"); } //if (_isInheritMonon) //{ // _script.Append("using System.Collections;\n"); // _script.Append("using UnityEngine;\n"); //} //_script.Append("using System.Collections.Generic;\n"); foreach (var item in Cites) { _script.Append($"using {item};\n"); } if (_isUserNamespace) { _script.Append($"namespace {_namespce}\n"); _script.Append("{\n"); } _script.Append($"{(_isUserNamespace ? " " : "")}public {(classTypeDic.ContainsKey(classType)? classTypeDic[classType]:"class")} {_scriptName} {(_isInheritMonon ? ": MonoBehaviour" : (InheritClass=="None"?"":$": {InheritClass}")) }\n"); _script.Append(_isUserNamespace ? " " : ""); _script.Append("{\n"); _script.Append(_isUserNamespace ? " " : ""); _script.Append("}\n"); if (_isUserNamespace) { _script.Append("}"); } } private void CreateScript() { if (_script.Length < 0) return; string fullName = "Assets"; UnityEngine.Object[] objects = Selection.GetFiltered(SelectionMode.Assets); if (objects.Length > 0) fullName = AssetDatabase.GetAssetPath(objects[0]); fullName += $"/{_scriptName}.cs"; string pathName = Application.dataPath.Remove(Application.dataPath.LastIndexOf("/")+1) + fullName; StreamWriter writer = new StreamWriter(pathName, false, UTF8Encoding.UTF8); writer.Write(_script.ToString()); writer.Close(); AssetDatabase.ImportAsset(fullName); MonoScript script = AssetDatabase.LoadAssetAtPath(fullName); AssetDatabase.OpenAsset(script); AssetDatabase.Refresh(); Close(); } } public class NewDesTemp:EditorWindow { static DesTempData _tempData; static TAction onSave; DesTempInfo tempInfo = new DesTempInfo(); bool isCanSave = true; public static void Open(DesTempData tempData,TAction action) { NewDesTemp win = GetWindow(); win.minSize = new Vector2(300, 300); _tempData = tempData; win.titleContent.text = "脚本描述模版"; onSave = action; win.Show(); } private void OnGUI() { using(new EditorGUILayout.HorizontalScope()) { GUILayout.Label("名称", GUILayout.ExpandWidth(false)); isCanSave = true; tempInfo.m_name = EditorGUILayout.TextField(tempInfo.m_name); if(_tempData.desTempInfos.Find(p=>p.m_name==tempInfo.m_name)!=null) { EditorGUILayout.HelpBox("存在同名模版!请更换名称", MessageType.Error); isCanSave = false; } } using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("描述",GUILayout.ExpandWidth(false)); tempInfo.m_des = EditorGUILayout.TextArea(tempInfo.m_des); } if(GUILayout.Button("保存")) { if(!string.IsNullOrEmpty(tempInfo.m_name)&&!string.IsNullOrEmpty(tempInfo.m_des)&&isCanSave) { _tempData.desTempInfos.Add(tempInfo); onSave?.Invoke(); EditorUtility.SetDirty(_tempData); AssetDatabase.SaveAssets(); Close(); } } } } }