继续看控件逻辑; 继承自UIBehaviour逻辑,它本身也是继承自MonoBehaviour,还有按钮点击的IPointerClickHandler; 然后,就是序列化,各个按钮点击相关 ![[Pasted image 20240315112250.png]] ![[Pasted image 20240315112334.png]] 这个控件,主要是用于,animationTime控制动画播放时间,和多久可以触发一次按钮invokeIntervalTime ![[Pasted image 20240315112428.png]] 触发和调用本身,是用的协程 ![[Pasted image 20240315112653.png]] 样式 ![[Pasted image 20240315112703.png]] 重置按钮,相关逻辑,就是置空,动画控制器,播放时间和触发时间归零,通过UnityEventTools,移除动画事件 ![[Pasted image 20240315112726.png]] ![[Pasted image 20240315124232.png]] 运行游戏,点击,效果也是正常的,实时修改也可以; 需要注意的是,两时间,是有制约关系的,间隔时间,是需要等动画播放完毕,才可以下一次点击,所以这里设置了MinValue最小值,就是按钮动画播放时间 ![[Pasted image 20240315124452.png]] ![[Pasted image 20240315124547.png]] 这是一个,遍历,创建Asset文件的脚本,可以看到,是继承自OdinMenuEditorWindow的,先拿到,自己创建的类 ![[Pasted image 20240315133039.png]] 会重写BuildMenuTree ![[Pasted image 20240315134042.png]] 是创建预制体的核心逻辑; 设置是,在menutree中,选中的预制体,作为asset命名; 在targetFolder目标文件夹中,创建即可; 其中预览Object实体,是在BuildMenuTree函数重写的逻辑里,完成初始化 参考:[[Activator.CreateInstance 方法]] ![[Pasted image 20240317184158.png]] ![[Pasted image 20240317184914.png]] 会根据选中的物体,如果是文件夹,就直接把它,当作目标文件夹;如果选中的物体,是文件,就拿它所在的文件夹,作为目标文件夹; 使用Trim处理修剪一下路径分割符号,然后显示窗体,即可 ![[Pasted image 20240317184427.png]] 表现 ![[Pasted image 20240319103329.png]] ![[Pasted image 20240319103354.png]] 这是收集UI节点的工具类 ![[Pasted image 20240319105656.png]] 在Canvas画布创建一个空节点 ![[Pasted image 20240319105732.png]] 加上这个工具类 ![[Pasted image 20240319105803.png]] 其中的UINode列表,包含一个UINodeGroup类 ![[Pasted image 20240319105934.png]] ![[Pasted image 20240319110010.png]] 点击+加号,会新增这个类对应的,绘制结构 ![[Pasted image 20240319110032.png]] 其中,节点类型的命名选择,是遍历UnityEngine.UI,拿到对应的Name字段即可 ![[Pasted image 20240319110110.png]] 而Nodes节点的选择,就是检索,所选物体,ChildGameObjectsOnly子物体下,归属UnityEngine.UI里面的节点; 其中的逻辑,也验证了,是否为选中的UI类型控件 ![[Pasted image 20240319110226.png]] 如果不是所选的UI类型控件,会显示这个报错提示 ![[Pasted image 20240319112959.png]] 在测试的空节点,创建3个ui组件 ![[Pasted image 20240319112633.png]] 先检索出来,Image图片类 ![[Pasted image 20240319112657.png]] 点+号,如逻辑所示,检索出子物体 ![[Pasted image 20240319112804.png]] 如果选择了,非Image类型的话,如逻辑所示,会出现验证提示 ![[Pasted image 20240319112829.png]] 修改成正确的类型,即可 ![[Pasted image 20240319113049.png]] ![[Pasted image 20240319113108.png]] 按钮和文本的ui控件,也是相同处理 ![[Pasted image 20240319113151.png]] 先加一个,对应面板的脚本 ![[Pasted image 20240319113216.png]] 加一个 partial 关键字 参考[[partial分部类和方法]]即可 ![[Pasted image 20240319113253.png]] 加上 ![[Pasted image 20240319113404.png]] 填上,点击 ![[Pasted image 20240319113433.png]] ![[Pasted image 20240319113451.png]] 对应逻辑; 文件后缀Extensions限制是"cs, lua",拿到对应类的名称,然后生成的类,命名后缀会加上,字符Extention; ![[Pasted image 20240319113520.png]] 添加注释说明,还有命名空间,主要使用StringBuilder实现即可; ![[Pasted image 20240319113725.png]] 创建一个Node,也是遍历uINodes里面节点组,创建即可 ![[Pasted image 20240319113842.png]] 最后,使用StreamWriter文件流,创建新的脚本文件即可 ![[Pasted image 20240319114021.png]] 这里有一个判断,是重名元素的 ![[Pasted image 20240319114104.png]] 是遍历节点组,查看是否有重复元素 ![[Pasted image 20240319114124.png]] 整一个字符串类,使用GroupBy处理,如果相同字符串的总数大于1,就输入提示 ![[Pasted image 20240319114153.png]] ![[Pasted image 20240319114334.png]] 测试一下,添加一个,Button下,跟Text控件,同名的子组件 ![[Pasted image 20240319114456.png]] ![[Pasted image 20240319114506.png]] 点击,重复提示,正常 ![[Pasted image 20240319114534.png]] 删掉测试的Text,重新点击 ![[Pasted image 20240319114607.png]] 自动创建出来了 ![[Pasted image 20240319114620.png]] 脚本内容 ![[Pasted image 20240319114650.png]] 编辑器表现: ![[Pasted image 20240319114733.png]] 为组件赋值,从className类名,这里是TestPanel,配合uINodes列表遍历,拿到对应的targetValue组件,再通过SetValue设置值即可 ![[Pasted image 20240319114801.png]] 点击,正常生效 ![[Pasted image 20240319115029.png]] 在这个脚本创建一个,按钮点击的逻辑 ![[Pasted image 20240319115121.png]] 运行,点击正常 ![[Pasted image 20240319115150.png]]