Skip to content
V0.39.0.0 Release Note

V0.39.0.0 Release Note

注意事项

1.Blank工程优化

Blank工程中新增一批通用UI文件,包括创建角色/排行榜/设置/商店等界面,欢迎使用或者制作UI时作为参考

一、编辑器交互及发版策略

[优化]视图管理器优化

  1. 视图选择器方向和代码定义方向统一,MW编辑器采用的是左手坐标系,定义如下:

imgimgimg

  • X轴正方向为前,X轴负方向为后。

  • Y轴正方向为右,Y轴负方向为左。

  • Z轴正方向为上,Z轴负方向为下。

  • 进入工程场景时,摄像机默认方向为“X轴正方向”。

  1. 视图选择器样式色彩和Transform Gizmo色彩统一。

img

  1. 在工具栏【显示】选项中,新增视图选择器的显示开关。
img

[优化]启动工程进度优化、编译进度优化

Loading从弹窗改为全屏,增加背景图、小贴士信息。

img

丰富启动工程进度细节,在右下角显示较为详细的进度说明,并提供动态表现。(可以通过这个动态来判断进程是否有卡住)

工程内弹窗编译,丰富编译进度和细节。

[新增]材质编辑面板

  1. 材质子编辑器移除,改为“材质编辑面板”。

    入口:①属性面板——材质资源编辑按钮 ②工程内容——材质中双击材质分页进行开启。

    imgimg
    优化前优化后

注意

因为材质编辑面板更专注于提供材质属性的调整,故现在需要依附于主视口中的对象进行展示。

建议大家在调整材质时,先将材质拖至某个易于观察的对象后,再进行修改(可以根据需求配合“对象聚焦”功能(F键)使用)。

  • 主要功能

    • 高级属性开关:开启后可以调整更多专业性更高的参数,默认关闭。

      img
    • 保存&另存:

      • 有数据修改时,按钮可点击,点击后将修改的数据另存为新材质文件(材质目录下)
        • 另存时材质分页为场景,则存至场景目录;为公共,则存至公共目录。
        • 另存时将自动保存至工程内容——材质路径下,命名为“自定义材质”+“序号”。

      img

    • 全部重置:

      • 无数据修改时,重置按钮置灰
      • 有数据修改时,重置按钮可点击,点击后重置为最后一次保存的数据
  • 显示优化

    • 显示结构从分页显示,改为父子结构,简化查看不同分页间的交互链路。

      imgimg
      优化前优化后
    • 材质属性多合一:将占用多行的属性,合并成一行,例如平铺率、偏移、流动效果等。

    imgimg
    优化前优化后
  • 面板的窗口特性:

    • 窗口始终位于主编辑器窗口层级之上。
    • 关闭窗口时,保存窗口的当时的尺寸和位置,下次打开时使用保存的窗口位置。
    • 同一时间只能打开一个材质编辑面板,打开新的材质文件时将替换为新的材质文件的数据。
  1. 属性面板材质属性分组中新增不透明度覆盖颜色属性
img

不透明度:模型整体不透明度。当属性值为0时模型完全不可见;当属性值为1时模型完全不透明。

覆盖颜色:插槽当前的颜色。该颜色会覆盖材质里面颜色的效果。随材质槽位切换而切换。

  1. 材质从“资源库”或“工程内容”拖入主视口时,将支持同时替换多个选中对象

  1. 材质编辑面板中的“取色器”面板新增强度属性交互控件
img
  • 取色器面板RGBA下方新增强度交互控件,可以通过拖拽滑动条快速调整RGB三值的乘算倍率,提高做自发光等设置时的交互易用性。
    • 乘算倍率默认值1,区间0.1~10,后方的输入框中支持手动输入更大的数值。
    • 进行乘算后关闭面板或点击确定均将会使用该乘算倍率乘算至RGB三值中进行保存和记录。

[新增]项目发布/更新时引导完成本地化适配

  • 未做本地化适配的项目在发布/更新时,会跳转到本地化菜单,进行自动收集文本;随后需要手动选择原文本语言种类,点击翻译按钮进行机翻,翻译完成后点击应用即可完成一次初版的游戏本地化
    • 项目必须含有本地化表格并且包括简中/英语/日语/韩语四种语言的翻译文本,才能通过检测成功发布/更新
    • 如果是已经在使用本地化功能的项目,不会受到影响,继续正常使用即可
    • 如果已经有整理好的多语言表格,推荐使用导入功能直接导入,更多信息请查看产品手册:游戏本地化 | 产品手册

  • 通过以上初版本地化流程之后,还需要进行人工校验和调整,如果平台审核游戏时发现简中/英语/日语/韩语四种重点语言的翻译有缺失,或者翻译后UI效果过差,游戏无法通过审核不能上线,以下几种情况需要额外注意:

    • a.动态拼接或者带占位符的文本,例如游戏中要显示【我有1000个金币】,如果编辑器自动收集到的文本是规范的带占位符文本【我有{0}个金币】,那么游戏中能正常匹配到,但如果编辑器自动收集的是【我有】和【个金币】,然后脚本动态拼接组成的【我有1000个金币】,这种情况没法匹配到,会显示原文本;以及要注意检查带占位符的文本机翻之后的语序是否正确
    • b.UI显示问题,同一段文本内容翻译到各种语言后的长度会有较大差别,如果文本变长会导致超框,需要注意开启文本框的自适应功能并设置合适的字号范围,以及注意控制各种翻译文本的长度,或者调整UI排版,为文本展示留出充足空间
    • c.带文本的图片,需要准备多个语言版本的图片(至少要求简中之外的语言能显示英文图片),并把这些Asset ID填到多语言表里,在游戏运行时使用LanguageUtil.getText读取当前语言应使用的Asset ID,再设置到图片上
    • d.打字机效果,如果游戏中制作了逐个字符展示的打字机效果,直到显示完整文本才会被检测替换,打字过程中会露出来原语言;正确做法是使用LanguageUtil.getText接口获取翻译文本来做打字机效果
  • 其他相关改动有:

    • 新增一个获取当前正在展示的语言种类的方法,以下情况都会影响到该接口获取的值:

      • editor启动游戏时,自动根据设置菜单中的预览语言设置了游戏语言
      • 移动端启动游戏时,自动根据app语言设置了游戏语言
      • 运行时使用setLanguage修改了游戏语言
    • <LanguageUtil>类新增方法

    • 功能说明方法名返回类型输入说明输入值范围输出说明输出值范围使用域
      获取当前游戏语言种类static getLanguage(): LanguageCodeTypeLanguageCodeType----仅客户端

      本地化窗口的机器翻译按钮新增了一个下拉选项,支持选择要翻译哪些种类的语言

      img

      为了引导大家注意使用自适应文本框的最大/最小字体大小功能,UI编辑器内新建文本框最大字体大小默认值调整为57,最小字体大小默认值调整为15;不会影响动态创建文本框和旧版本创建的文本框

img

二、UI 编辑器新增功能及 API 更新

[新增]UI控件新增自定义属性

UI控件新增自定义属性,属性面板上可以新增/修改/移除自定义属性,运行时可以通过API新增/修改自定义属性,但不能移除

img

<Class><Widget> - 控件

属性

属性含义属性名类型默认值取值范围说明
自定义属性修改onCustomPropertyChangeMulticastDelegate<(path: string, value: unknown, oldValue: unknown) => void>--在自定义属性修改后执行绑定函数。path:当属性为基本类型的时候返回属性名value:属性新值oldValue:属性旧值

方法

功能说明方法名返回类型输入说明输入值范围输出说明输出值范围使用域
设置自定义属性的值setCustomProperty(propertyName: string,value: CustomPropertyType): voidvoidpropertyName自定义属性名字value属性值---仅客户端
获取自定义属性的值getCustomProperty(propertyName: string): CustomPropertyTypeanypropertyName自定义属性名字-对象自定义属性的值-仅客户端
获取自定义属性名字数组getCustomProperties(): Array stringArray string--对象所有自定义属性的Map,key是自定义属性名,value是属性值。-仅客户端
获取给定自定义属性修改时触发的事件代理。getCustomPropertyChangeDelegate(customProperty: string): MulticastDelegateMulticastDelegate(path: string, value: unknown, oldValue: unknown) => void>customProperty自定义属性名字-给定自定义属性修改时触发的事件代理path:当属性为基本类型的时候返回属性名value:属性新值oldValue:属性旧值-仅客户端

脚本示例:

TypeScript
    let jumpBtn = this.uiWidgetBase.findChildByPath('RootCanvas/Button_Jump') as Button
    jumpBtn.setCustomProperty(propertyName, val);
    console.log("val " + jumpBtn.getCustomProperty(propertyName));
    jumpBtn.getCustomProperties().forEach((v) => {
        console.log("custom property " + v);
    });
    //监听所有自定义属性同步回调
    jumpBtn.onCustomPropertyChange.add((path, val, oldVal) => {
        console.error("onCustomPropertyChange");
        console.error("--path " + path + " --val " + val + " --oldVal " + oldVal);
    });
    
    //监听某个自定义属性同步回调
    let d = jumpBtn.getCustomPropertyChangeDelegate(propertyName);
    d.clear();
    d.add((path, val, oldVal) => {
        console.error("getCustomPropertyChangeDelegate");
        console.error("--path " + path + " --val " + val + " --oldVal " + oldVal);
    });
    let jumpBtn = this.uiWidgetBase.findChildByPath('RootCanvas/Button_Jump') as Button
    jumpBtn.setCustomProperty(propertyName, val);
    console.log("val " + jumpBtn.getCustomProperty(propertyName));
    jumpBtn.getCustomProperties().forEach((v) => {
        console.log("custom property " + v);
    });
    //监听所有自定义属性同步回调
    jumpBtn.onCustomPropertyChange.add((path, val, oldVal) => {
        console.error("onCustomPropertyChange");
        console.error("--path " + path + " --val " + val + " --oldVal " + oldVal);
    });
    
    //监听某个自定义属性同步回调
    let d = jumpBtn.getCustomPropertyChangeDelegate(propertyName);
    d.clear();
    d.add((path, val, oldVal) => {
        console.error("getCustomPropertyChangeDelegate");
        console.error("--path " + path + " --val " + val + " --oldVal " + oldVal);
    });

三、编辑器新增功能及 API 更新

[新增]后处理-泛光效果

增加后处理-泛光参数,并提供相应的API在运行时进行设置

TypeScript
PostProcess.bloom = 3  //设置泛光强度
PostProcess.bloomExposureFactor = 1 //设置泛光曝光系数
PostProcess.bloomRange = 2 //设置泛光范围
PostProcess.bloomSpread = 1 //设置泛光扩散度
PostProcess.bloom = 3  //设置泛光强度
PostProcess.bloomExposureFactor = 1 //设置泛光曝光系数
PostProcess.bloomRange = 2 //设置泛光范围
PostProcess.bloomSpread = 1 //设置泛光扩散度

[优化]角色数据存储拆分

TIP

角色数据支持按照更详细的分类组合存储,并优化保存和另存弹窗的交互。

本次角色数据存储拆分的功能优化分为三部分:

  1. 保存时支持快捷选择 完整角色套装服饰 。保存后可直接上传到资源库对应的完整角色和套装服饰分类中。
  2. 新增角色数据预览窗口,选择需要保存的角色数据分类后,根据勾选的分类在窗口中预览效果。
  3. 角色数据支持根据更详细的分类进行组合保存。

img

角色分类所对应的角色数据如下:

imgimg
拆分前拆分后
分类名称对应数据
角色主体->角色主Mesh。img
头部->头部相关中的头部和捏脸数据。img
身体->身体相关中的捏体数据。img
化妆-肤色->化妆分类中的整体肤色。img
化妆-面部->化妆分类中的面部贴花。img
化妆-身体->化妆分类中的身体贴花。img

[新增]天空球背景偏移属性

在之前Z轴偏移的基础上,新增X轴偏移和Y轴偏移属性

img

[新增]环境光遮蔽开关

后处理的属性面板中可自定义是否开启环境光遮蔽,若开启,环境光遮蔽强度和环境光遮蔽半径参数显示在属性面板中且可调节;若关闭,环境光遮蔽强度和环境光遮蔽半径两个参数不显示在属性面板中。

API

<Class><PostProcess> - 后处理

静态成员属性

属性含义属性名类型默认值取值范围说明读写使用域
启用AOambientOcclusionEnabledbooleantrue-AO功能开关,默认值为true,开启环境光遮蔽效果。可读可写仅客户端可用
调整AO半径ambientOcclusionRadiusnumber50.000-100设置环境光遮蔽半径,数值越大,半径越大可读可写仅客户端可用
调整AO强度ambientOcclusionIntensitynumber0.600-1数值越大,强度越大可读可写仅客户端可用
  • 在【PostProcess】的【属性面板】中
imgimg
可开关环境光遮蔽效果开启状态下暴露两个可调节环境光遮蔽强度和半径的参数

注意事项:

画质分级1-6级环境光遮蔽效果在场景中不显示,画质分级7-9则默认开启环境光遮蔽效果,可通过后处理属性面板自行关闭。

[新增]多场景共用资源功能

背景:

同一个项目中的多个子场景通常会用到一些完全相同工程文件(包括脚本、UI文件等),此前需要在各个场景路径中处理多份文件,例如场景a中用了x1脚本,场景b中用了x2脚本,x1和x2实际上完全相同,如果在x1脚本中修改了一段代码,还需要手动修改场景b中的x2脚本,才能让改动对场景b生效,比较麻烦

因此,编辑器在039上提供了多场景共用资源功能,共用资源可以被每个子场景引用,并且只存在一份文件

  • 工程内容顶部的下拉选项中可以设置展示场景资源/共用资源;在右键菜单中可以将该资源设置为场景资源or共用资源,该操作会把该资源移动到对应场景/共用路径的最外层,不会修改资源的内部信息(包括Asset ID);将文件夹设置为场景资源/共用资源时,文件夹内所有的资源都将会一起设置过去

  • 四类本地资源(声音、UI贴图、场景贴图、静态模型)只存放在共用资源中

  • 导入资源时,取决于工程内容顶部的下拉选项当前选择的是场景资源/共用资源,就导入为哪种资源;四种本地资源固定导入到共用资源

    imgimg
  • 共用资源存放在项目路径中的common文件夹内,common文件夹与子场景文件夹同级

img

编辑器/TS脚本中使用共用资源Asset ID时的注意事项:

  • 包括属性面板中挂脚本/UI文件(记录在level文件),UI文件Root中挂脚本,UI文件中引用其他UI文件作为自定义UI文件等情况
  • 如果存在Asset ID相同的场景和共用资源,会优先引用场景资源
  • 每次重新进入项目时,编辑器会检测一次是否存在Asset ID重复冲突的情况,冲突资源会展示红色标识,并且弹出弹窗(由于检测耗时较高,目前只会在进入项目时刷新一次标识状态)

发生Asset ID重复冲突的解决方法:

  • 可以删除冲突的共用资源或者场景资源,只保留一份文件

  • 可以找到冲突的共用资源,使用右键菜单-重新生成Asset ID,为其重新赋予不同的Asset ID,之后给使用到该资源的地方重新配置一次,保证编辑器能用新的Asset ID找到此共用资源

  • 也可以不处理,但是要注意编辑器会优先引用同Asset ID的场景资源

    imgimg

TS脚本中通过路径引用共用资源的注意事项:

  • 包括脚本中引用脚本,脚本中用路径创建UI等情况

  • 需要注意移动脚本之后,需要检查这个脚本引用或者被引用的脚本是否在同一路径下,如果路径有更改需要修改引用的路径名

    imgimg

其他注意事项:

  • 游戏发布时,共用资源会放在每个场景的包体内,会导致每个场景的进入游戏时长以及内存增加,因此高复用率资源(最好是每个场景都要用到的)才应该被放到共用资源中

  • 如果不需要使用共用资源,可以当成之前的多场景功能继续使用,只使用场景资源即可

  • 只能场景资源引用共用资源,不允许反向引用

  • 本次优化没有调整编译的逻辑,所有编译仍然**仅编译当前打开的场景;**包括修改共用资源后,也只会编译一次当前场景,剩余场景还需要各自手动编译,可以使用以下路径的一键编译脚本(会在后续版本增加编辑器内一键编译多个场景的功能)

    img

[新增]模型碰撞是否影响寻路区域接口

TypeScript
//模型碰撞不影响寻路导航数据构建
model.canAffectNavigation = false;
//模型碰撞不影响寻路导航数据构建
model.canAffectNavigation = false;

[优化]多人跳转到非公开房间优化

  • 此前版本中,使用RoomSettings.enableJoiningMidgame(true) 只会清理掉RoomSettings.enableJoiningMidgame(false) 的状态,本次优化后会也会一起清理掉跳转房间接口TeleportService.asyncTeleportToScene中的创建非公开房间createNewPrivateRoom的非公开状态
  • 多人跳转接口通过TeleportService.asyncTeleportToScene中的createNewPrivateRoom参数创建非公开房间时,userIds支持传入非在线玩家,这些玩家后续可以通过TeleportService.asyncTeleportToRoom指定房间跳转接口跳转过去(房间没满人且没有销毁的情况下)

[优化]prefab反序列化&同步时机改动

早前版本prefab在C端反序列化时机可能晚于对象同步时机,造成prefab对象在S端的改动同步至C端后又被反序列化的属性值给重新覆盖造成错误。本次针对prefab的任务时序改动在修复该问题的同时针对C端prefab进行分帧创建以平滑性能曲线。带来的影响是预制体中双端对象的属性同步可能慢于旧版本。

[新增]本地存储

本地容量限制:5MB

原有API

TypeScript
declare namespace mw {
    class DataStorage {
        static getDataSize(data: any): number;
        static asyncSetData(key: string, value: any): Promise DataStorageResultCode;
        static asyncGetData(key: string): Promise DataStorageResult;
        static asyncRemoveData(key: string): Promise DataStorageResultCode;
        
        //废弃
        //static setTemporaryStorage(isTemporary: boolean): void;
        
        static asyncGetOtherGameData(gameId: string, key: string): Promise DataStorageResult;
        static asyncSetOtherGameData(gameId: string, key: string, value: any): Promise DataStorageResultCode;
    }
}
declare namespace mw {
    class DataStorage {
        static getDataSize(data: any): number;
        static asyncSetData(key: string, value: any): Promise DataStorageResultCode;
        static asyncGetData(key: string): Promise DataStorageResult;
        static asyncRemoveData(key: string): Promise DataStorageResultCode;
        
        //废弃
        //static setTemporaryStorage(isTemporary: boolean): void;
        
        static asyncGetOtherGameData(gameId: string, key: string): Promise DataStorageResult;
        static asyncSetOtherGameData(gameId: string, key: string, value: any): Promise DataStorageResultCode;
    }
}

新增API - Client Only

TIP

由于本地存储将数据存储在本地,所以不受在线数据存储的有效存储间隔(6s)限制,可以频繁设置

img

TypeScript
declare namespace mw {
    
    class DataStorage {
        
        //设置本地数据
        static asyncSetLocalData(key: string, value: any): Promise DataStorageResultCode;
        
        //获取本地数据
        static asyncGetLocalData(key: string): Promise DataStorageResult;
        
        //删除本地数据
        static asyncRemoveLocalData(key: string): Promise DataStorageResultCode;
    
    }

}
declare namespace mw {
    
    class DataStorage {
        
        //设置本地数据
        static asyncSetLocalData(key: string, value: any): Promise DataStorageResultCode;
        
        //获取本地数据
        static asyncGetLocalData(key: string): Promise DataStorageResult;
        
        //删除本地数据
        static asyncRemoveLocalData(key: string): Promise DataStorageResultCode;
    
    }

}

[新增]网络配置:角色权威端为准 & 主控端调用同步

在**文件路径:**MetaWorldSaved\Saved\MetaWorld\Project\Edit[ProjectName]\Config\GameSetting.ini下:

  • 新增字段**bAcceptAutonomousProxyRequest**(接受主控端请求)
  • 原有字段**bUseAutonomousProxyAuthority**(主控端为准)

二者排列组合,支持角色新网络配置:角色服务端为准 & 主控端调用同步(兼容C端权威的项目写法)。

bUseAutonomousProxyAuthoritybAcceptAutonomousProxyRequest说明
truetrue角色服务端为准主控端调用同步
true-角色主控端为准
false-角色服务端为准

[新增]视图选择器Gizmo接口开放

TypeScript
class ViewGizmo extends mw.PanelWidget {
        /**
         * @groups 界面/控件/视图选择器
         * @description 点击视图面事件
         * @effect  只在客户端调用生效
         * @returns 返回事件的代理
         */
        get onClicked(): mw.MulticastDelegate<(face: GizmoCubeFace, rotation: mw.Rotation) => void>;
        /**
         * @groups 界面/控件/视图选择器
         * @description 拖拽开始
         * @effect  只在客户端调用生效
         * @returns 返回事件的代理
         */
        get onDragStart(): mw.Delegate<(absolutionPosition: mw.Vector2) => void>;
        /**
         * @groups 界面/控件/视图选择器
         * @description 拖拽结束
         * @effect  只在客户端调用生效
         * @returns 返回事件的代理
         */
        get onDragMove(): mw.Delegate<(absolutionPosition: mw.Vector2, Delta: mw.Vector2) => void>;
        /**
         * @groups 界面/控件/视图选择器
         * @description 拖拽结束
         * @effect  只在客户端调用生效
         * @returns 返回事件的代理
         */
        get onDragEnd(): mw.Delegate<(absolutionPosition: mw.Vector2) => void>;
        /** 设置视口选择器旋转 */
        bindViewRotation(fn: () => mw.Rotation): void;
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取视图选择器对应面的ImageInfo
         * @effect  只在客户端调用生效
         * @param face 要设置的gizmo立方体的面
         * @returns 返回ImageInfo对象
         */
        getViewGizmoImageInfo(face: GizmoCubeFace): mw.ImageInfo;
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取视图选择器边框的ImageInfo
         * @effect  只在客户端调用生效
         * @returns 返回ImageInfo对象
         */
        getViewGizmoFrameImageInfo(): mw.ImageInfo;
        /**
         * @groups 界面/控件/视图选择器
         * @description 创建 ViewGizmo 控件
         * @description 当parent和inName与已有的对象相同时,旧的对象会被销毁
         * @effect  只在客户端调用生效
         * @param parent usage:创建控件的外parent对象 default: null
         * @param inName usage:创建控件的名称 default:null   range:设置合理的名称即可
         * @returns 返回创建的对象
         */
        static newObject(parent?: mw.Canvas, inName?: string): ViewGizmo;
        /**
         * @groups 界面/控件/视图选择器
         * @description 设置点击事件触发模式
         * @effect  只在客户端调用生效
         * @param inTouchMethod usage:Touch模式选择
         */
        set touchMethod(inTouchMethod: mw.ButtonTouchMethod);
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取点击模式
         * @effect  只在客户端调用生效
         * @returns 点击模式选择
         */
        get touchMethod(): mw.ButtonTouchMethod;
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取轴文字大小
         * @effect  只在客户端调用生效
         */
        get fontSize(): number;
        /**
         * @groups 界面/控件/视图选择器
         * @description 设置轴文字大小
         * @effect  只在客户端调用生效
         * @param size usage:文字大小
         */
        set fontSize(size: number);
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取轴粗细
         * @effect  只在客户端调用生效
         */
        get lineThickness(): number;
        /**
         * @groups 界面/控件/视图选择器
         * @description 设置轴粗细
         * @effect  只在客户端调用生效
         * @param thickness usage:轴粗细
         */
        set lineThickness(thickness: number);
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取轴相对于视图选择器比例
         * @effect  只在客户端调用生效
         */
        get lineScale(): number;
        /**
         * @groups 界面/控件/视图选择器
         * @description 设置轴相对于视图选择器比例
         * @effect  只在客户端调用生效
         * @param scale usage:轴相对于视图选择器比例
         */
        set lineScale(scale: number);
        /**
         * @author maohang.zeng
         * @groups ViewGizmo
         * @description ViewGizmo方向
         */
        export enum GizmoCubeFace{
            /** 前面 */
            Front = 0,
            /** 左边 */
            Left,
            /** 右边 */
            Right,
            /** 背边 */
            Back,
            /** 顶部 */
            Top,
            /** 底部 */
            Bottom,
    }
class ViewGizmo extends mw.PanelWidget {
        /**
         * @groups 界面/控件/视图选择器
         * @description 点击视图面事件
         * @effect  只在客户端调用生效
         * @returns 返回事件的代理
         */
        get onClicked(): mw.MulticastDelegate<(face: GizmoCubeFace, rotation: mw.Rotation) => void>;
        /**
         * @groups 界面/控件/视图选择器
         * @description 拖拽开始
         * @effect  只在客户端调用生效
         * @returns 返回事件的代理
         */
        get onDragStart(): mw.Delegate<(absolutionPosition: mw.Vector2) => void>;
        /**
         * @groups 界面/控件/视图选择器
         * @description 拖拽结束
         * @effect  只在客户端调用生效
         * @returns 返回事件的代理
         */
        get onDragMove(): mw.Delegate<(absolutionPosition: mw.Vector2, Delta: mw.Vector2) => void>;
        /**
         * @groups 界面/控件/视图选择器
         * @description 拖拽结束
         * @effect  只在客户端调用生效
         * @returns 返回事件的代理
         */
        get onDragEnd(): mw.Delegate<(absolutionPosition: mw.Vector2) => void>;
        /** 设置视口选择器旋转 */
        bindViewRotation(fn: () => mw.Rotation): void;
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取视图选择器对应面的ImageInfo
         * @effect  只在客户端调用生效
         * @param face 要设置的gizmo立方体的面
         * @returns 返回ImageInfo对象
         */
        getViewGizmoImageInfo(face: GizmoCubeFace): mw.ImageInfo;
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取视图选择器边框的ImageInfo
         * @effect  只在客户端调用生效
         * @returns 返回ImageInfo对象
         */
        getViewGizmoFrameImageInfo(): mw.ImageInfo;
        /**
         * @groups 界面/控件/视图选择器
         * @description 创建 ViewGizmo 控件
         * @description 当parent和inName与已有的对象相同时,旧的对象会被销毁
         * @effect  只在客户端调用生效
         * @param parent usage:创建控件的外parent对象 default: null
         * @param inName usage:创建控件的名称 default:null   range:设置合理的名称即可
         * @returns 返回创建的对象
         */
        static newObject(parent?: mw.Canvas, inName?: string): ViewGizmo;
        /**
         * @groups 界面/控件/视图选择器
         * @description 设置点击事件触发模式
         * @effect  只在客户端调用生效
         * @param inTouchMethod usage:Touch模式选择
         */
        set touchMethod(inTouchMethod: mw.ButtonTouchMethod);
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取点击模式
         * @effect  只在客户端调用生效
         * @returns 点击模式选择
         */
        get touchMethod(): mw.ButtonTouchMethod;
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取轴文字大小
         * @effect  只在客户端调用生效
         */
        get fontSize(): number;
        /**
         * @groups 界面/控件/视图选择器
         * @description 设置轴文字大小
         * @effect  只在客户端调用生效
         * @param size usage:文字大小
         */
        set fontSize(size: number);
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取轴粗细
         * @effect  只在客户端调用生效
         */
        get lineThickness(): number;
        /**
         * @groups 界面/控件/视图选择器
         * @description 设置轴粗细
         * @effect  只在客户端调用生效
         * @param thickness usage:轴粗细
         */
        set lineThickness(thickness: number);
        /**
         * @groups 界面/控件/视图选择器
         * @description 获取轴相对于视图选择器比例
         * @effect  只在客户端调用生效
         */
        get lineScale(): number;
        /**
         * @groups 界面/控件/视图选择器
         * @description 设置轴相对于视图选择器比例
         * @effect  只在客户端调用生效
         * @param scale usage:轴相对于视图选择器比例
         */
        set lineScale(scale: number);
        /**
         * @author maohang.zeng
         * @groups ViewGizmo
         * @description ViewGizmo方向
         */
        export enum GizmoCubeFace{
            /** 前面 */
            Front = 0,
            /** 左边 */
            Left,
            /** 右边 */
            Right,
            /** 背边 */
            Back,
            /** 顶部 */
            Top,
            /** 底部 */
            Bottom,
    }

[新增]Editor插件一期

编辑器目前开放部分Editor模块插件功能,大家可以编写代码和设计GUI来对Editor功能进行修改和扩展。本次开放的模块包含:

  • 插件管理 PluginInfo

【插件管理】主要包含插件的导入导出、创建、编译、查询、加载卸载等功能已经对应完成事件。同时定义了“插件”这一对象的数据结构,囊括了插件的必要信息。

img
  • 对象管理器 MainOutliner

【对象管理】主要针对主视口进行一个可视化管理,它可以对主视口存在的对象进行(取消)选中、查询、添加/删除/查询脚本、创建文件夹/合并对象/群组对象、添加/删除/查询预加载资源、设置对象的网络/锁定/可视状态、序列化和反序列化等多重操作,并给予对应事件进行监听

img

  • 窗口 PluginWindow

【窗口】是一个系统层的概念,是承载各个逻辑功能的容器。它主要决定逻辑功能展示的布局以及对应的UI。它首先定义了窗口对象的数据结构包含类型、标题、状态、坐标、大小等。此外它具备聚焦/失焦、文字弹窗、提示弹窗、创建(组合)UI窗口、创建自定义窗口等多重功能,并支持在窗口中注册/注销各类功能tab,例如:

提示弹窗

img

文字弹窗

img

组合UI窗口

img

自定义窗口

img

  • 视口 ViewPort

【视口】是一个游戏场景的抽象,它可以创建默认场景、操作默认摄像机、按需求截屏拍照、创建/删除/查询对象、绘制内容。主视口是一个特殊视口,作为编辑器的主场景对象保存为静态变量。此外视口还封装了许多插件用户输入事件例如鼠标移动、按键按下等,便于桥接用户操作和视口逻辑。

img

  • 工程内容 ProjectContent

【工程内容】主要负责管理项目工程文件,资源。工程内容按左侧导览进行分类,使用WorkData对象统一管理文件。模块包含内容搜集、导览 & 内容更新、资源导入导出、内容的增删改查等功能。

img

  • 文件 File

【文件】主要负责定义对象的数据接口含路径信息、时间戳、读写权限、后缀、名称等。此外所有文件相关的操作均作为模块能力封装接口以供调用。它可以完成判断/打开/创建/删除/读写、打开对话框:打开文件/文件夹/保存文件、压缩/解压、复制/移动等常规文件操作。

  • 菜单锚点 MenuAnchor

【菜单锚点】是编辑器封装的默认菜单控件,插件用户可以打开/关闭菜单、动态添加/删除菜单项、设置打开位置和打开方式。此外还可以自定义部分暴露的UI参数例如最大列表长度。

img

  • 快捷键 Shortcut

快捷键】主要负责操作全局快捷键映射和UI快捷键映射。可以用于添加/移除快捷键(含编辑器内置)。

[新增]模型:“开启碰撞”支持touch事件

运行时执行逻辑model.touchEnabled = true即可开启模型touch能力,从而支持onTouchonTouchEnd事件的监听。需注意当角色移动以客户端为准时,最好在客户端进行touch事件的监听,此时服务器仅被动接受客户端移动的最终结果,可能并未产生碰撞。

四、游戏功能对象新增功能及 API 更新

[优化]点光源效果优化

  • 解决了部分角色皮肤被点光源照亮时,不受点光源衰减指数影响的问题表现
  • 统一各材质次表面散射效果,材质的在逆光侧也会有一定的透光效果,使得点光源效果更加协调一致
优化后优化前
imgimg
imgimg

[优化]寻路区域参数设置位置

将寻路区域参数从寻路区域逻辑对象属性面板移到到世界设置中;

img

五、材质更新

[优化]角色服装动态黑面问题

针对角色服饰遇到黑面穿帮的问题(动态骨骼服装严重)进行修复

imgimg
优化前优化后