meta data for this page
  •  

📚 差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
developer:extend:gui [2024/08/10 04:08] – 移除 - 外部编辑 (Unknown date) 127.0.0.1developer:extend:gui [2024/08/10 04:08] (当前版本) – ↷ 页面developer:function:gui被移动至developer:extend:gui bibiboxs
行 1: 行 1:
 +<markdown>
 +# GUI功能参考
  
 +在沙盘引擎中,有关GUI的功能分成两个部分,分别是`FairyGUI模板`与`NativeGUI`组成。
 +
 +沙盘引擎**默认使用[FairyGUI](https://www.fairygui.com/)**作为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源文件放到模组中**。
 +
 +[note3]
 +**注意:请保持默认格式的导出文件命名(`package_fui.bytes | package_xxx.png`),否则引擎可能无法正确识别GUI数据。**
 +[/note]
 +
 +
 +
 +### 模组GUI翻译文件
 +
 +> 如果模组GUI不需要用到多语言翻译功能,可以忽略此部分。
 +
 +如果开发模组拥有**FairyGUI多语言文件(.xml)**,只需将语言文件导出到`Mod/Language`目录下(FairyGUI机制:所有包共用一个`xml`语言文件),引擎在载入新场景时会自动导入翻译。
 +
 +关于语言适配详情参考[《游戏多语言适配》](developer/mod/language)。
 +
 +
 +
 +### 通过脚本进行使用
 +
 +> 当开发者将GUI文件导出到模组GUI目录后,模组将会在下次载入场景时自动导入GUI资源。
 +
 +> 因此,在导入GUI后如需使用,至少应该重载场景或载入新的场景进行更新。
 +
 +```javascript
 +//使用此方法创建一个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代码方式](https://fairygui.com/docs/unity "FairyGUI代码方式")来使用。
 +
 +
 +
 +## GUI脚本扩展类
 +[note3]
 + **注意:此功能在开发版本中暂时关闭,当前版本中暂不可用。**
 +[/note]
 +
 +> **此项内容比较重要,建议开发者可以参考,可能会对开发UI事半功倍。**
 +
 +在GUI的制作过程中,经常会遇到某些附带功能且经常被复用的组件,比如说背包系统的背包格子,按照传统的方式可能需要每次建立一个格子就得绑定“此UI的文本、图片等引用”,哪怕是自行封装一个方法也仍然会比较麻烦。
 +
 +GUI类延续了FairyGUI的`UIObjectFactory.SetPackageItemExtension`方法,并根据需要对其封装成了`GUI.BindExtend`方法。
 +
 +**使用此功能,开发者可以为某个GUI组件绑定一个扩展类,绑定的类负责此组件的全部生命周期事件,这样可以对一些复杂或频繁复用的UI组件更清晰的开发。**
 +
 +```javascript
 +//需要在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用户系统没有安装此字体,这样的话实现的效果将不会达到预期。
 +>
 +> ==沙盘引擎内置了数个优秀字体(免费+可商用),如需使用引擎内置字体,请填写[《参考文档》](https://docs.qq.com/sheet/DQUNkY3ZpWWFxSU1o?tab=2dpoj5)内的**字体标示名称**。==
 +
 +
 +
 +## 默认UI设定
 +
 +对于一些UI全局的设定内容(如**字体**、原生组件)等需要在模组加载之前进行修改,如果有这些内容的修改需求,可以在模组目录下的`Mod.json`进行设定。
 +
 +
 +
 +</markdown>