FairyGUI editor custom menu extension plug-in

The software involved in this article is: FairyGUI, VSCode

The code environment involves: Lua

VSCode plug-in: EmmyLua

Before writing the FairyGUI editor menu, understanding the API of FairyGUIEditor will effectively help us solve many problems. The extension of FairyGUI is implemented through the plug-in function that comes with the editor. In the plug-in, I use the lua environment template. Import the LuaAPI of the editor. The file can be found in the plug-in directory of the FairyGUI-Editor source code. Next, the corresponding API functions will be explained through functions.

The location of the plugin

 If you can't find the plug-in panel, you can add it through "View → Plug-ins" or "Tools → Plug-ins".

1. Open the plug-in directory. The plug-in directory is under the "Project Directory/plugins" folder. Each plug-in corresponds to a subfolder.

2. Create a new plug-in

3. Refresh the plug-in list

The birth of a new plug-in

Click to create a new plug-in, and you can select the plug-in type and language format to be written in the plug-in template.

After clicking Create, the new plug-in just created will appear in the plug-in list.

At this time, click to open the plug-in directory, and you will find that there is a newly created plug-in folder in the originally empty plug-in directory. Right-click and use VSCode to open it.

It can be noticed that there are two files "main.lua" and "package.json" in the directory. Among them, main.lua is the entry script of the plug-in, and package.json is the configuration file of the plug-in.

After double-clicking main.lua, you can see the "onDestroy" method, and you can add subsequent cleanup code here. Save the written code and click to refresh the plug-in list in the editor to synchronize the latest plug-in code to the editor. If the editor saves at this time, if it is not a code writing error, you can refresh the plug-in by restarting the editor.

 Editor's personal common API

App is the project entry class, type: CS.FairyEditor.App. The function fields in the editor can be seen through CS_FairyEditor_App in LuaAPI. The fields and methods that will be used are listed below.

CS.FairyEditor.App
Field name type effect
project CS.FairyEditor.FProject Record the configuration and resources of the current project
libView CS.FairyEditor.View.LibraryView Editor's Library Panel
inspectorView CS.FairyEditor.View.InspectorView Editor's Inspector panel
consoleView CS.FairyEditor.View.ConsoleView Editor's console panel
menu CS.FairyEditor.Component.IMenu Editor menu bar
pluginManager CS.FairyEditor.PluginManager Plug-in management
CS.FairyEditor.FProject
Field name type effect
name string Project name "such as: FGUIProject"
basePath string The path of the project "such as: D:\Documents\FGUIProject"
assetsPath string The path of the project "such as: D:\Documents\FGUIProject\assets"
allPackages CS.FairyEditor.Fpackage[] All packages in the project
allBranches string[] All branches in the project
CS.FairyEditor.Fpackage
Field name type effect
name string The name of the current package
items CS.FairyEditor.FPackageItem[] Resources under the current package
CS.FairyEditor.FPackageItem
Field name type effect
path string Resource path
name string Resource name
CS.FairyEditor.View.LibraryView
Field name type effect
contextMenu CS.FairyEditor.Component.NPopupMenu Resource library right-click menu
CS.FairyEditor.Component.NPopupMenu
method name parameter effect
AddItem caption:string, name:string, selectCallback:(fun():void) Add a menu item and set a selected callback event
AddSeperator Add menu divider
SetItemGrayed string name, bool grayed Set target cannot be clicked
onPopup CS.FairyGUI.EventListener Menu popup event

 Start writing plugin code

Requirement 1

Requirement 1: Add the "Export all UI names" menu item to the tool menu, click and copy the result.

Premise: All UI interfaces have the same naming rules. Here I use UIXXX, so when getting all UIs, you only need to check whether the name of the current file UI exists. In this required function, you need to prepare a text code in Lua code format, and then replace the classField with the obtained UI name.

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

Detailed annotations have been added to the code. You can view the complete code directly:

---@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
 Requirement 2:

Requirement 2: Add "Copy Component Script Path" to the right-click menu of the resource library to facilitate the extraction of the require path of the current component. And implement component filtering. If the conditions are not met, the "Copy Component Script Path" menu item will be grayed out and unavailable.

Prerequisite: All non-UI components are stored in the Comps folder of the current package.

Create a new plug-in or continue writing in the previous plug-in. Here I am continuing to write from the previous plug-in.

---添加资源库右键菜单
---需求:复制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)

Don't forget to remove our menu item "XiaoCopyAssetPath" in the onDestroy method afterwards

toolMenu:RemoveItem("XiaoCopyAssetPath")

 

Complete plug-in code

---@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

Currently, only these two types of menu operations are used. If there are more in actual operations later, we will continue to update!

Guess you like

Origin blog.csdn.net/u012433546/article/details/132367236