技术笔记(10)Unity编辑器扩展
技术笔记(10)Unity编辑器扩展
-
希望实现的功能或目标:
- 编写一个编辑器扩展功能,用以快速创建Event和Command脚本
-
学习笔记:
-
CreateScriptWindow类
-
继承EditorWindow类
-
用两个常量字符串,记录模板所在的文件路径
-
const string EVENTTEMPLATE_PATH = "Assets/Scripts/GameFramework/ReusableCode/Layers/Utility/Editor/EventTemplateScript.txt"; const string COMMANDTEMPLATE_PATH = "Assets/Scripts/GameFramework/ReusableCode/Layers/Utility/Editor/CommandTemplateScript.txt";
-
-
调用MenuItem选择新增按钮的索引位置
-
[MenuItem("Assets/Create/C# Event Script(Command)")]
-
-
AssetsCreate方法:调用GetWindow方法,得到一个当前类名的window,并调用这个window的Show方法
-
static void AssetsCreate() { CreateScriptWindow window = (CreateScriptWindow)GetWindow(typeof(CreateScriptWindow), false, "创建C#"); window.Show(true); }
-
-
两个普通字符串
-
string _scriptName; string _description;
-
-
OnGUI方法
-
通过GetPath方法获取当前所选的目录
-
在Directory中查询该目录是否存在
-
如果存在,则创建一个TextField用来输入脚本名。
-
然后创建一个“创建事件”按钮
-
如果创建成功了,设置要生成的脚本的路径,并展示出来
- 检测输入的脚本名是否正确,是否已有同名脚本并报错
- 如果都没问题,把模板里的内容读出来,把所有的“My”替换成输入的脚本名,并以UTF8的编码格式写到新生成的脚本里
- 刷新project列表,显示创建成功的提示信息
-
-
创建命令脚本的逻辑同上
-
-
private void OnGUI() { string selectDirPath = GetPath(); if (Directory.Exists(selectDirPath)) { _scriptName = EditorGUILayout.TextField("脚本名:", _scriptName); if(GUILayout.Button("创建事件", GUILayout.Height(40))) { string path = selectDirPath + "/" + _scriptName + "Event.cs"; EditorGUILayout.LabelField("路径:", path); EditorGUILayout.Space(); if (!CheckScriptName(_scriptName)) { ShowNotification(new GUIContent("请输入正确的脚本名!")); } else if(CheckRepeat(selectDirPath)) { ShowNotification(new GUIContent("当前文件夹下已经有同名脚本!")); } else { string content = File.ReadAllText(EVENTTEMPLATE_PATH); content = content.Replace("My", _scriptName); File.WriteAllText(path, content, Encoding.UTF8); AssetDatabase.Refresh(); ShowNotification(new GUIContent("Success!")); } } if (GUILayout.Button("创建命令", GUILayout.Height(40))) { string path = selectDirPath + "/" + _scriptName + "Command.cs"; EditorGUILayout.LabelField("路径:", path); EditorGUILayout.Space(); if (!CheckScriptName(_scriptName)) { ShowNotification(new GUIContent("请输入正确的脚本名!")); } else if (CheckRepeat(selectDirPath)) { ShowNotification(new GUIContent("当前文件夹下已经有同名脚本!")); } else { string content = File.ReadAllText(COMMANDTEMPLATE_PATH); content = content.Replace("My", _scriptName); File.WriteAllText(path, content, Encoding.UTF8); AssetDatabase.Refresh(); ShowNotification(new GUIContent("Success!")); } } } else { EditorGUILayout.LabelField("请在Project面板中选择将要放置脚本的文件夹"); } }
-
-
CheckScriptName方法
- 用正则表达式记录命名标准格式
- 对输入的参数进行检测,并返回是否符合格式
-
bool CheckScriptName(string scriptName) { Regex regex = new Regex("^[a-zA-Z_][a-zA-Z0-9_]*$"); return regex.IsMatch(scriptName); }
-
CheckRepeat方法
- 以所选路径为参数,new一个DirectoryInfo对象
- 并用FileInfo数组存这个DirectoryInfo对象里获取到的所有文件
- 脚本名字符串附上其格式“.cs”
- 遍历FileInfo数组,与文件名一一进行对比,有重名则返回true,无则返回false
-
bool CheckRepeat(string selectDirPath) { DirectoryInfo dir = new DirectoryInfo(selectDirPath); FileInfo[] files = dir.GetFiles(); string scriptName = _scriptName + ".cs"; for(int i = 0;i<files.Length;i++) { if (files[i].Name == scriptName) { return true; } } return false; }
-
OnSelectionChange方法
- 调用Repaint方法
-
GetPath方法
- 调用AssetDatabase类的GetAssetPath方法,以Selection.activeInstanceID作为其参数。从而获得选中资产的相对路径
-
private string GetPath() { string assetPath = null; if(assetPath == null || assetPath == "") { assetPath = AssetDatabase.GetAssetPath(Selection.activeInstanceID); } return assetPath; }
-
-
-
实现过程中产生的疑惑:
- 编辑器扩展的作用?
- 有哪些实际的应用?
-
对疑惑的解答:
-
其允许我们通过自定义脚本和插件来增强和个性化unity编辑器的功能,主要作用有:
- 提高开发效率:自动化处理重复性任务
- 自定义工具和界面:以适应特定的开发需求,提高工作流程和效率和舒适度
- 增强可视化编辑:绘制辅助图形、直观编辑对象属性
- 集成第三方工具:3d建模、音视频编辑软件
-
实际应用:
- 可用来运行游戏特定部分,进行快速测试而无需启动整个游戏
- 查找和替换材质、优化纹理等
- 集成Photoshop、Blender等外部工具的功能
-
日期:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战