V0.39.0.0 Release Note
注意事项
1.Blank工程优化
Blank工程中新增一批通用UI文件,包括创建角色/排行榜/设置/商店等界面,欢迎使用或者制作UI时作为参考
一、编辑器交互及发版策略
[优化]视图管理器优化
- 视图选择器方向和代码定义方向统一,MW编辑器采用的是左手坐标系,定义如下:
X轴正方向为前,X轴负方向为后。
Y轴正方向为右,Y轴负方向为左。
Z轴正方向为上,Z轴负方向为下。
进入工程场景时,摄像机默认方向为“X轴正方向”。
- 视图选择器样式色彩和Transform Gizmo色彩统一。
- 在工具栏【显示】选项中,新增视图选择器的显示开关。
[优化]启动工程进度优化、编译进度优化
Loading从弹窗改为全屏,增加背景图、小贴士信息。
丰富启动工程进度细节,在右下角显示较为详细的进度说明,并提供动态表现。(可以通过这个动态来判断进程是否有卡住)
工程内弹窗编译,丰富编译进度和细节。
[新增]材质编辑面板
材质子编辑器移除,改为“材质编辑面板”。
入口:①属性面板——材质资源编辑按钮 ②工程内容——材质中双击材质分页进行开启。
优化前 优化后
注意
因为材质编辑面板更专注于提供材质属性的调整,故现在需要依附于主视口中的对象进行展示。
建议大家在调整材质时,先将材质拖至某个易于观察的对象后,再进行修改(可以根据需求配合“对象聚焦”功能(F键)使用)。
主要功能
高级属性开关:开启后可以调整更多专业性更高的参数,默认关闭。
保存&另存:
- 有数据修改时,按钮可点击,点击后将修改的数据另存为新材质文件(材质目录下)
- 另存时材质分页为场景,则存至场景目录;为公共,则存至公共目录。
- 另存时将自动保存至工程内容——材质路径下,命名为“自定义材质”+“序号”。
- 有数据修改时,按钮可点击,点击后将修改的数据另存为新材质文件(材质目录下)
全部重置:
- 无数据修改时,重置按钮置灰
- 有数据修改时,重置按钮可点击,点击后重置为最后一次保存的数据
显示优化
显示结构从分页显示,改为父子结构,简化查看不同分页间的交互链路。
优化前 优化后 材质属性多合一:将占用多行的属性,合并成一行,例如平铺率、偏移、流动效果等。
优化前 优化后 面板的窗口特性:
- 窗口始终位于主编辑器窗口层级之上。
- 关闭窗口时,保存窗口的当时的尺寸和位置,下次打开时使用保存的窗口位置。
- 同一时间只能打开一个材质编辑面板,打开新的材质文件时将替换为新的材质文件的数据。
- 属性面板材质属性分组中新增不透明度、覆盖颜色属性
不透明度:模型整体不透明度。当属性值为0时模型完全不可见;当属性值为1时模型完全不透明。
覆盖颜色:插槽当前的颜色。该颜色会覆盖材质里面颜色的效果。随材质槽位切换而切换。
- 材质从“资源库”或“工程内容”拖入主视口时,将支持同时替换多个选中对象
- 材质编辑面板中的“取色器”面板新增强度属性交互控件
- 取色器面板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(): LanguageCodeType LanguageCodeType - - - - 仅客户端 本地化窗口的机器翻译按钮新增了一个下拉选项,支持选择要翻译哪些种类的语言
为了引导大家注意使用自适应文本框的最大/最小字体大小功能,UI编辑器内新建文本框最大字体大小默认值调整为57,最小字体大小默认值调整为15;不会影响动态创建文本框和旧版本创建的文本框
二、UI 编辑器新增功能及 API 更新
[新增]UI控件新增自定义属性
UI控件新增自定义属性,属性面板上可以新增/修改/移除自定义属性,运行时可以通过API新增/修改自定义属性,但不能移除
<Class><Widget>
- 控件
属性
属性含义 | 属性名 | 类型 | 默认值 | 取值范围 | 说明 |
---|---|---|---|---|---|
自定义属性修改 | onCustomPropertyChange | MulticastDelegate<(path: string, value: unknown, oldValue: unknown) => void> | - | - | 在自定义属性修改后执行绑定函数。path:当属性为基本类型的时候返回属性名value:属性新值oldValue:属性旧值 |
方法
功能说明 | 方法名 | 返回类型 | 输入说明 | 输入值范围 | 输出说明 | 输出值范围 | 使用域 |
---|---|---|---|---|---|---|---|
设置自定义属性的值 | setCustomProperty(propertyName: string,value: CustomPropertyType): void | void | propertyName自定义属性名字value属性值 | - | - | - | 仅客户端 |
获取自定义属性的值 | getCustomProperty(propertyName: string): CustomPropertyType | any | propertyName自定义属性名字 | - | 对象自定义属性的值 | - | 仅客户端 |
获取自定义属性名字数组 | getCustomProperties(): Array string | Array string | - | - | 对象所有自定义属性的Map,key是自定义属性名,value是属性值。 | - | 仅客户端 |
获取给定自定义属性修改时触发的事件代理。 | getCustomPropertyChangeDelegate(customProperty: string): MulticastDelegate | MulticastDelegate(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
角色数据支持按照更详细的分类组合存储,并优化保存和另存弹窗的交互。
本次角色数据存储拆分的功能优化分为三部分:
- 保存时支持快捷选择 完整角色 和 套装服饰 。保存后可直接上传到资源库对应的完整角色和套装服饰分类中。
- 新增角色数据预览窗口,选择需要保存的角色数据分类后,根据勾选的分类在窗口中预览效果。
- 角色数据支持根据更详细的分类进行组合保存。
角色分类所对应的角色数据如下:
拆分前 | 拆分后 |
分类名称 | 对应数据 |
---|---|
角色主体->角色主Mesh。 | |
头部->头部相关中的头部和捏脸数据。 | |
身体->身体相关中的捏体数据。 | |
化妆-肤色->化妆分类中的整体肤色。 | |
化妆-面部->化妆分类中的面部贴花。 | |
化妆-身体->化妆分类中的身体贴花。 |
[新增]天空球背景偏移属性
在之前Z轴偏移的基础上,新增X轴偏移和Y轴偏移属性
[新增]环境光遮蔽开关
后处理的属性面板中可自定义是否开启环境光遮蔽,若开启,环境光遮蔽强度和环境光遮蔽半径参数显示在属性面板中且可调节;若关闭,环境光遮蔽强度和环境光遮蔽半径两个参数不显示在属性面板中。
API
<Class><PostProcess>
- 后处理
静态成员属性
属性含义 | 属性名 | 类型 | 默认值 | 取值范围 | 说明 | 读写 | 使用域 |
---|---|---|---|---|---|---|---|
启用AO | ambientOcclusionEnabled | boolean | true | - | AO功能开关,默认值为true,开启环境光遮蔽效果。 | 可读可写 | 仅客户端可用 |
调整AO半径 | ambientOcclusionRadius | number | 50.00 | 0-100 | 设置环境光遮蔽半径,数值越大,半径越大 | 可读可写 | 仅客户端可用 |
调整AO强度 | ambientOcclusionIntensity | number | 0.60 | 0-1 | 数值越大,强度越大 | 可读可写 | 仅客户端可用 |
- 在【PostProcess】的【属性面板】中
可开关环境光遮蔽效果 | 开启状态下暴露两个可调节环境光遮蔽强度和半径的参数 |
注意事项:
画质分级1-6级环境光遮蔽效果在场景中不显示,画质分级7-9则默认开启环境光遮蔽效果,可通过后处理属性面板自行关闭。
[新增]多场景共用资源功能
背景:
同一个项目中的多个子场景通常会用到一些完全相同工程文件(包括脚本、UI文件等),此前需要在各个场景路径中处理多份文件,例如场景a中用了x1脚本,场景b中用了x2脚本,x1和x2实际上完全相同,如果在x1脚本中修改了一段代码,还需要手动修改场景b中的x2脚本,才能让改动对场景b生效,比较麻烦
因此,编辑器在039上提供了多场景共用资源功能,共用资源可以被每个子场景引用,并且只存在一份文件
工程内容顶部的下拉选项中可以设置展示场景资源/共用资源;在右键菜单中可以将该资源设置为场景资源or共用资源,该操作会把该资源移动到对应场景/共用路径的最外层,不会修改资源的内部信息(包括Asset ID);将文件夹设置为场景资源/共用资源时,文件夹内所有的资源都将会一起设置过去
四类本地资源(声音、UI贴图、场景贴图、静态模型)只存放在共用资源中
导入资源时,取决于工程内容顶部的下拉选项当前选择的是场景资源/共用资源,就导入为哪种资源;四种本地资源固定导入到共用资源
共用资源存放在项目路径中的common文件夹内,common文件夹与子场景文件夹同级
编辑器/TS脚本中使用共用资源Asset ID时的注意事项:
- 包括属性面板中挂脚本/UI文件(记录在level文件),UI文件Root中挂脚本,UI文件中引用其他UI文件作为自定义UI文件等情况
- 如果存在Asset ID相同的场景和共用资源,会优先引用场景资源
- 每次重新进入项目时,编辑器会检测一次是否存在Asset ID重复冲突的情况,冲突资源会展示红色标识,并且弹出弹窗(由于检测耗时较高,目前只会在进入项目时刷新一次标识状态)
发生Asset ID重复冲突的解决方法:
可以删除冲突的共用资源或者场景资源,只保留一份文件
可以找到冲突的共用资源,使用右键菜单-重新生成Asset ID,为其重新赋予不同的Asset ID,之后给使用到该资源的地方重新配置一次,保证编辑器能用新的Asset ID找到此共用资源
也可以不处理,但是要注意编辑器会优先引用同Asset ID的场景资源
TS脚本中通过路径引用共用资源的注意事项:
包括脚本中引用脚本,脚本中用路径创建UI等情况
需要注意移动脚本之后,需要检查这个脚本引用或者被引用的脚本是否在同一路径下,如果路径有更改需要修改引用的路径名
其他注意事项:
游戏发布时,共用资源会放在每个场景的包体内,会导致每个场景的进入游戏时长以及内存增加,因此高复用率资源(最好是每个场景都要用到的)才应该被放到共用资源中
如果不需要使用共用资源,可以当成之前的多场景功能继续使用,只使用场景资源即可
只能场景资源引用共用资源,不允许反向引用
本次优化没有调整编译的逻辑,所有编译仍然仅编译当前打开的场景;包括修改共用资源后,也只会编译一次当前场景,剩余场景还需要各自手动编译。
[新增]模型碰撞是否影响寻路区域接口
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)限制,可以频繁设置
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端权威的项目写法)。
bUseAutonomousProxyAuthority | bAcceptAutonomousProxyRequest | 说明 |
---|---|---|
true | true | 角色服务端为准主控端调用同步 |
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
【插件管理】主要包含插件的导入导出、创建、编译、查询、加载卸载等功能已经对应完成事件。同时定义了“插件”这一对象的数据结构,囊括了插件的必要信息。
- 对象管理器 MainOutliner
【对象管理】主要针对主视口进行一个可视化管理,它可以对主视口存在的对象进行(取消)选中、查询、添加/删除/查询脚本、创建文件夹/合并对象/群组对象、添加/删除/查询预加载资源、设置对象的网络/锁定/可视状态、序列化和反序列化等多重操作,并给予对应事件进行监听
- 窗口 PluginWindow
【窗口】是一个系统层的概念,是承载各个逻辑功能的容器。它主要决定逻辑功能展示的布局以及对应的UI。它首先定义了窗口对象的数据结构包含类型、标题、状态、坐标、大小等。此外它具备聚焦/失焦、文字弹窗、提示弹窗、创建(组合)UI窗口、创建自定义窗口等多重功能,并支持在窗口中注册/注销各类功能tab,例如:
提示弹窗
文字弹窗
组合UI窗口
自定义窗口
- 视口 ViewPort
【视口】是一个游戏场景的抽象,它可以创建默认场景、操作默认摄像机、按需求截屏拍照、创建/删除/查询对象、绘制内容。主视口是一个特殊视口,作为编辑器的主场景对象保存为静态变量。此外视口还封装了许多插件用户输入事件例如鼠标移动、按键按下等,便于桥接用户操作和视口逻辑。
- 工程内容 ProjectContent
【工程内容】主要负责管理项目工程文件,资源。工程内容按左侧导览进行分类,使用WorkData
对象统一管理文件。模块包含内容搜集、导览 & 内容更新、资源导入导出、内容的增删改查等功能。
- 文件 File
【文件】主要负责定义对象的数据接口含路径信息、时间戳、读写权限、后缀、名称等。此外所有文件相关的操作均作为模块能力封装接口以供调用。它可以完成判断/打开/创建/删除/读写、打开对话框:打开文件/文件夹/保存文件、压缩/解压、复制/移动等常规文件操作。
- 菜单锚点 MenuAnchor
【菜单锚点】是编辑器封装的默认菜单控件,插件用户可以打开/关闭菜单、动态添加/删除菜单项、设置打开位置和打开方式。此外还可以自定义部分暴露的UI参数例如最大列表长度。
- 快捷键 Shortcut
【快捷键】主要负责操作全局快捷键映射和UI快捷键映射。可以用于添加/移除快捷键(含编辑器内置)。
[新增]模型:“开启碰撞”支持touch事件
运行时执行逻辑model.touchEnabled = true
即可开启模型touch能力,从而支持onTouch
和onTouchEnd
事件的监听。需注意当角色移动以客户端为准时,最好在客户端进行touch事件的监听,此时服务器仅被动接受客户端移动的最终结果,可能并未产生碰撞。
四、游戏功能对象新增功能及 API 更新
[优化]点光源效果优化
- 解决了部分角色皮肤被点光源照亮时,不受点光源衰减指数影响的问题表现
- 统一各材质次表面散射效果,材质的在逆光侧也会有一定的透光效果,使得点光源效果更加协调一致
优化后 | 优化前 |
---|---|
[优化]寻路区域参数设置位置
将寻路区域参数从寻路区域逻辑对象属性面板移到到世界设置中;
五、材质更新
[优化]角色服装动态黑面问题
针对角色服饰遇到黑面穿帮的问题(动态骨骼服装严重)进行修复
优化前 | 优化后 |