meta data for this page
📚 GUI功能参考
在沙盘引擎中,有关GUI的功能分成两个部分,分别是FairyGUI模板
与NativeGUI
组成。
沙盘引擎默认使用FairyGUI作为UI系统框架,经过综合考虑得出结果,引擎内的模组、衍生作品UI搭建也应使用FairyGUI工具进行制作。
📒 为什么使用FairyGUI
FairyGUI是一个国产的优质游戏UI解决方案(社区免费),且经过沙盘引擎开发者的亲身体验,确实对GameUI开发会起到很大的帮助和简化流程,沙盘引擎本身就是使用FGUI作为UI框架,同时经过综合考虑后,引擎的模组、衍生作品也应使用此框架工具进行制作UI。
在早期引擎版本中,我们曾考虑过同时支持FGUI、NativeGUI(原生代码UI)的方案,但是考虑到实际开发阶段不会有太多开发者愿意使用代码的方式,而更多愿意使用“所见即所得”的制作界面,为了减少开发维护成本,所以最终只选择FairyGUI作为UI开发工具和框架。
尽管学习FairyGUI需要一点时间成本,但是好在工具的上手难度并不高,毕竟游戏UI也是决定作品是否精彩的关键组成,所以强烈建议开发者使用FairyGUI进行UI制作,可以无需代码+所见即所得实现大部分常用的UI功能和效果。
📒 引擎默认UI
尽管沙盘引擎开放了绝大部分内容允许开发者进行自定义UI,但是仍然有部分内容属于引擎原生内容从而无法进行自定义UI及修改(因为理论上不应该被修改,且修改资源、重写API难度较大)。
常见的例如:引擎地图编辑器、设置界面、服务器浏览器界面、默认开发者名单等。
经过版本更新迭代,除地图编辑器这类并不建议修改的默认UI外,其他例如设置菜单、服务器浏览器等内容均可实现自定义UI,并提供了对应的API以供数据获取和保存,如果开发者并不喜欢引擎原生的设置菜单、服务器浏览器这些,完全可以使用FairyGUI(或修改Public包)等方式来重写这类UI,并且功能可做到完全一致。
例如关键API:SetGameOption
BindGameOption
目前版本来看,如果没有一定开发基础仍然不建议对原生UI进行修改,特别是设置菜单重写适配是有一定难度的。原生界面已经尽可能适配更多场景,除了UI风格固定外是十分稳定的,可以尝试接受它。
📒 引擎加载UI逻辑
当模组开始加载时,遍历载入Store\GUI
文件夹内的FairyGUI导出文件.bytes
(提前预加载到内存中,无论是否使用)。
Store文件夹
内的文件大多数都是在加载模组时载入到内存中,所以开发者应该确保没有多余、重复、恶意的文件放到这里。
📒 快速入门:开始制作GUI
注意:GUI代码只能通过客户端脚本内实现,因为这属于客户端内容。
在沙盘引擎GUI框架设计中,虽然框架本身基于FairyGUI,但是为了更适合引擎内的直接使用,沙盘引擎对GUI内容重新封装了一个Client.GUI
类。
除此之外,开发者也应该遵守引擎所制定的UI制作及命名规范。
📘 创建FairyGUI工程
沙盘引擎是原生支持FairyGUI框架的,所以开发者只需要按照正常步骤,通过FairyGUI创建一个UI工程即可。
有关FairyGUI的工具内操作请访问https://www.fairygui.com/docs/editor查看。
注意:引擎最终需要读取的是由FairyGUI导出的bytes
文件及资源,并不需要UI工程源文件,所以工程文件夹可以不用放到模组文件夹中。
📘 导出到模组GUI目录
注意:导出这个词只是一个习惯性解释,在FairyGUI工具中应该叫作发布。
FairyGUI工具内的导出可参考文档:https://www.fairygui.com/docs/editor/publish。
导出目录需要是:Mod\Store\GUI
,导出成功后应该包含package_fui.bytes
与package_xxx.png
图集等文件,无需将FairyGUI源文件放到模组中。
package_fui.bytes | package_xxx.png
),否则引擎可能无法正确识别GUI数据。
📘 模组GUI翻译文件
如果模组GUI不需要用到多语言翻译功能,可以忽略此部分。
如果开发模组拥有FairyGUI多语言文件(.xml),只需将语言文件导出到Mod/Language
目录下(FairyGUI机制:所有包共用一个xml
语言文件),引擎在载入新场景时会自动导入翻译。
关于语言适配详情参考《游戏多语言适配》。
📘 通过脚本进行使用
当开发者将GUI文件导出到模组GUI目录后,模组将会在下次载入场景时自动导入GUI资源。
因此,在导入GUI后如需使用,至少应该重载场景或载入新的场景进行更新。
//使用此方法创建一个FGUI实例 let testView = GUI.Create("PackageName", "ViewName"); //创建UI之后,剩下的代码基本和FairyGUI使用方式相同,只不过需要注意JavaScript的限制和特性 let button = testView.GetChild("Button").asButton; if(button) { button.onClick.Set(() => { DLog(view.GetChild("n1").name); }); }
除了Client.GUI
部分引擎封装的API之外,其他的代码都是基于FairyGUI API
,开发者可尝试直接按照FairyGUI代码方式来使用。
📒 GUI脚本扩展类
此项内容比较重要,建议开发者可以参考,可能会对开发UI事半功倍。
在GUI的制作过程中,经常会遇到某些附带功能且经常被复用的组件,比如说背包系统的背包格子,按照传统的方式可能需要每次建立一个格子就得绑定“此UI的文本、图片等引用”,哪怕是自行封装一个方法也仍然会比较麻烦。
GUI类延续了FairyGUI的UIObjectFactory.SetPackageItemExtension
方法,并根据需要对其封装成了GUI.BindExtend
方法。
使用此功能,开发者可以为某个GUI组件绑定一个扩展类,绑定的类负责此组件的全部生命周期事件,这样可以对一些复杂或频繁复用的UI组件更清晰的开发。
//需要在UI被建立之前,初始化一次绑定事件,以后就不需要再绑定了 GUI.BindExtend("SEngineGUI", "UIView_Test", "MyButton"); //包名、组件名、脚本扩展类名 //这里是自行在脚本中新建的一个“UI扩展类”,继承的是GButton(什么类型的组件就要扩展什么类型的类,最好按照规范) class MyButton extends FairyGUI.GButton { //定义了一个整数型变量 count = 0; constructor() { //此处的代码必须完整保留 super(); this.__onConstruct = () => { this.onConstruct(); }; } //初始化函数 onConstruct() { //获取了当前组件下的n1子组件下的title子组件,并修改其标题为“点击” this.GetChild("n1").GetChild("title").text = "点击"; //为当前组件绑定一个点击事件 this.onClick.Set(() => { this.count ++; this.GetChild("n1").GetChild("title").text = this.count.toString(); }); } //自定义函数 test() { DLog("test"); } } //确认已经绑定事件后,按正常方式创建UI即可 let view = GUI.Create("SEngineGUI", "UIView_Test"); view.Root.test(); //这里执行了扩展类的test方法,会输出一个“test” //Root表示的才是View的实体GComponent,CreateView返回的并不是FGUI的类,而是引擎GUI类下的UIView类
注意:如果组件A只是一个普通的组件,没有定义“扩展”,那么基类是GComponent,如上例所示;如果组件UIView_Test
的FGUI编辑器内扩展是按钮
,那么MyButton
的基类应该为GButton
,如果扩展是进度条
,那么基类应该为GProgressBar
以此类推。这个千万不能弄错,否则会出现报错。
有关FairyGUI更多代码定义和内容,请访问https://www.fairygui.com/docs/editor 查看。
📒 加载自定义字体
在当前版本下,目前仅支持使用用户本地系统字体、沙盘引擎内置字体,暂不支持通过资源的方式导入字体。
全局字体需要在加载模组之前进行设置,需要在Mod/Mod.json
配置文件提前设定,并使用标准的字体名称标识。
注意:不同用户本地系统存在的字体并不统一,有可能A用户存在AAA字体,但B用户系统没有安装此字体,这样的话实现的效果将不会达到预期。
沙盘引擎内置了数个优秀字体(免费+可商用),如需使用引擎内置字体,请填写《参考文档》内的字体标示名称。
📒 默认UI设定
对于一些UI全局的设定内容(如字体、原生组件)等需要在模组加载之前进行修改,如果有这些内容的修改需求,可以在模组目录下的Mod.json
进行设定。