提交 dd83c85e 编写于 作者: O oceanxiao

Update Design Document

上级 1be504ce
......@@ -2,7 +2,7 @@
0. 转换导出插件勾选"Profiling-funcs", 请勿使用Development(该模式将极大降低性能)。 发布上线版本请务必关闭该选项!
1. 在Android微信小游戏打开调试进行录制
<image src='../image/androidprofile1.png' width="300"/>
<img src='../image/androidprofile1.png' width="300"/>
2. 停止性能数据录制
......@@ -13,16 +13,16 @@
录制结束后,Android会生成一份xxx.cpuprofile,该文件格式可以使用chrome进行解析。
因此我们需要将录制后的文件传输到PC使用chrome进行分析。
文件路径通常为:Android/data/com.tencent.mm/MicroMsg/appbrand/trace
<image src='../image/androidprofile2.png' width="300"/>
<img src='../image/androidprofile2.png' width="300"/>
4. 利用PC(Windows/Mac)的chrome加载数据
<image src='../image/androidprofile3.png' width="500"/>
<img src='../image/androidprofile3.png' width="500"/>
5. 使用JavaScriptProfile进行数据分析
<image src='../image/androidprofile4.png' width="700"/>
<img src='../image/androidprofile4.png' width="700"/>
注意:
1. 编译版本仅当导出勾选Profiling-funcs(推荐)或Development时才能在函数堆栈中看到可读函数名。
......
......@@ -21,11 +21,11 @@
1. 新建一个云函数的空工程
云函数可以和前端的游戏逻辑独立创建为不同的项目。当然也可以在同一个项目中(project.config.json 中指定 cloudfunctionRoot,避免云函数代码被业务逻辑代码一同打包发布到外网),以下示例为独立项目的模式
<image src='../image/cf/init-cf-proj.jpg' width="800"/>
<image src='../image/cf/cf-overview.png' width="800"/>
<img src='../image/cf/init-cf-proj.jpg' width="800"/>
<img src='../image/cf/cf-overview.png' width="800"/>
2. 该小游戏首次使用云开发需要先开通云开发
<image src='../image/cf/open-cf.jpg' width="800"/>
<image src='../image/cf/cf-free.jpg' width="800"/>
<img src='../image/cf/open-cf.jpg' width="800"/>
<img src='../image/cf/cf-free.jpg' width="800"/>
> 云开发有一个基本的免费套餐,请求量达到一定上限后需要[配额调整](https://developers.weixin.qq.com/minigame/dev/wxcloud/billing/quota.html)或[申请代金券后更换配额套餐](https://developers.weixin.qq.com/minigame/dev/wxcloud/billing/voucher.html)
......@@ -84,9 +84,9 @@ exports.main = async (event, context) => {
4. 部署云函数
- 云函数可以同时存在多个环境(可自定义,如测试环境、生产环境。本示例为"product"),选中需要部署的云函数环境:
<image src='../image/cf/choose-env.jpg' width="800"/>
<img src='../image/cf/choose-env.jpg' width="800"/>
- 选中需要部署的云函数(本示例为"msgSecCheck"),点击“创建并部署:云端安装依赖”(本云函数仅依赖了 wx-server-sdk 模块,选云端安装依赖即可;若使用了其他第三方 node 模块,则需要选“创建并部署:所有文件”)
<image src='../image/cf/upload-cf.png' width="800"/>
<img src='../image/cf/upload-cf.png' width="800"/>
- 等云函数部署完成(看工具的提示),Console 可以输入调用云函数代码进行简单测试,或者右键云函数-开启云函数本地调试
```Javascript
......
......@@ -81,7 +81,7 @@ loadingPageConfig: {
## 默认效果
<image src='../image/loading_default.png' width="600">
<img src='../image/loading_default.png' width="600">
实现默认效果很简单,开发者只需在导出时配置启动素材即可
......@@ -98,12 +98,12 @@ loadingBarWidth: 加载进度条宽度;-- $LOADING_BAR_WIDTH
启动loader提供的默认加载界面为了契合不同游戏,做得相对通用,但游戏可能会存在定制启动loading的需求,以达到和游戏更贴近的体验。
- 小游戏表现
<image src='../image/loading_demo.jpg' width="600">
<img src='../image/loading_demo.jpg' width="600">
- 设计稿
设计尺寸:1600*720
<image src='../image/loading_design.jpg' width='600'>
<img src='../image/loading_design.jpg' width='600'>
- 小游戏配置
```js
......
......@@ -11,11 +11,11 @@
运行阶段点右上角->打开调试->出现vconsole
<image src='../image/debugexception4.png' width="800"/>
<img src='../image/debugexception4.png' width="800"/>
以文本方式打开导出目录/webgl/Build/xxx.symbols 文件
<image src='../image/debugexception5.png' width="800"/>
<img src='../image/debugexception5.png' width="800"/>
通过日志的函数id找到对应的原始函数名,分析调用堆栈。
这里有个[小工具](Symbol.md)可以帮助替换日志
......@@ -32,7 +32,7 @@
BuildSettings->Player Settings->Publish Settings->Enable Exceptions
选项表示 Unity 引擎捕捉哪种级别的异常
<image src='../image/debugexception1.png' width="800"/>
<img src='../image/debugexception1.png' width="800"/>
**什么是异常级别? 简单来说,就是确定哪些异常由引擎捕捉,未被捕捉的异常将抛给 WASM 虚拟机,最终会导致 VM 结束。**
......@@ -62,14 +62,14 @@ BuildSettings->Player Settings->Publish Settings->Enable Exceptions
异常捕捉:不捕捉任何异常,引擎或业务代码导致的异常都会抛出到 WASM,并导致程序 Crash。 该选项性能最高,但必须保证游戏不使用任何异常,**try catch 也无法捕捉任何异常**。从下图看到程序在第 1 个 Exception 产生时已终止,代码是无法 catch 该异常的。
异常信息:取决于虚拟机,在开发者工具有出现详细堆栈函数 ID,在真机环境则无。
<image src='../image/debugexception9.png'/>
<img src='../image/debugexception9.png'/>
**Explicitly Thrown Exceptions Only**
异常捕捉: 游戏代码的异常将被捕捉,如果非致命异常(不在关键路径上),逻辑代码可以继续。try catch 有效。
异常信息:Debug.Log 等函数等与程序未捕捉异常可输出简要的异常信息,无堆栈信息。
<image src='../image/debugexception8.png'/>
<img src='../image/debugexception8.png'/>
**Full Without Stacktrace**
......@@ -77,14 +77,14 @@ BuildSettings->Player Settings->Publish Settings->Enable Exceptions
Out of Bounds Array accesses“。
异常信息: Debug.Log 等函数与程序未捕捉异常都只有输出简要的异常信息,无堆栈信息。
<image src='../image/debugexception7.png'/>
<img src='../image/debugexception7.png'/>
**Full With Stacktrace**
异常捕捉: 同"Full Without Stacktrace"
异常信息: Debug.Log 等函数得到完整的堆栈,程序未捕捉异常有最浅层堆栈函数名。
<image src='../image/debugexception6.png'/>
<img src='../image/debugexception6.png'/>
注意:
......@@ -94,10 +94,10 @@ Out of Bounds Array accesses“。
BuildSettings->Player Settings->Publish Settings->DebugSymbols
<image src='../image/debugexception3.png' width="800"/>
<img src='../image/debugexception3.png' width="800"/>
Debug Symbols将产生函数id与函数名之间的映射关系,使用文本方式打开即可。 通常我们从异常log中找到函数id,此时可通过该文件找到C#源代码中的函数名。
### Development Build
<image src='../image/debugexception2.png' width="800"/>
<img src='../image/debugexception2.png' width="800"/>
Development Build会在异常产生时直接附带完整的函数名,与"Full With Stacktrace"类似,且程序未捕捉异常也有详细堆栈。该选项产生的代码体积较大,且对性能有较大影响。
......@@ -62,4 +62,4 @@ defaultReleaseSize: 清理时,默认额外清理的大小,单位Bytes,1MB
缓存文件在usr目录下
<image src='../image/cache_path.png'>
<img src='../image/cache_path.png'>
......@@ -4,7 +4,7 @@
本文描述Unity WebGL游戏运行过程中,如果遇到异常(业务代码、引擎)时开发者应该如何进行调试。
## 开启代码异常
<image src='../image/howtodebug1.png' width="600"/>
<img src='../image/howtodebug1.png' width="600"/>
> 默认情况下,使用“转换插件”这两个选项都已设置完成。
......@@ -39,7 +39,7 @@ python3 -m pip install brotli
2. 添加需要导出的scene
<image src='../image/scene.png' width="600"/>
<img src='../image/scene.png' width="600"/>
建议仅勾选Loading场景,后续场景使用AssetsBundle/Addressable进行按需加载。
......@@ -49,7 +49,7 @@ python3 -m pip install brotli
因为Mac上的隐私安全问题,使用mac的用户需要先授权,使用window的用户跳过这步。点击"微信小游戏"->"MacOS脚本授权",进行授权,直到不报错为止。若授权后还是报错,重启unity后再点授权试试。
2. 选择 点击 微信小游戏 -> 转换小游戏, 填写相应参数,点击`导出WEBGL并转换为小游戏`按钮 ,等待转换完成。
<image src='../image/export.png' width="600"/>
<img src='../image/export.png' width="600"/>
其中:
* 必须:appid 为 小游戏的Appid
......
......@@ -5,7 +5,7 @@
## Git Issue
开发者遇到BUG或者希望新增特性优先使用[Git Issue](https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues),因为这里可以更好进行问题沉淀、讨论与跟踪。
<image src='../image/issueandcontact1.png' />
<img src='../image/issueandcontact1.png' />
问题复现尽可能详细,包括以下内容:
* 操作步骤
......@@ -17,4 +17,4 @@
## 小游戏研发助手
开发者也可以通过“研发助手号”直接与小游戏团队进行技术交流
<image src='../image/issueandcontact2.jpg' width="200"/>
<img src='../image/issueandcontact2.jpg' width="200"/>
......@@ -11,8 +11,8 @@
数据入口:MP平台-用户反馈
当玩家游戏中出现问题时,进行功能反馈将会提交“用户反馈日志“,开发者可以在后台下载到对应数据:
<image src='../image/issueforproduction1.png' width="800"/>
<image src='../image/issueforproduction2.png' width="800"/>
<img src='../image/issueforproduction1.png' width="800"/>
<img src='../image/issueforproduction2.png' width="800"/>
该功能需要两个必要条件:
1. 玩家提交反馈
......@@ -31,7 +31,7 @@
[实时日志](https://developers.weixin.qq.com/miniprogram/dev/framework/realtimelog/)为帮助小程序开发者快捷地排查小程序漏洞、定位问题.
<image src='../image/issueforproduction3.png' width="800"/>
<img src='../image/issueforproduction3.png' width="800"/>
相对于用户反馈日志,小游戏实时日志**不需要用户反馈行为**
但需要开发者上报游戏关键节点信息与异常日志。
......@@ -41,7 +41,7 @@
数据入口:MP平台-开发管理-错误日志
微信小游戏框架会在顶层监控到任何**未捕捉的JS异常**
<image src='../image/issueforproduction4.png' width="800"/>
<img src='../image/issueforproduction4.png' width="800"/>
使用Unity WebGL转换方案的游戏通常会有这几种错误会产生:
......
......@@ -20,12 +20,12 @@ Unity WebGL内存结构可先参考:
[Unity博客:Unity WebGL 内存:Unity 堆 (Unity WebGL Memory: The Unity Heap)](https://blog.unity.com/technology/unity-webgl-memory-the-unity-heap)
<image src='../image/optimizationMemory1.png' width="1080"/>
<img src='../image/optimizationMemory1.png' width="1080"/>
Unity WebGL是以WebAssembly+WebGL技术为基础的应用,运行在浏览器环境,因此游戏内存的分配也是完全托管在这个环境中。
适配在小游戏后,小游戏进程也就成为了“容器”,虽然不再是标准的浏览器,但内存组成结构与上图基本一致,典型游戏的内存占用如下图所示:
<image src='../image/optimizationMemory10.png' width="800"/>
<img src='../image/optimizationMemory10.png' width="800"/>
- 基础库+Canvas:在小游戏环境中并不存在DOM,但依然会存在一些基本消耗,比如小游戏公共库,Canvas画布等。典型地,***小游戏公共库约占用内存100~150MB,Canvas 画布与设备物理分辨率相关***,比如iPhone 11 Promax占用约80MB。
......@@ -56,14 +56,14 @@ Unity WebGL是以WebAssembly+WebGL技术为基础的应用,运行在浏览器
- Android:WeChat AppBrand1/2
- iOS:普通模式WeChat、高性能模式(WebContent)
#### Instruments in Xcode(iOS)
<image src='../image/optimizationMemory2.png' width="800"/>
<img src='../image/optimizationMemory2.png' width="800"/>
使用“Activity Monitor”,选择对应的设备-all processes-捕捉,即可看到所有进程的CPU与内存情况.
<image src='../image/optimizationMemory3.png' width="800"/>
<img src='../image/optimizationMemory3.png' width="800"/>
#### Perfdog(Android or iOS)
使用[Perfdog](https://perfdog.qq.com)选择对应的设置-进程名,即可看到相关性能数据,iOS设备应以紫色的XcodeMemory为准。
<image src='../image/optimizationMemory4.png' width="800"/>
<img src='../image/optimizationMemory4.png' width="800"/>
### 3.2 UnityHeap
UnityHeap非常关键,典型由以下几部分组成:
......@@ -75,7 +75,7 @@ UnityHeap非常关键,典型由以下几部分组成:
1. 勾选转换面板"ProfilingMemory"
2. 代码中增加WeChatWASM.WX.OpenProfileStats显示性能面板(注意:提审版本请勿显示).
游戏左上角显示Performence Stats性能面板
<image src='../image/optimizationMemory6.jpg' width="600"/>
<img src='../image/optimizationMemory6.jpg' width="600"/>
每项指标有三个数值:当前帧、最小值、最大值。
......@@ -97,7 +97,7 @@ Unity引擎视角:
- UsedHeapMemory:UnityHeap真实使用量
- UnAllocatedMemory:UnityHeap预留量
<image src='../image/optimizationMemory11.png' width="600"/>
<img src='../image/optimizationMemory11.png' width="600"/>
底层分配器:
- 绿色为空闲内存或碎片,底层分配器会尽量复用
......@@ -108,7 +108,7 @@ Unity引擎视角:
由于Unity WebGL是托管在浏览器环境中,因此JavaScript Heap包含了大部分(并非全部)我们关注的内存, 通常我们可以使用浏览器自带的内存工具。
#### FireFox Memory(PC)
#### iOS Safari Timeline(PC or iOS)
<image src='../image/optimizationMemory5.png' width="1080"/>
<img src='../image/optimizationMemory5.png' width="1080"/>
### 四、内存优化方案
计算公式:
......
# 使用Unity Profiler性能调优
1. 导出选项时勾选"Development Build"与"Autoconnection Profiler"
<image src='../image/profile1.png' width="400"/>
<img src='../image/profile1.png' width="400"/>
2. 打开Unity-Window-Analysis-Profile窗口
<image src='../image/profile2.png' width="400"/>
<img src='../image/profile2.png' width="400"/>
Unity将自启动监听端口34999等待调试链接,对于WebGL版本会启动websockify.js(用于websocket转发)。
此时,导出的WebGL游戏在浏览器时能自动连接到Unity Profiler。
3. 微信开发者工具小游戏Profile
使用转换脚本导出微信小游戏包并启动小游戏,微信小游戏将自动连接到Unity Profiler
<image src='../image/profile3.png' width="400"/>
<img src='../image/profile3.png' width="400"/>
4. 真机调试
Android或iOS启动之后将使用"ws://ip:port"自动连接到“Unity Profiler”, 如果无法连接请关注vConsole输出的IP:Port是否可达。
如果需要手工调整端口可通过修改以下代码:
<image src='../image/profile4.png' width="400"/>
<img src='../image/profile4.png' width="400"/>
> 一般来说,保持端口为54998,如修改端口需重启websocketfy.js:
> windows: "$UNITY_PATH/Editor/Data/Tools/nodejs/node.exe" "$UNITY_PATH/Editor/Data/PlaybackEngines/WebGLSupport/BuildTools/websockify/websockify.js" 0.0.0.0:port localhost:34999
......
......@@ -21,7 +21,7 @@ eg: `adSpaceType=1&adType=1&materialType=1`
## 三、上报自定义阶段
为了详细统计玩家的流失情况以便开发者进行优化,我们拆分了三个部分。
<image src='../image/reportstartupstat3.png'/>
<img src='../image/reportstartupstat3.png'/>
其中**自动上报**为Unity Loader自动完成开发者无需关注,但**自定义阶段****启动加载完成**需开发者主动调用接口进行上报。详细接口可参考C# SDK中的WX.cs,此处列出关键接口:
**1. 定义阶段**
......@@ -109,9 +109,9 @@ gameManager.onLaunchProgress = (e) => {
## 五、获取数据统计
数据报表包含Unity Loader自动上报与开发者自定义阶段。关注总体流失漏斗以确定需要优化的方向,同时分阶段的耗时分布有利于帮助我们分析该阶段的对应耗时的用户占比。
<image src='../image/reportstartupstat1.png'/>
<img src='../image/reportstartupstat1.png'/>
<image src='../image/reportstartupstat2.png'/>
<img src='../image/reportstartupstat2.png'/>
注:
目前该数据统计报表需要建联[小游戏研发助手](IssueAndContact.md)获取,未来会开放到《小游戏数据助手》。
......@@ -6,85 +6,85 @@
## 地铁跑酷
<image src='../image/showcase23.png' width="200"/>
<img src='../image/showcase23.png' width="200"/>
超好玩的3D跑酷手游!简单的上手操作,丰富的游戏画面,众多的城市场景,让你爱不释手!
## 谜题大陆
<image src='../image/showcase25.png' width="200"/>
<img src='../image/showcase25.png' width="200"/>
一款独具创新的魔幻三消策略小游戏,神奇的消除战争之旅!带你探索不一样的魔幻体验!
## 翡翠大师
<image src='../image/showcase8.png' width="200"/>
<img src='../image/showcase8.png' width="200"/>
模拟经营游戏,玩家将体验到富有风险的翡翠原石选石过程,通过切石,设计,抛光的流程获得精美的翡翠雕刻成品,让自己的翡翠珍宝展馆发展壮大,熠熠生辉;在得到成就感的同时收获相关的翡翠知识。
## 大侠不哭
<image src='../image/showcase26.png' width="200"/>
<img src='../image/showcase26.png' width="200"/>
喜欢武侠世界,曾梦想惩恶扬善、和志同道合的伙伴携手闯仗剑走天涯!
## 我叫MT2
<image src='../image/showcase24.png' width="200"/>
<img src='../image/showcase24.png' width="200"/>
由乐动卓越研发的精美3D手游,延续了传统《我叫MT》的经典特色。钓鱼挖矿,外域探险玩法都将为您呈现独一无二的掌中魔幻世界!
## 神枪手杰克
<image src='../image/showcase13.png' width="200"/>
<img src='../image/showcase13.png' width="200"/>
在这个绝地世界中,最强的枪神一颗子弹就能解决一个敌人!玩家控制绝地枪神,穿越敌人的枪林弹雨拯救人质
## 盖楼我最强之打工人
<image src='../image/showcase18.png' width="200"/>
<img src='../image/showcase18.png' width="200"/>
一款轻松解压的模拟经营游戏,每天只需要在空闲时间打开游戏,世界上知名的建筑就会在你手中呈现,快来体验吧!
## 火柴人冒险世界
<image src='../image/showcase27.png' width="200"/>
<img src='../image/showcase27.png' width="200"/>
火柴人冒险世界是一款火柴人冒险模拟游戏
## 小锁酱
<image src='../image/showcase28.png' width="200"/>
<img src='../image/showcase28.png' width="200"/>
叫你不要吵我吧!弄断了吧!!
## 画个飞机
<image src='../image/showcase29.png' width="200"/>
<img src='../image/showcase29.png' width="200"/>
来呀,画个飞机,battle呀
## 拳拳大乱斗正版
<image src='../image/showcase31.png' width="200"/>
<img src='../image/showcase31.png' width="200"/>
全民拳拳大乱斗,是一款派对竞技的多人游戏,像香肠派对,糖豆人,人类一败涂地软体物理的对战休闲游戏。快来和好朋友一起玩吧!
## 开心解绳子
<image src='../image/showcase30.png' width="200"/>
<img src='../image/showcase30.png' width="200"/>
解绳子3d, 益智休闲小游戏。
## 就差一刀
<image src='../image/showcase7.png' width="200"/>
<img src='../image/showcase7.png' width="200"/>
每个关卡都有不同的任务,挑战玩法对玩家很有吸引力,点击屏幕可以使刀跳起来,让玩家体验到更多有趣的体验,并将其分解成相应的形状,各种挑战也会给玩家带来惊喜。
## 拯救花园
<image src='../image/showcase14.png' width="200"/>
<img src='../image/showcase14.png' width="200"/>
当你醒来发现拥有了一个自己的花园,但却缺乏生机,快动动手指划出线条,引导水管把水送到杯中,收集星星和金币,让花园更加生机盎然。
## 解救公主殿下
<image src='../image/showcase22.png' width="200"/>
<img src='../image/showcase22.png' width="200"/>
一款非常经典的竞技类游戏,游戏内玩家可以选择不同的角色,在迷宫中冒险并找到公主殿下,玩家可以展开多人竞技吗,磨炼自身的技术,注意的是每个关卡都有着无数的敌人,感兴趣的还不快快下载解救公主殿下游戏尝试一下啦。
......@@ -92,68 +92,68 @@
## 飞车乱斗
<image src='../image/showcase17.png' width="200"/>
<img src='../image/showcase17.png' width="200"/>
来体验一把速度与激情吧!
## 拯救史莱姆
<image src='../image/showcase15.png' width="200"/>
<img src='../image/showcase15.png' width="200"/>
丰富的创意,小巧的关卡,开动你的脑筋来拯救可爱的史莱姆吧!
## 泡泡龙开心消除
<image src='../image/showcase16.png' width="200"/>
<img src='../image/showcase16.png' width="200"/>
泡泡龙开心消消乐,保护小松鼠之战,你能消除所有泡泡,解救可爱的小松鼠吗?休闲益智的泡泡龙消除等你来挑战!
## 生存天才
<image src='../image/showcase9.png' width="200"/>
<img src='../image/showcase9.png' width="200"/>
《生存天才》是一款创意的生存冒险小游戏,通过不断战斗、采集才能渡过饥荒与躲过危机,小游戏简介 迷你饥荒,生存冒险,你能坚持多久?
## 动感消除
<image src='../image/showcase12.png' width="200"/>
<img src='../image/showcase12.png' width="200"/>
《动感消除》是一款2D三消类游戏,可爱的画风与丰富的消除玩法规则,必然让你爱不释手。玩家通过消除方块,合成道具,完成关卡目标,通过不同的游戏模式。
## 找茬对对碰之找茬达人
<image src='../image/showcase19.png' width="200"/>
<img src='../image/showcase19.png' width="200"/>
一款能让你恢复视力的游戏。
## 小灰灰历险记
<image src='../image/showcase21.png' width="200"/>
<img src='../image/showcase21.png' width="200"/>
不会吧!!!这么多同学都在玩~
## 极度漂移3D
<image src='../image/showcase11.png' width="200"/>
<img src='../image/showcase11.png' width="200"/>
《极度漂移3D》是一款的3D赛车游戏,由[extreme-drift](https://assetstore.unity.com/packages/templates/systems/extreme-drift-88601)项目适配转换。精美的赛车造型、多样的赛道选择,配合玩家熟练的操作体验到漂移的乐趣。
## TrashDash
<image src='../image/showcase2.png' width="200"/>
<img src='../image/showcase2.png' width="200"/>
Unity制作的[
EndlessRunnerSampleGame](https://github.com/Unity-Technologies/EndlessRunnerSampleGame)的小游戏适配。 一款有趣的跑酷类游戏,控制一条勇敢的街头猫,沿着一个大城市的街道跑步,沿途收集鱼骨和沙丁鱼罐头,同时避开各种致命的障碍和怪物。
## Match3
<image src='../image/showcase5.png' width="200"/>
<img src='../image/showcase5.png' width="200"/>
《Match3》是经典三消游戏类型中很棒的完整项目,玩法上具有许多目标和障碍。
## OTowerDefence
<image src='../image/showcase4.jpg' width="200"/>
<img src='../image/showcase4.jpg' width="200"/>
《OTowerDefence》由Unity Learn的官方教程移植,该示例阐述了塔防的所有游戏元素,玩家可以选择不同的塔防建筑对抗AI敌人的进攻。建筑物可升级,售卖,具备丰富的玩法组合。
## AirStrike
<image src='../image/showcase6.png' width="200"/>
<img src='../image/showcase6.png' width="200"/>
《AirStrike》是一款休闲类3D飞行游戏,丰富的关卡设计与战机造型, 模拟真实的飞行体验与环境,紧张刺激的敌我空战让玩家沉浸其中。
......
......@@ -2,12 +2,12 @@
## 启动加载时序
Unity WebGL转换的小游戏主要依靠Unity Loader进行初始化,典型的流程如下图所示:
<image src="../image/launch1.png">
<img src="../image/launch1.png">
## Unity Loader工作流程
<image src="../image/launch.png">
<img src="../image/launch.png">
关键过程:
......
......@@ -14,7 +14,7 @@
通过timelog开发者可以看到小游戏目前的启动首屏时长:
<image src='../image/startupop1.png' width="400"/>
<img src='../image/startupop1.png' width="400"/>
要知道各个阶段的含义,我们必要理解[启动流程](Startup.md)
......@@ -57,7 +57,7 @@ WASM分包的大小会直接影响代码下载时长以及程序初始化编译
### 2.3 优化总览
我们总结下启动时序以及开发者、平台提升启动性能的优化事项:
<image src='../image/startupop2.png'/>
<img src='../image/startupop2.png'/>
## 三、常用启动优化技巧
......
# Unity WebGL小游戏适配方案概述
## 一、技术原理
<image src='../image/summary1.png' width="1080"/>
<img src='../image/summary1.png' width="1080"/>
Unity的BuildTarget支持WebGL平台,WebGL导出包是基于WebAssembly技术运行在浏览器环境。
为了能让导出包运行在微信小游戏环境,我们提供了以下支持:
......@@ -12,7 +12,7 @@ Unity的BuildTarget支持WebGL平台,WebGL导出包是基于WebAssembly技术
## 二、接入流程
接入流程主要包含以下几个环节:
<image src='../image/summary2.png'/>
<img src='../image/summary2.png'/>
> 注:图中每个环节的人力时间为预计,具体时间因具体项目不同。
......
......@@ -3,7 +3,7 @@
## 操作系统
目前由Unity WebGL转换的小游戏兼容性与性能在不同平台的表现会有所差异,部分平台依然在迭代优化。
<image src='../image/supportedplatfoerm1.png'/>
<img src='../image/supportedplatfoerm1.png'/>
## 微信小游戏基础库
......
......@@ -4,7 +4,7 @@
添加需要导出的scene
<image src='../image/scene.png' width="600"/>
<img src='../image/scene.png' width="600"/>
建议仅勾选Loading场景,后续场景使用AssetsBundle/Addressable进行按需加载。
......@@ -14,7 +14,7 @@
### 2.1 转换小游戏
顶部菜单栏 点击 微信小游戏 -> 转换小游戏, 填写相应参数,点击`导出WEBGL并转换为小游戏`按钮 ,等待转换完成。
<image src='../image/export.png' width="600"/>
<img src='../image/export.png' width="600"/>
其中:
1. 必须
......@@ -63,18 +63,18 @@
导入转换后的`minigame`目录
3. 工具预览
<image src='../image/devtools_preview.png'>
<img src='../image/devtools_preview.png'>
注意:
> 项目使用了小游戏Unity适配插件,若小游戏是第一次使用本插件,在开发者工具会报错提示插件未授权
<image src="../image/addPlugin.png">
<img src="../image/addPlugin.png">
**请前往mp后台-能力地图-生产提效包-快适配,开通使用**
<image src='../image/mp_addplugin.png'>
<img src='../image/mp_addplugin.png'>
<image src='../image/auth_plugin.png'>
<img src='../image/auth_plugin.png'>
4. 真机预览
点击**预览**,扫码二维码预览即可。
......
# 使用Unity Profiler性能调优
1. 导出选项时勾选"Development Build"与"Autoconnection Profiler"
<image src='../image/profile1.png' width="400"/>
<img src='../image/profile1.png' width="400"/>
2. 打开Unity-Window-Analysis-Profile窗口
<image src='../image/profile2.png' width="400"/>
<img src='../image/profile2.png' width="400"/>
Unity将自启动监听端口34999等待调试链接,对于WebGL版本会启动websockify.js(用于websocket转发)。
此时,导出的WebGL游戏在浏览器时能自动连接到Unity Profiler。
3. 微信开发者工具小游戏Profile
使用转换脚本导出微信小游戏包并启动小游戏,微信小游戏将自动连接到Unity Profiler
<image src='../image/profile3.png' width="400"/>
<img src='../image/profile3.png' width="400"/>
4. 真机调试
Android或iOS启动之后将使用"ws://ip:port"自动连接到“Unity Profiler”, 如果无法连接请关注vConsole输出的IP:Port是否可达。
如果需要手工调整端口可通过修改以下代码:
<image src='../image/profile4.png' width="400"/>
<img src='../image/profile4.png' width="400"/>
> 一般来说,保持端口为54998,如修改端口需重启websocketfy.js:
> windows: "$UNITY_PATH/Editor/Data/Tools/nodejs/node.exe" "$UNITY_PATH/Editor/Data/PlaybackEngines/WebGLSupport/BuildTools/websockify/websockify.js" 0.0.0.0:port localhost:34999
......
......@@ -28,7 +28,7 @@ Addressable提供了以下能力:
Unity中资源按需加载也可以使用老的AssetBundle,然而使用AB需要做不少的工作:标识Asset、组织Bundle、编译、Load/Unload、依赖关系以及后期维护的复杂工作。新一代的Addressable正是对这些痛点做了不少改进,开发者只需要将Asset设置为addressable然后加载即可,[功能强大并且学习曲线变得平滑]
(https://docs.google.com/document/d/1hPLNLdrF0qAvjEJTpKf-cuO_d4FCV0H2cqBeP1Zo6mA/edit)。
<image src='../image/addressable7.png' width="600"/>
<img src='../image/addressable7.png' width="600"/>
### 2.3 在小游戏中使用Addressable Assets System
......@@ -38,7 +38,7 @@ Unity中资源按需加载也可以使用老的AssetBundle,然而使用AB需
## 三、启动优化与资源优化实战
### 3.1 从首包开始
首包资源应该只包含首屏所需资源,比如Splash界面以及对应文案。
<image src='../image/addressable2.png' width="800"/>
<img src='../image/addressable2.png' width="800"/>
首屏资源需要注意:
> 1. 导出场景不要勾选任何其他场景
> 2. 不要打包字体文件,字体往往压缩率很低。
......@@ -54,7 +54,7 @@ Unity中资源按需加载也可以使用老的AssetBundle,然而使用AB需
### 3.2 资源按需加载
#### 3.2.1 场景动态加载
如前所述,我们构建时仅选择了splash/loading场景,那么主场景(如大厅/战斗等)该如何加载?此时我们可以**将每个场景单独作为Addressable分组**,在用到的时候才下载该场景包。
<image src='../image/addressable5.png' width="800"/>
<img src='../image/addressable5.png' width="800"/>
使用Addressables.LoadSceneAsync可以动态加载场景与获取加载进度:
```
......@@ -75,19 +75,19 @@ Unity中资源按需加载也可以使用老的AssetBundle,然而使用AB需
```
选择分组,设置分组属性如下:
<image src='../image/addressable8.png' width="800"/>
<img src='../image/addressable8.png' width="800"/>
如果我们仅将场景作为分组,其中静态摆放的物件不单独设置为Addressable也会一并打包到场景所在bundle。那么,这是会产生一个问题:两个场景都使用同样资源是否产生冗余?答案是肯定的!!
那么,如何消除冗余呢?当我们Adressable面板的Tools-->Analyze进行分析时,可看到以下内容:
<image src='../image/addressable9.png' width="800"/>
<img src='../image/addressable9.png' width="800"/>
此时,我们应将这些冗余的内容单独进行设置为Addressable。而更为简单的做法是:选中“Check Duplicate Bundle Dependencies”,点击“Fixed Selected Rules”,工具会自动将冗余项逐个设置为Addressable。
### 3.2.2 物件动态加载
除了静态场景外,我们还会经常动态实例化(Instantiate)或在内存中创建资源对象。比如:
<image src='../image/addressable3.png' width="600"/>
<img src='../image/addressable3.png' width="600"/>
``` C#
public class LoadAssetScript : MonoBehaviour
......
......@@ -8,7 +8,7 @@
注意:小游戏环境不支持assetbundle本地加载
### 1.1 组织资源
自行组织资源如何分组,以及各个bundle之间依赖关系,包名相同的资源会打包到一起
<image src="../image/assetbundle/set-bundlename.png" width="600" />
<img src="../image/assetbundle/set-bundlename.png" width="600" />
### 1.2 AssetBundle打包
```c#
public static void Build()
......@@ -92,7 +92,7 @@ public static void Build()
界面如下
<image src="../image/assetbundle/assetbundle-scene.png" width="600" />
<img src="../image/assetbundle/assetbundle-scene.png" width="600" />
按钮从上往下加载方式分别为使用`UnityWebRequestAssetBundle.GetAssetBundle`, `UnityWebRequest`, `WWW.LoadFromCacheOrDownload`, `WWW`
......@@ -124,11 +124,11 @@ StartCoroutine(UnityWebRequestLoad(string.Format("http://127.0.0.1:8080/Streamin
通过加载前后snapshot来对比总内存变化
- UnityWebRequestAssetBundle.GetAssetBundle/UnityWebRequest/WWW
这三种加载方式加载前后内存无变化
<image src="../image/assetbundle/normal-assetbundle-memory.png" />
<img src="../image/assetbundle/normal-assetbundle-memory.png" />
- WWW.LoadFromCacheOrDownload
加载bundle后内存增加了5403162字节,增加了bundle大小的内存,是因为WWW.LoadFromCacheOrDownload除了会将文件存入IndexDB外,还会存入内存中的UnityCache
<image src="../image/assetbundle/assetbundle-unnormal-memory.png" />
<img src="../image/assetbundle/assetbundle-unnormal-memory.png" />
**因此需要注意业务中不要使用已淘汰的WWW类,尤其WWW.LoadFromCacheOrDownload,当bundle数量多时,会浪费不少内存。**
......
......@@ -37,7 +37,7 @@ dataFileSubPrefix: 首包资源相对cdn地址的存放目录,默认首包资
### 3.2 启动界面
由于Unity WebGL启动加载需要一定时间,因此需要使用视频或图片等内容作为过渡以留住玩家。Unity Loader默认使用视频+进度信息呈现,开发者可以自定义封面/视频,可参考[启动Loader视频规范](video.md)进行配置。
<image src="../image/coverview_loading.png" height="500">
<img src="../image/coverview_loading.png" height="500">
#### 转换插件相关配置
```
......
......@@ -3,7 +3,7 @@
通过 [启动流程与时序](Startup.md)我们知道,在UnityLoader加载过程中存在**网络空闲**的情况。特别是“引擎初始化和首场景准备”,影响该步骤包括:引擎自身模块与数据初始化,游戏首个场景加载以及Awake流程。这个过程是CPU处理密集,但网络空闲的期间,根据机型性能不同,通常**平均耗时会在3~6s**左右,我们可以在此阶段提前下载资源。
## 导出预下载列表
<image src='../image/usingpreload1.png' width="500"/>
<img src='../image/usingpreload1.png' width="500"/>
#### MiniGameConfig.asset相关配置
```
......
......@@ -37,7 +37,7 @@ unity导出小游戏项目后,代码是在一个wasm文件里,经过brotli
分包工作流如图所示
<image src="../image/wasmsplit/workflow.png">
<img src="../image/wasmsplit/workflow.png">
如图所示,对于未分包项目,开发者可以在插件里启用分包,然后配置版本信息,这时候会插件会自动开始第一次分包,变成已分包项目
......@@ -49,16 +49,16 @@ unity导出小游戏项目后,代码是在一个wasm文件里,经过brotli
通过开发者工具的设置-拓展设置-编辑器自定义拓展,安装 wasmCodeSplit 这个插件(插件后续0.0.6及以下存在部分使用问题,但不影响分包结果,我们会在0.0.7修复相关问题)
<image src="../image/wasmsplit/extension-panel.png">
<img src="../image/wasmsplit/extension-panel.png">
### 迭代流程
1. 打开插件开关后,在目录树上的工具栏中,可以看到插件的按钮,如图所示,点击后即可进入插件页:
<image src="../image/wasmsplit/enable-plugin-1.png">
<img src="../image/wasmsplit/enable-plugin-1.png">
2. 点击启用代码分包,新导出的小游戏(注:同一游戏从 unity 的不同次导出也认为是新的)会提示输入版本描述,简单输入方便识别版本的描述即可,然后插件会自动进行首次分包
<image src="../image/wasmsplit/enable-plugin-2.png">
<image src="../image/wasmsplit/start-split.png">
<img src="../image/wasmsplit/enable-plugin-2.png">
<img src="../image/wasmsplit/start-split.png">
3. 第一次分包完成后,就可以开始迭代式收集,每一轮迭代流程如下:
......@@ -73,7 +73,7 @@ unity导出小游戏项目后,代码是在一个wasm文件里,经过brotli
- 点击开发者工具的预览,在真机上跑,有条件的话可以尽量覆盖各种机型(主流品牌)以及平台(Android/iOS)
- 当插件页显示的收集到增量函数个数相对稳定时,可以点击“我已收集好,继续下一步”
<image src="../image/wasmsplit/code-split-index.png">
<img src="../image/wasmsplit/code-split-index.png">
随着迭代轮数增多,新增函数会越来越少,这里没有完成收集的标准,建议开发者能回归覆盖游戏的各种启动场景即可(不同进度,二次启动等等),目的是为了延迟依赖剩下的分包的时间
......@@ -93,7 +93,7 @@ unity导出小游戏项目后,代码是在一个wasm文件里,经过brotli
因此我们支持了增量分包,可以在二次导出时,通过选择之前已经进行过分包的版本,在之前分包的基础上进行增量分包
<image src="../image/wasmsplit/incremental-split.png">
<img src="../image/wasmsplit/incremental-split.png">
这里主要是通过symbol文件,按函数签名识别相同函数来实现的,因此需要导出时有symbol文件
......
......@@ -11,7 +11,7 @@
### CPU消耗
通过多款游戏项目,我们得到实际游戏项目的CPU占用如下图所示:
<image src='../image/iosoptimization3.png' width="500"/>
<img src='../image/iosoptimization3.png' width="500"/>
我们得到以下结论:
- 高性能模式在长期执行过程中CPU明显低于普通模式,后者长期处于高CPU占用因此长期运行容易越来越烫
......@@ -29,8 +29,8 @@
分数越高,代表的运行能力越强。
<image src='../image/iosoptimization1.png' width="250"/>
<image src='../image/iosoptimization2.png' width="250"/>
<img src='../image/iosoptimization1.png' width="250"/>
<img src='../image/iosoptimization2.png' width="250"/>
上图分别是iOS端普通模式与高性能模式的得分,可以看到在几个压测示例中高性能模式均明显优于普通模式。
......
......@@ -15,51 +15,51 @@
打开拓展设置,找到水印工具,添加插件
<image src="../image/wasmsplit/extension-panel.png" width="600" />
<img src="../image/wasmsplit/extension-panel.png" width="600" />
<image src="../image/watermark/panel.png" width="600" />
<img src="../image/watermark/panel.png" width="600" />
<image src="../image/watermark/add.png" width="600" />
<img src="../image/watermark/add.png" width="600" />
#### 使用插件
在目录树上方工具栏找到水印工具icon,点击显示水印插件面板
<image src="../image/watermark/icon.png" width="400" />
<img src="../image/watermark/icon.png" width="400" />
项目首次使用插件默认会启用打水印功能。
插件检测并展示项目中的wasm文件,开发者自行决定是否需要上传并打水印。
<image src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/163231/single-file.png" width="400" />
<img src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/163231/single-file.png" width="400" />
点击上传按钮后,插件会自动执行逻辑
正在打水印
<image src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/164104/doing.png" width="400">
<img src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/164104/doing.png" width="400">
下载中
<image src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/164114/downloading.png" width="400">
<img src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/164114/downloading.png" width="400">
已完成
<image src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/164504/reset.png" width="400">
<img src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/164504/reset.png" width="400">
完成后,即可测试小游戏是否正常运行,若有异常,可点击还原wasm文件到初始状态,重新打水印。
当有两个wasm文件时,操作同理
<image src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/163222/multi-file.png" width="400" />
<img src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/163222/multi-file.png" width="400" />
若不想使用水印功能,点击关闭水印,wasm代码回到初始状态
<image src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/163419/disabled.png" width="400"/>
<img src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/163419/disabled.png" width="400"/>
### 注意
打水印和下载过程可能会有一定耗时,请耐心等待。
若AppID为测试号,或者是小程序AppID,会出现如下界面,更换正确的AppID后重新检测即可
<image src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/163318/invalid-appid.png" width="400"/>
<img src="https://res.wx.qq.com/wechatgame/product/webpack/userupload/20210623/163318/invalid-appid.png" width="400"/>
# Unity WebGL 微信小游戏适配方案(公测)
欢迎使用 Unity WebGL 小游戏适配(转换)方案,本方案设计目的是**降低 Unity 游戏转换到微信小游戏的开发成本**。基于WebAssembly技术,无需更换Unity引擎与重写核心代码的情况下将原有游戏项目适配到微信小游戏。
- 若图片无法显示,请访问[gitee项目地址](https://gitee.com/wechat-minigame/minigame-unity-webgl-transform)
## 方案特点
* 保持原引擎工具链与技术栈
* 无需重写游戏核心逻辑,支持大部分第三方插件
......@@ -12,7 +14,7 @@
## 转换案例
| 我叫MT2(回合战斗) | 旅行串串(休闲) | 谜题大陆(SLG) | 热血神剑(MMO) |
| --- | --- | --- | --- |
| <image src='image/showcase34.png' width="240"/> | <image src='image/showcase32.png' width="220"/> | <image src='image/showcase25.png' width="230"/>| <image src='image/showcase33.png' width="230"/> |
| <img src='image/showcase34.png' width="240"/> | <img src='image/showcase32.png' width="220"/> | <img src='image/showcase25.png' width="230"/>| <img src='image/showcase33.png' width="230"/> |
- [更多转换案例](Design/ShowCase.md)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册