6.1.3版本编辑器设置图集4的倍数导出, 有部分图片会拉伸

回复

编辑器使用chang1134 发起了问题 • 1 人关注 • 0 个回复 • 14 次浏览 • 1 天前 • 来自相关话题

能不能在代码中监听到点击了复制?

回复

编辑器使用南佐 发起了问题 • 1 人关注 • 0 个回复 • 59 次浏览 • 2026-01-08 15:02 • 来自相关话题

在插件中实现控制台清空和插件刷新

编辑器使用misakacirno 发表了文章 • 0 个评论 • 104 次浏览 • 2025-12-17 15:15 • 来自相关话题

控制台在API中直接暴露出来可获取,相对来说简单一些:
let consoleViewRoot: CS.FairyGUI.GComponent = App.consoleView.GetChildAt(0).asCom;
let clearButton: CS.FairyGUI.GButton = consoleViewRoot.GetChild("btnClear").asButton;
clearButton.onClick.Call();同时,通过这个途径,我们也可以获取控制台中的所有内容:
export function GetConsoleLines(): string[] {
/**
* ConsoleView的结构
* - ""(GComponenet)
* - "list"(GList)
* - "n12"(GGraph)
* - "btnCopy"(GButton)
* - "btnClear"(GButton)
* - "n9"(GGroup)
*/

let result: string[] = [];

let consoleViewRoot: CS.FairyGUI.GComponent = App.consoleView.GetChildAt(0).asCom;
let consoleList: CS.FairyGUI.GList = consoleViewRoot.GetChild("list").asList;

if (consoleList == null) {
console.warn("未找到Console列表");
return result;
}

console.log(`Console List Item Count: ${consoleList.numItems}`);
for (let i = 0; i < consoleList.numItems; i++) {
let item: CS.FairyGUI.GButton = consoleList.GetChildAt(i).asButton;
// console.log(`Console List Item ${i}: ${item.name} | ${item.GetType().FullName} | ${item.text}`);
result.push(item.text);
}

return result;
}
 
而插件并没有类似于 App.pluginView 的东西可以直接访问,经过一些研究,我发现它被存储于 App.viewManager 之中。
 
App.viewManager 内部应该是有个列表来管理成员,通过遍历其 viewIds 属性即可获得,例如:
let ids = App.viewManager.viewIds;
for (let i = 0; i < ids.Count; i++) {
let viewId = ids.get_Item(i);
let view = App.viewManager.GetView(viewId);
console.log(` View ${i}: ID=${viewId} | Name=${view.name} | Type=${view.GetType().FullName}`);
}可获得结果:

View 0: ID=fairygui.LibraryView | Name=fairygui.LibraryView | Type=FairyEditor.View.LibraryView
View 1: ID=fairygui.InspectorView | Name=fairygui.InspectorView | Type=FairyEditor.View.InspectorView
View 2: ID=fairygui.HierarchyView | Name=fairygui.HierarchyView | Type=FairyEditor.View.HierarchyView
View 3: ID=fairygui.PreviewView | Name=fairygui.PreviewView | Type=FairyEditor.View.PreviewView
View 4: ID=fairygui.TimelineView | Name=fairygui.TimelineView | Type=FairyEditor.View.TimelineView
View 5: ID=fairygui.TransitionListView | Name=fairygui.TransitionListView | Type=FairyEditor.View.TransitionListView
View 6: ID=fairygui.FavoritesView | Name=fairygui.FavoritesView | Type=FairyEditor.View.FavoritesView
View 7: ID=fairygui.SearchView | Name=fairygui.SearchView | Type=FairyEditor.View.SearchView
View 8: ID=fairygui.ConsoleView | Name=fairygui.ConsoleView | Type=FairyEditor.View.ConsoleView
View 9: ID=fairygui.ReferenceView | Name=fairygui.ReferenceView | Type=FairyEditor.View.ReferenceView
View 10: ID=fairygui.PlugInView | Name=fairygui.PlugInView | Type=FairyEditor.View.PlugInView
View 11: ID=fairygui.DocumentView | Name=fairygui.DocumentView | Type=FairyEditor.View.DocumentView
View 12: ID=fairygui.TestView | Name=fairygui.TestView | Type=FairyEditor.View.TestView

可以看出,编辑器中的全部窗口应该都在这个列表里了。
其中,fairygui.PlugInView 就是要找的插件窗口了。此时就可以用类似的方法调用了:
let pluginViewRoot: CS.FairyGUI.GComponent = App.viewManager.GetView("fairygui.PlugInView").GetChildAt(0).asCom;
let reloadButton: CS.FairyGUI.GButton = pluginViewRoot.GetChild("reload").asButton;
reloadButton.onClick.Call();但想法是美好的,现实是骨感的。
触发reload之后应该会卸载插件环境,但是执行指令还在插件的代码中执行,这里就会出现生命周期冲突的问题。
表现的迹象就是编辑器卡死随后闪退。
因此在插件中想要reload插件似乎是不现实的。也难怪这部分内容没有直接公开在编辑器的API中。 查看全部
控制台在API中直接暴露出来可获取,相对来说简单一些:
let consoleViewRoot: CS.FairyGUI.GComponent = App.consoleView.GetChildAt(0).asCom;
let clearButton: CS.FairyGUI.GButton = consoleViewRoot.GetChild("btnClear").asButton;
clearButton.onClick.Call();
同时,通过这个途径,我们也可以获取控制台中的所有内容:
export function GetConsoleLines(): string[] {
/**
* ConsoleView的结构
* - ""(GComponenet)
* - "list"(GList)
* - "n12"(GGraph)
* - "btnCopy"(GButton)
* - "btnClear"(GButton)
* - "n9"(GGroup)
*/

let result: string[] = [];

let consoleViewRoot: CS.FairyGUI.GComponent = App.consoleView.GetChildAt(0).asCom;
let consoleList: CS.FairyGUI.GList = consoleViewRoot.GetChild("list").asList;

if (consoleList == null) {
console.warn("未找到Console列表");
return result;
}

console.log(`Console List Item Count: ${consoleList.numItems}`);
for (let i = 0; i < consoleList.numItems; i++) {
let item: CS.FairyGUI.GButton = consoleList.GetChildAt(i).asButton;
// console.log(`Console List Item ${i}: ${item.name} | ${item.GetType().FullName} | ${item.text}`);
result.push(item.text);
}

return result;
}

 
插件并没有类似于 App.pluginView 的东西可以直接访问,经过一些研究,我发现它被存储于 App.viewManager 之中。
 
App.viewManager 内部应该是有个列表来管理成员,通过遍历其 viewIds 属性即可获得,例如:
let ids = App.viewManager.viewIds;
for (let i = 0; i < ids.Count; i++) {
let viewId = ids.get_Item(i);
let view = App.viewManager.GetView(viewId);
console.log(` View ${i}: ID=${viewId} | Name=${view.name} | Type=${view.GetType().FullName}`);
}
可获得结果:


View 0: ID=fairygui.LibraryView | Name=fairygui.LibraryView | Type=FairyEditor.View.LibraryView
View 1: ID=fairygui.InspectorView | Name=fairygui.InspectorView | Type=FairyEditor.View.InspectorView
View 2: ID=fairygui.HierarchyView | Name=fairygui.HierarchyView | Type=FairyEditor.View.HierarchyView
View 3: ID=fairygui.PreviewView | Name=fairygui.PreviewView | Type=FairyEditor.View.PreviewView
View 4: ID=fairygui.TimelineView | Name=fairygui.TimelineView | Type=FairyEditor.View.TimelineView
View 5: ID=fairygui.TransitionListView | Name=fairygui.TransitionListView | Type=FairyEditor.View.TransitionListView
View 6: ID=fairygui.FavoritesView | Name=fairygui.FavoritesView | Type=FairyEditor.View.FavoritesView
View 7: ID=fairygui.SearchView | Name=fairygui.SearchView | Type=FairyEditor.View.SearchView
View 8: ID=fairygui.ConsoleView | Name=fairygui.ConsoleView | Type=FairyEditor.View.ConsoleView
View 9: ID=fairygui.ReferenceView | Name=fairygui.ReferenceView | Type=FairyEditor.View.ReferenceView
View 10: ID=fairygui.PlugInView | Name=fairygui.PlugInView | Type=FairyEditor.View.PlugInView
View 11: ID=fairygui.DocumentView | Name=fairygui.DocumentView | Type=FairyEditor.View.DocumentView
View 12: ID=fairygui.TestView | Name=fairygui.TestView | Type=FairyEditor.View.TestView


可以看出,编辑器中的全部窗口应该都在这个列表里了。
其中,fairygui.PlugInView 就是要找的插件窗口了。此时就可以用类似的方法调用了:
let pluginViewRoot: CS.FairyGUI.GComponent = App.viewManager.GetView("fairygui.PlugInView").GetChildAt(0).asCom;
let reloadButton: CS.FairyGUI.GButton = pluginViewRoot.GetChild("reload").asButton;
reloadButton.onClick.Call();
但想法是美好的,现实是骨感的。
触发reload之后应该会卸载插件环境,但是执行指令还在插件的代码中执行,这里就会出现生命周期冲突的问题。
表现的迹象就是编辑器卡死随后闪退。
因此在插件中想要reload插件似乎是不现实的。也难怪这部分内容没有直接公开在编辑器的API中。

NTexture.CustomDestroyMethod 没有收到回调

回复

UnityScottosong 发起了问题 • 0 人关注 • 0 个回复 • 120 次浏览 • 2025-12-12 14:35 • 来自相关话题

[Laya2.0]Label中设置延展和自动收缩导致卡死bug

回复

Layacnscj 发起了问题 • 1 人关注 • 0 个回复 • 141 次浏览 • 2025-11-14 19:19 • 来自相关话题

cocos3.8.7中支持颜色混合

CocosCreatorGodChouyu 发表了文章 • 0 个评论 • 170 次浏览 • 2025-11-14 19:05 • 来自相关话题

仅在cocos3.8.7中测试。
两种方法。
1.可以修改源码的情况下,修改BlendMode.ts文件的apply函数。
public static apply(node: Node, blendMode: BlendMode) {
let f = factors[<number>blendMode];
node.components.forEach(component => {
if (component instanceof UIRenderer) {
component["_srcBlendFactor"] = f[0];
component["_dstBlendFactor"] = f[1];
}
})
}2.不修改源码,覆盖GObject的setup_beforeAdd方法。随意一个脚本中添加并调用Init();
public static init() {
const factors = [
[gfx.BlendFactor.SRC_ALPHA, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //normal
[gfx.BlendFactor.ONE, gfx.BlendFactor.ONE], //none
[gfx.BlendFactor.SRC_ALPHA, gfx.BlendFactor.ONE], //add
[gfx.BlendFactor.DST_COLOR, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //mul
[gfx.BlendFactor.ONE, gfx.BlendFactor.ONE_MINUS_SRC_COLOR], //screen
[gfx.BlendFactor.ZERO, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //erase
[gfx.BlendFactor.ZERO, gfx.BlendFactor.SRC_ALPHA], //mask
[gfx.BlendFactor.ONE_MINUS_DST_ALPHA, gfx.BlendFactor.DST_ALPHA], //below
[gfx.BlendFactor.ONE, gfx.BlendFactor.ZERO], //off
[gfx.BlendFactor.SRC_ALPHA, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //custom1
[gfx.BlendFactor.SRC_ALPHA, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //custom2
[gfx.BlendFactor.SRC_ALPHA, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //custom2
];

const GObjectSetupBeforeAdd = fgui.GObject.prototype.setup_beforeAdd;
fgui.GObject.prototype.setup_beforeAdd = function (this: fgui.GObject, buffer: ByteBuffer, beginPos: number) {
GObjectSetupBeforeAdd.call(this, buffer, beginPos);
let f = factors[<number>this.blendMode];
this.node.components.forEach(component => {
if (component instanceof cc.UIRenderer) {
component["_srcBlendFactor"] = f[0];
component["_dstBlendFactor"] = f[1];
}
})
}
}
因为blend模块的相关代码没有导出,所以先这么处理。factors数组是从fgui源码中复制出来的。
_srcBlendFactor和_dstBlendFactor两个属性的cocos源码在cocos源码地址。
 
已经提交pr,谷主看到的话希望能合并一下。
  查看全部
仅在cocos3.8.7中测试。
两种方法。
1.可以修改源码的情况下,修改BlendMode.ts文件的apply函数。
public static apply(node: Node, blendMode: BlendMode) {
let f = factors[<number>blendMode];
node.components.forEach(component => {
if (component instanceof UIRenderer) {
component["_srcBlendFactor"] = f[0];
component["_dstBlendFactor"] = f[1];
}
})
}
2.不修改源码,覆盖GObject的setup_beforeAdd方法。随意一个脚本中添加并调用Init();
public static init() {
const factors = [
[gfx.BlendFactor.SRC_ALPHA, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //normal
[gfx.BlendFactor.ONE, gfx.BlendFactor.ONE], //none
[gfx.BlendFactor.SRC_ALPHA, gfx.BlendFactor.ONE], //add
[gfx.BlendFactor.DST_COLOR, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //mul
[gfx.BlendFactor.ONE, gfx.BlendFactor.ONE_MINUS_SRC_COLOR], //screen
[gfx.BlendFactor.ZERO, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //erase
[gfx.BlendFactor.ZERO, gfx.BlendFactor.SRC_ALPHA], //mask
[gfx.BlendFactor.ONE_MINUS_DST_ALPHA, gfx.BlendFactor.DST_ALPHA], //below
[gfx.BlendFactor.ONE, gfx.BlendFactor.ZERO], //off
[gfx.BlendFactor.SRC_ALPHA, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //custom1
[gfx.BlendFactor.SRC_ALPHA, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //custom2
[gfx.BlendFactor.SRC_ALPHA, gfx.BlendFactor.ONE_MINUS_SRC_ALPHA], //custom2
];

const GObjectSetupBeforeAdd = fgui.GObject.prototype.setup_beforeAdd;
fgui.GObject.prototype.setup_beforeAdd = function (this: fgui.GObject, buffer: ByteBuffer, beginPos: number) {
GObjectSetupBeforeAdd.call(this, buffer, beginPos);
let f = factors[<number>this.blendMode];
this.node.components.forEach(component => {
if (component instanceof cc.UIRenderer) {
component["_srcBlendFactor"] = f[0];
component["_dstBlendFactor"] = f[1];
}
})
}
}

因为blend模块的相关代码没有导出,所以先这么处理。factors数组是从fgui源码中复制出来的。
_srcBlendFactor和_dstBlendFactor两个属性的cocos源码在cocos源码地址
 
已经提交pr,谷主看到的话希望能合并一下。
 

FGUI 编辑器插件如何获取文本和按钮的标题

回复

编辑器使用xiepeng888 发起了问题 • 1 人关注 • 0 个回复 • 215 次浏览 • 2025-11-11 10:54 • 来自相关话题

FairyGUI 在 Unity 中异步加载字体

Unityhwei 发表了文章 • 0 个评论 • 295 次浏览 • 2025-10-23 17:07 • 来自相关话题

如果你在开发小游戏,字体文件通常很大,并且需要在第一次运行时下载。这有可能会影响首屏加载性能。
 
为了解决这个问题,我们不用等待字体下载好,先提前显示 UI。
此时 UI 中的中文可能会无法显示。
不过没关系,等字体下载好再用下面这个函数来加载字体:
public static void SetFont(string name, Font font)
{
// 如果其他 UI 已经用过 name 字体,则获得该字体的动态字体对象,否则 GetFont 会自动返回一个默认动态字体。
var dynamicFont = FairyGUI.FontManager.GetFont(name) as FairyGUI.DynamicFont;
// 无论如何,更新这个字体背后的 Unity Font 对象
dynamicFont.nativeFont = font;
// version 变化会触发使用到这个字体的 UI 刷新
dynamicFont.version += 1;
}于是就做到了异步加载字体。
 
进一步优化:先用一个体积比较小的字体覆盖所有 UI 用到的字体,让中文先可读。然后等体积大的正式字体下载完毕再覆盖上去,提升画面效果。 查看全部
如果你在开发小游戏,字体文件通常很大,并且需要在第一次运行时下载。这有可能会影响首屏加载性能。
 
为了解决这个问题,我们不用等待字体下载好,先提前显示 UI。
此时 UI 中的中文可能会无法显示。
不过没关系,等字体下载好再用下面这个函数来加载字体:
public static void SetFont(string name, Font font)
{
// 如果其他 UI 已经用过 name 字体,则获得该字体的动态字体对象,否则 GetFont 会自动返回一个默认动态字体。
var dynamicFont = FairyGUI.FontManager.GetFont(name) as FairyGUI.DynamicFont;
// 无论如何,更新这个字体背后的 Unity Font 对象
dynamicFont.nativeFont = font;
// version 变化会触发使用到这个字体的 UI 刷新
dynamicFont.version += 1;
}
于是就做到了异步加载字体。
 
进一步优化:先用一个体积比较小的字体覆盖所有 UI 用到的字体,让中文先可读。然后等体积大的正式字体下载完毕再覆盖上去,提升画面效果。

切换场景后,第一次点击无效。

回复

Unityxiaomaitai 发起了问题 • 1 人关注 • 0 个回复 • 299 次浏览 • 2025-09-06 12:39 • 来自相关话题

FairyGUI导出选中的xml配置后,导出的目录结构和当前工作的目录结构不一致

回复

编辑器使用gaxlin 发起了问题 • 1 人关注 • 0 个回复 • 219 次浏览 • 2025-09-04 10:07 • 来自相关话题

编辑器报错

回复

编辑器使用无名无性 发起了问题 • 1 人关注 • 0 个回复 • 213 次浏览 • 2025-08-28 10:41 • 来自相关话题

fairy导入序列帧图片过多时会闪退

回复

编辑器使用tdddd 发起了问题 • 2 人关注 • 0 个回复 • 262 次浏览 • 2025-08-05 16:27 • 来自相关话题

在FairyGUI編輯器中,Spine的透明度異常、切圖會比預期的大

回复

编辑器使用AlanHung 发起了问题 • 1 人关注 • 0 个回复 • 279 次浏览 • 2025-08-04 15:39 • 来自相关话题

图片平铺次数

回复

编辑器使用yhy 发起了问题 • 1 人关注 • 0 个回复 • 325 次浏览 • 2025-08-04 11:46 • 来自相关话题

使用CreateObjectAsync, 组件出场音效首次播放失败

回复

Unityeggbbq 发起了问题 • 1 人关注 • 0 个回复 • 262 次浏览 • 2025-07-20 11:42 • 来自相关话题

为啥虚拟列表和普通列表的_overlapSize值不一样

回复

Unityzzzxaa 发起了问题 • 1 人关注 • 0 个回复 • 318 次浏览 • 2025-07-16 10:39 • 来自相关话题

最小化无法打开

回复

编辑器使用jeff2023 发起了问题 • 1 人关注 • 0 个回复 • 217 次浏览 • 2025-06-09 15:38 • 来自相关话题

Cocos creator3.8项目 其中使用了第三方字体 由Cocos creator预览后字体没有显示

回复

CocosCreatorIssacLynx 发起了问题 • 1 人关注 • 0 个回复 • 476 次浏览 • 2025-05-22 20:38 • 来自相关话题

unity导入报错

回复

Unitycoder 发起了问题 • 1 人关注 • 0 个回复 • 286 次浏览 • 2025-05-22 11:37 • 来自相关话题