FairyGUI编辑器自定义菜单扩展插件

news2025/1/22 15:05:29

本文涉及到的软件有:FairyGUI,VSCode

代码环境涉及到了:Lua

VSCode插件:EmmyLua

在编写FairyGUI编辑器菜单前,了解一下FairyGUIEditor的API会有效的帮助我们解决很多问题。FairyGUI的扩展是通过编辑器自带的插件功能实现的,插件中我使用的是lua环境模板。导入编辑器的LuaAPI,文件可以在FairyGUI-Editor源码的插件目录中找到。接下来将通过功能来说明对应的API作用。

插件的位置

 如果找不到插件面板,可以通过“视图→插件”或“工具→插件”添加插件面板。

1、打开插件目录,插件目录是在“项目目录/plugins"文件夹下,每个插件对应一个子文件夹。

2、创建新插件

3、刷新插件列表

一个新插件的诞生

点击创建新插件,可以在插件模板选择要写的插件类型和语言格式

点击创建后,插件列表中就会出现刚刚创建的新插件。

这时候,点击打开插件目录,会发现原本空空的插件目录中多了一个刚刚新建的插件文件夹,右键使用VSCode打开。

可以注意到,目录下有两个文件“main.lua”和“package.json”。其中main.lua是插件的入口脚本,package.json是插件的配置文件。

双击main.lua后可以看到“onDestroy”方法,可以将之后的清理代码添加到此处。保存编写后的代码,在编辑器中点击刷新插件列表,可以将最新插件代码同步到编辑器。如果这时候编辑器保存,如果不是代码书写错误,可以通过重启编辑器进行刷新插件。

 编辑器的个人常用API

App是工程入口类,类型:CS.FairyEditor.App。通过LuaAPI中的CS_FairyEditor_App可以看到编辑器中的功能字段。下面将列出将要用的字段和方法。

CS.FairyEditor.App
字段名类型作用
projectCS.FairyEditor.FProject记录当前工程的配置和资源
libViewCS.FairyEditor.View.LibraryView编辑器的资源库面板
inspectorViewCS.FairyEditor.View.InspectorView编辑器的检查器面板
consoleViewCS.FairyEditor.View.ConsoleView编辑器的控制台面板
menuCS.FairyEditor.Component.IMenu编辑器的菜单栏
pluginManagerCS.FairyEditor.PluginManager插件管理
CS.FairyEditor.FProject
字段名类型作用
namestring工程名“如:FGUIProject”
basePathstring工程的路径“如:D:\Documents\FGUIProject”
assetsPathstring工程的路径“如:D:\Documents\FGUIProject\assets”
allPackagesCS.FairyEditor.Fpackage[]工程中的所有包
allBranchesstring[]工程中的所有分支
CS.FairyEditor.Fpackage
字段名类型作用
namestring当前包的名字
itemsCS.FairyEditor.FPackageItem[]当前包下的资源
CS.FairyEditor.FPackageItem
字段名类型作用
pathstring资源路径
namestring资源名
CS.FairyEditor.View.LibraryView
字段名类型作用
contextMenuCS.FairyEditor.Component.NPopupMenu资源库的右键菜单
CS.FairyEditor.Component.NPopupMenu
方法名参数作用
AddItemcaption:string, name:string, selectCallback:(fun():void)添加一个菜单项并设置选中回调事件
AddSeperator添加菜单分割线
SetItemGrayedstring name, bool grayed设置目标不能点击
onPopupCS.FairyGUI.EventListener菜单弹出事件

 开始编写插件代码

需求1

需求1:在工具菜单中添加“导出所有UI名字”的菜单项,点击后复制结果。

前提:所有UI界面具有相同的命名规则,这里我用的是UIXXX,所以在获取所有UI的时候只需要检测当前文件的名字UI是否存在。在这个需求实现的功能中,需要准备一个lua代码格式的文本代码,之后会将classField替换为获取到的UI名。

local tmp_ui_type = [[
---@class UIType
return {
    classField
}
]]

代码已经加了详细的注解,可以直接查看完整代码:

---@type CS.FairyEditor.App
local _app = CS.FairyEditor.App
local project = _app.project
---输出绝对文件路径
local file_out_path =("%s/UIType.lua"):format(project.basePath)
---Lua模板
local tmp_ui_type = [[
---@class UIType
return {
    classField
}
]]
---获取工具菜单
---@type CS.FairyEditor.Component.MenuBar
local toolMenu = _app.menu:GetSubMenu("tool")
---添加分隔符
toolMenu:AddSeperator()
---添加菜单,显示名字,内部标签名,回调方法
toolMenu:AddItem("导出UIType","XiaoExportUIType",function()
    local _classField = ""
    ---获取工程中的所有包,返回值是列表
    local allPackages = _app.project.allPackages
    for i = 1, allPackages.Count do
        ---C#索引从0开始
        ---@type CS.FairyEditor.FPackage
        local package = allPackages[i - 1]
        ---获取当前包中的所有子项,返回值是列表
        local items = package.items
        for i = 1, items.Count do
            ---@type CS.FairyEditor.FPackageItem
            local item = items[i - 1]
            ---记录所有UI开头的子项
            if string.find(item.name,"UI") == 1 then
                local uiType = string.format("%s = %s_%s,\n\t",item.name,package.name,item.name)
                _classField = _classField .. uiType
            end
        end
    end
    ---输出日志打印
    fprint(_classField)
    ---替换模板
    tmp_ui_type = tmp_ui_type:gsub("classField",_classField)
    ---写出模板
    local f = io.open(file_out_path,"w")
    f:write(tmp_ui_type)
    f:close()
    ---输出路径打印
    fprint(string.format("导出UIType:[url]%s[/url]",file_out_path))
end)
function onDestroy()
-------do cleanup here-------
    toolMenu:RemoveItem("XiaoExportUIType")
end

 需求2:

需求2:在资源库的右键菜单中添加“复制组件脚本路径”,方便提取当前组件的require路径。并且实现组件筛选,在不满足条件的情况下,“复制组件脚本路径”菜单项置灰不可用。

前提:所有非UI的组件都在当前包的Comps的文件夹下存放。

重新新建一个插件或者在之前的插件中继续编写,这里我是接着之前的插件继续写。

---添加资源库右键菜单
---需求:复制Comps文件夹下的组件所转化的脚本路径
---获取右键菜单
local libcontextMenu = _app.libView.contextMenu
---添加分割线
libcontextMenu:AddSeperator()
libcontextMenu:AddItem("复制组件脚本路径","XiaoCopyAssetPath",function()
    ---获取当前选中的资源
    ---@type CS.FairyEditor.FPackageItem
    local item = _app.libView:GetSelectedResource()
    ---检测资源是否满足条件
    if item.path:find("/Comps/") == 1 then
        ---准备复制
        local cp_str = ("require(\"UI.%s.Comps.%s\")"):format(item.owner.name,item.name)
        ---Unity复制操作
        CS.UnityEngine.GUIUtility.systemCopyBuffer = cp_str
        ---弹窗提示
        _app.Alert("复制成功")
    else
        _app.Alert("复制失败")
    end
end)
---在弹出的菜单中检测当前选择的资源是否满足条件
libcontextMenu.onPopup:Add(function()
    ---@type CS.FairyEditor.FPackageItem
    local item = _app.libView:GetSelectedResource()
    local grayed = true
    if item.path:find("/Comps/") == 1 then
        -- body
        grayed = false
    end

    libcontextMenu:SetItemGrayed("XiaoCopyAssetPath",grayed)
end)

之后不要忘记在onDestroy方法中移除我们的菜单项“XiaoCopyAssetPath”

toolMenu:RemoveItem("XiaoCopyAssetPath")

 

完整插件代码

---@type CS.FairyEditor.App
local _app = CS.FairyEditor.App
local project = _app.project

---输出绝对文件路径
local file_out_path =("%s/UIType.lua"):format(project.basePath)

---Lua模板
local tmp_ui_type = [[
---@class UIType
return {
    classField
}
]]

---获取工具菜单
---@type CS.FairyEditor.Component.MenuBar
local toolMenu = _app.menu:GetSubMenu("tool")
---添加分隔符
toolMenu:AddSeperator()
---添加菜单,显示名字,内部标签名,回调方法
toolMenu:AddItem("导出UIType","XiaoExportUIType",function()
    local _classField = ""
    ---获取工程中的所有包,返回值是列表
    local allPackages = _app.project.allPackages
    for i = 1, allPackages.Count do
        ---C#索引从0开始
        ---@type CS.FairyEditor.FPackage
        local package = allPackages[i - 1]
        ---获取当前包中的所有子项,返回值是列表
        local items = package.items
        for i = 1, items.Count do
            ---@type CS.FairyEditor.FPackageItem
            local item = items[i - 1]
            ---记录所有UI开头的子项
            if string.find(item.name,"UI") == 1 then
                local uiType = string.format("%s = %s_%s,\n\t",item.name,package.name,item.name)
                _classField = _classField .. uiType
            end
        end
    end
    ---输出日志打印
    fprint(_classField)
    ---替换模板
    tmp_ui_type = tmp_ui_type:gsub("classField",_classField)
    ---写出模板
    local f = io.open(file_out_path,"w")
    f:write(tmp_ui_type)
    f:close()
    ---输出路径打印
    fprint(string.format("导出UIType:[url]%s[/url]",file_out_path))
end)

---添加资源库右键菜单
---需求:复制Comps文件夹下的组件所转化的脚本路径
---获取右键菜单
local libcontextMenu = _app.libView.contextMenu
---添加分割线
libcontextMenu:AddSeperator()
libcontextMenu:AddItem("复制组件脚本路径","XiaoCopyAssetPath",function()
    ---获取当前选中的资源
    ---@type CS.FairyEditor.FPackageItem
    local item = _app.libView:GetSelectedResource()
    ---检测资源是否满足条件
    if item.path:find("/Comps/") == 1 then
        ---准备复制
        local cp_str = ("require(\"UI.%s.Comps.%s\")"):format(item.owner.name,item.name)
        ---Unity复制操作
        CS.UnityEngine.GUIUtility.systemCopyBuffer = cp_str
        ---弹窗提示
        _app.Alert("复制成功")
    else
        _app.Alert("复制失败")
    end
end)

---在弹出的菜单中检测当前选择的资源是否满足条件
libcontextMenu.onPopup:Add(function()
    ---@type CS.FairyEditor.FPackageItem
    local item = _app.libView:GetSelectedResource()
    local grayed = true
    if item.path:find("/Comps/") == 1 then
        -- body
        grayed = false
    end

    libcontextMenu:SetItemGrayed("XiaoCopyAssetPath",grayed)
end)


function onDestroy()
-------do cleanup here-------
    toolMenu:RemoveItem("XiaoExportUIType")
    toolMenu:RemoveItem("XiaoCopyAssetPath")
end

菜单的操作目前只用到了这两种,后面在实际操作中如果还有,则会继续更新!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/895254.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sed 语法和基础命令

1. 准备工作 准备备一个数据文件data.txt,内容如下: 101,Zhang san,Fu Jian 102,Li si,Shan Dong 103,Wang Wu,Bei Jing 104,Zhao Qian Sun,Zhe Jiang 105,Ge Lin,Shang Hai 每一行为一条数据,每条数据包含三个元素:ID&#xf…

薪资涨幅1000%+,转行学Java后,他彻底开挂了

以下为学长故事的文字版: 哈喽黑马程序员的学员们大家好,我是17级毕业的学长陈同学,很高兴和大家分享我的转行故事。 来黑马前后的变化 我刚毕业是去了浙江的一个电力公司,做电器的一个项目,这个项目一共工作了半年…

PIN TO PIN替代LT8911EXB|CS5523低成本替代LT8911EXB|MIP DSI转DP EDP方案设计

PIN TO PIN替代LT8911EXB|CS5523低成本替代LT8911EXB|MIP DSI转DP EDP方案设计 LT8911EXB是MIPI DSI/CSI 转eDP转换芯片,ASL CS5523不需要改电路就可以直接PIN TO PIN替代与兼容LT8911EXB。 ASL CS5523与 LT8911EXB的功能与参数,用途方式以及封装方式和…

《TCP IP网络编程》第十八章

第 18 章 多线程服务器端的实现 18.1 理解线程的概念 线程背景: 第 10 章介绍了多进程服务端的实现方法。多进程模型与 select 和 epoll 相比的确有自身的优点,但同时也有问题。如前所述,创建(复制)进程的工作本身会…

[Docker精进篇] Docker镜像构建和实践 (三)

前言: Docker镜像构建的作用是将应用程序及其依赖打包到一个可移植、自包含的镜像中,以便在不同环境中快速、可靠地部署和运行应用程序。 文章目录 Docker镜像构建1️⃣是什么?2️⃣为什么?3️⃣镜像构建一、用现有容器构建新镜像…

构建可远程访问的企业内部论坛

文章目录 前言1.cpolar、PHPStudy2.Discuz3.打开PHPStudy,安装网页论坛所需软件4.进行网页运行环境的构建5.运行Discuz网页程序6.使用cpolar建立穿透内网的数据隧道,发布到公网7.对云端保留的空白数据隧道进行配置8.Discuz论坛搭建完毕 前言 企业在发展…

Python科研绘图--Task01

目录 科研论文配图主要成分 常见的插图格式 像素图 矢量图 色彩模式 RGB色彩模式 CMYK色彩模式 HEX色彩模式 色轮配色原理 单色配色方案 例子 互补色配色方案 例子 等距三角配色方案 例子 四角配色方案 例子 颜色主题 单色系 例子 双色渐变色系 例子 多色…

直线导轨的选购要素

直线导轨是用来支撑和引导运动部件,按给定的方向做往复直线运动,主要用于精密机床、坐标测量机和大型机床,对于我们整个国民生产、生活活动都起着至关重要的作用。 我们在选购直线导轨时,都想要选到质量好的,那么我们要…

【JavaEE基础学习打卡05】JDBC之基本入门就可以了

目录 前言一、JDBC学习前说明1.Java SE中JDBC2.JDBC版本 二、JDBC基本概念1.JDBC原理2.JDBC组件 三、JDBC基本编程步骤1.JDBC操作的数据库准备2.JDBC操作数据库表步骤 四、代码优化1.简单优化2.with-resources探讨 总结 前言 📜 本系列教程适用于JavaWeb初学者、爱好…

Spring框架之揭秘Bean的生命周期与单例详解【面试题超详细回答】

目录 一、前言 1.1.介绍Spring框架和Bean的概念 二、Bean的实例化阶段 2.1.Bean的实例化过程 2.2.介绍默认构造函数和工厂方法的使用 三、Bean的初始化阶段 3.1.InitializingBean接口和PostConstruct注解的使用 3.2.Bean的初始化方法配置和执行顺序 四、Bean的销毁阶段…

数据库变革:HashData云数仓实现事务级实时性

8月16-18日,第十四届中国数据库技术大会(DTCC 2023)在北京召开。酷克数据资深解决方案架构师陈义贤在“数据库内核•技术创新”专场发表题为“分布式数仓的TP能力探索—HashData UnionStore”的演讲,介绍HashData以Log is databas…

QT的mysql(数据库)最佳实践和常见问题解答

涉及到数据库,首先安利一个软件Navicat Premium,用来查询数据库很方便 QMysql驱动是Qt SQL模块使用的插件,用于与MySQL数据库进行通信。要编译QMysql驱动,您需要满足以下条件: 您需要安装MySQL的客户端库和开发头文件…

三生ONE物,无限可能|博睿数据上市三周年!

2020年8月17日,北京博睿宏远数据科技股份有限公司作为国内A股市场上的“APM应用性能监控第一股”公司,在科创板荣登上市!(股票号688229) 2023年8月17日,三载日夜更替,博睿一路砥砺前行&#xf…

Eclipse集成MapStruct

Eclipse集成MapStruct 在Eclipse中添加MapStruct依赖配置Eclipse支持MapStruct①安装 m2e-aptEclipse Marketplace的方式安装Install new software的方式安装(JDK8用到) ②添加到pom.xml 今天拿到同事其他项目的源码,导入并运行的时候抛出了异…

Channel是什么?FileChannel类的常用方法

Channel 是一个接口对象,它类似于传统的流对象,但与传统的流对象又有些不同,具体表现如下: • Channel可以异步地执行I/O读写操作。 • Channel的读写操作是双向的,既可以从 Channel中读取数据,又可以写数据到Channel,而流的读写操作通常都是单向的。 • Channel…

Can‘t find end of central directory : is this a zip file ? at XMLHttpRequest

导出woed出现这个报错,原因其实很简单,路径写错了, 这个word首先必须是docx格式,然后必须放在public文件包下 如果放在public文件包下还没有用,则放在public包下 参考帖子: https://www.cnblogs.com/hejun26/p/13647927.html

VR漫游:720度实景参观,打造魅力生态小区

随着城市的不断发展,小区的建设越发具有生态化、绿色化的特点,人们也会偏向选择更加适合居住的小区。为了让更多的用户体验小区的舒适性,不少地产开发商准备引入VR漫游技术。 VR漫游不仅能够真实地展示现场环境,还可以改变传统网络…

shell编程 基础

将content.txt文件中的内容输出到控制台上 将content.txt中有tom的行输出到控制台 将$2文件中含有gree的行输出到控制台 case语法 简易计算器 查找有root的行 查找以root开头的行 查询时忽略大小写 grep -E 则适用于复杂的正则表达式,可以使用多项选择、重复和子表达…

开发者不可错过的提效工具——低代码开发

开发者不可错过的提效工具 基础低码功能及搭建 01、代码生成器 02、工作流程 03、门户设计 04、大屏设计 05、报表设计 06、第三方登录 07、多租户实现 08、分布式调度 为什么低码平台能够成为开发者的宠儿? 1.低码平台能够大幅提高开发效率 2.低码平台具备高度的可…

QString常用函数介绍

此篇博客核心介绍QT中的QString类型的常用函数,介绍到的函数均从帮助手册或其他博客中看到 QString 字符串类 Header: #include qmake: QT core 一、QString字符串转换 1、QString类字符串转换为整数 int toInt(bool *ok Q_NULLPTR, int base 10) cons…