Unity编辑器扩展精粹_第二章
先创建一个空文件夹
编辑器类,子文件夹
创建代码相关的类
用到的命名空间和归属
跟编辑器文件夹同级,创建一个Bind绑定脚本
添加到组件菜单,其中会Get获取,组件名称,这里测试的,只是加了MeshRenderer和SpriteRenderer,否则,都判定为Transform即可;
也可以右键添加,对应逻辑,调用Selection.objects.First接口,选中文件队列的第一个,添加Bind组件即可
入口
编辑器文件夹,创建一个绑定脚本的信息类
会声明,实体之间的,父子相对路径,组件名,实体名称
创建一个生成代码的模板类
生成的代码有两种: 1、根据实际脚本架构去动态生成 2、固定的样式
所以,需要两个代码模板类
用到的模板类,对应两种类型的代码
命名空间也应该可以自定义,新建一个数据类,用来自定义命名空间
用到的命名空间和业务逻辑: 保存的key是readonly只读的 整一个获取器和设置器,其中获取器设置好,字符串的默认值 三元运算符,判空,如果为空,就将它设置成默认值
再整一个布尔判断接口,判断是否为默认值
先完成固定样式的写入逻辑 脚本名字和所在文件夹,是传递进来的,如果脚本已存在,就return返回就好,如果命名空间是默认值,就写入中文提示
然后就是写入代码行数了,先是命名空间,然后是partial类 参考partial分部类和方法 其中\t是Tab退格的意思
然后,是动态生成的写入方法 动态生成的逻辑,代码名字需要在固定样式的名字基础上,加.后缀,在这里是.Designer; 传参里,有Bind绑定的bindInfos列表容器,遍历,写入新的脚本文件
其中,也使用了Guid.NewGuid函数,整出来一个,新的guid
测试生成的脚本里面,有这个注释
回到创建脚本的类,在GameObject目录下创建一个选项 先是打印log
整一个方法,是寻找绑定了Bind脚本的,递归 如果存在bind脚本,并且不是根节点,就构造一个BindInfo,往List里加,List是引用类型 继续,遍历子节点,然后递归调用 传参有一个三元运算符,判断是否为根节点,进而判断,是否要修改父子path路径传参
整一个静态Bind脚本信息相关的List列表
写一个类,是用来控制,生成代码和预制体位置,还有一个布尔,判断是否要生成预制体; 其中ExecuteInEditMode标签,指的是,只在编辑器模式下,运行; 参考ExecuteInEditMode
也加一个脚本,是对应CodeGenerateInfo的面板UI类,主要是用来设置相关路径;
这是右键入口逻辑
创建空物体,右键点击,选择入口
表现正常
完善创建代码类逻辑; 这个创建逻辑,是需要选中某个实体,先判断选中实体列表的长度,需要大于0,然后拿选中实体列表的第一个; 创建代码目录结构,如果不存在,就代码创建这个目录; Bind信息列表先clear清理一下,然后调用前面写好的,搜索绑定的bind脚本,调用前面写好的,两个代码模版,ComponentTemplate和ComponentDesignerTemplate; 然后把实体名字,写入到编辑器的本地化持久GENERATE_CLASS_NAME; AssetDatabase.Refresh刷新数据
加一个方法体,是用来检测编译结果的; DidReloadScripts标签,是在脚本发生改动后,会调用的函数 特别是在AssetDatabase.Refresh();之后
先拿到前面本地化持久GENERATE_CLASS_NAME的字符串数据
右键,点击选择:
打印正常,可以看到,编译完成的时机,也正常打印了
创建出来的脚本:
继续完善,编译后逻辑 如果字段字符长度为空,就不继续操作,并且删除这个本地化持久,不保留数据影响后面的
否则,继续操作; 获取已加载到这个应用程序域执行上下文的程序集; 拿到程序集中,第一个名字是"Assembly-CSharp"的程序集 从这个程序集中,拿到对应命名空间下的类 如果类为空,提示编译失败 如果不为空,就先拿到这个实体,然后往这个实体挂载同名脚本,然后通过SerializedObject序列化脚本; 清空bind信息列表,
然后重新搜索和赋值列表; 遍历信息列表,对序列化文件中,使用FindProperty方法,拿到同名的变量,进行赋值操作; 然后拿到CodeGenerateInfo组件,也是使用FindProperty方法,获取生成的脚本和预制体路径
调用serialiedScript.ApplyModifiedPropertiesWithoutUndo(); SerializedObject.ApplyModifiedPropertiesWithoutUndo 如果勾选了,生成预制体,就调用SaveAsPrefabAssetAndConnect接口,生成即可; 保存修改,然后删除本地化持久,不保留数据影响后面的
再设置好,这个创建代码类,继承自编辑器 然后,添加编辑器入口; 刷新界面,是获取和修改自定义命名空间
保存修改,点击入口
这个是默认命名空间
改一下
创建一个空的子物体
加Bind节点
回到父物体,点击创建
预制体和脚本,生成正常; 组件挂载,正常;
逻辑内容正常