通知设置 新通知
在插件中实现控制台清空和插件刷新
编辑器使用 • misakacirno 发表了文章 • 0 个评论 • 104 次浏览 • 2025-12-17 15:15
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中。 查看全部
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 没有收到回调
回复Unity • Scottosong 发起了问题 • 0 人关注 • 0 个回复 • 120 次浏览 • 2025-12-12 14:35
cocos3.8.7中支持颜色混合
CocosCreator • GodChouyu 发表了文章 • 0 个评论 • 170 次浏览 • 2025-11-14 19:05
两种方法。
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,谷主看到的话希望能合并一下。
查看全部
两种方法。
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,谷主看到的话希望能合并一下。
FairyGUI 在 Unity 中异步加载字体
Unity • hwei 发表了文章 • 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 用到的字体,让中文先可读。然后等体积大的正式字体下载完毕再覆盖上去,提升画面效果。
FairyGUI导出选中的xml配置后,导出的目录结构和当前工作的目录结构不一致
回复编辑器使用 • gaxlin 发起了问题 • 1 人关注 • 0 个回复 • 219 次浏览 • 2025-09-04 10:07
在FairyGUI編輯器中,Spine的透明度異常、切圖會比預期的大
回复编辑器使用 • AlanHung 发起了问题 • 1 人关注 • 0 个回复 • 279 次浏览 • 2025-08-04 15:39
使用CreateObjectAsync, 组件出场音效首次播放失败
回复Unity • eggbbq 发起了问题 • 1 人关注 • 0 个回复 • 262 次浏览 • 2025-07-20 11:42
cocos2.2.1,使用装载器GLoader ,加载url,,url是https地址的,,,在安卓手机上不显示,,麻烦可以看一下这个问题吗
回复CocosCreator • cocos0524 发起了问题 • 1 人关注 • 0 个回复 • 389 次浏览 • 2025-07-16 19:08
Cocos creator3.8项目 其中使用了第三方字体 由Cocos creator预览后字体没有显示
回复CocosCreator • IssacLynx 发起了问题 • 1 人关注 • 0 个回复 • 476 次浏览 • 2025-05-22 20:38