gg helper手游是真的吗游

当前位置: >
> 苹果版2017腾讯手游合集下载
苹果版下载排行小皮手游网登录
其他登录方式:
小皮手游微信
所属分类:
专区推荐热门手游新游推荐
卡牌游戏动作格斗角色扮演腾讯游戏休闲娱乐
查看: 2093|回复: 4
奇迹暖暖小皮下载地址集合
主题帖子积分
论坛元老, 积分 7327, 距离下一级还需 9992672 积分
论坛元老, 积分 7327, 距离下一级还需 9992672 积分
1、安卓版&IOS版-论坛领福利
2、小皮手游宝-边玩边领礼包
3、小皮助手-电脑上玩奇暖
<div id="post_
<div id="post_
<div id="post_
<div id="post_
我是M酱,我在小皮论坛玩手游!
为什么奇迹暖暖下载能安装,但是就是他说有200什么必须要更新,然后我点击更新,它老说失败,这是为什么
为什么奇迹暖暖下载了却不能玩
为什么我已经安装了奇迹暖暖却玩不了
戒_╰)不掉*^*你的傻笑 发表于
为什么奇迹暖暖下载能安装,但是就是他说有200什么必须要更新,然后我点击更新,它老说失败,这是为什么 ...
我的也是这样&p&这是一个关于强迫症的故事。Unity中如果没有自定义脚本的Inspector,就会默认绘制出一个,不可编辑的脚本对应选取框。&/p&&img src=&/v2-5b72e54f77f2e4ed1abdfb6148daa853_b.jpg& data-caption=&& data-rawwidth=&945& data-rawheight=&319& class=&origin_image zh-lightbox-thumb& width=&945& data-original=&/v2-5b72e54f77f2e4ed1abdfb6148daa853_r.jpg&&&p&这有什么好处呢 ?鼠标点击的时候,能够在Project试图里定位脚本所在的文件夹和位置。当然如果没有,也可以鼠标右键进行Editor Script。&/p&&p&如果我们override了OnInspectorGUI函数,除非调用base.OnInspectorGUI父类的方法,否则是不会绘制这个脚本选择框的。UGUI自带的组件,也都没有绘制这个选择框。&/p&&img src=&/v2-d6ed10cbd461282ecd2a0_b.jpg& data-caption=&& data-rawwidth=&549& data-rawheight=&169& class=&origin_image zh-lightbox-thumb& width=&549& data-original=&/v2-d6ed10cbd461282ecd2a0_r.jpg&&&p&&b&那么,现在我需要自定义Inspector,并且还就是想要这个默认的脚本选择框,该怎么办 ?&/b& 经过我的研究,虽然UGUI的源码没有答案,但我还是找到了一个实现的途径。&/p&&p&先直接看代码。&/p&&div class=&highlight&&&pre&&code class=&language-c&&&span&&/span& &span class=&n&&public&/span& &span class=&n&&abstract&/span& &span class=&n&&class&/span& &span class=&nl&&BaseEditor&/span& &span class=&p&&:&/span& &span class=&n&&Editor&/span&
&span class=&p&&{&/span&
&span class=&n&&protected&/span& &span class=&n&&SerializedObject&/span& &span class=&n&&serializedTarget&/span&&span class=&p&&;&/span&
&span class=&n&&protected&/span& &span class=&n&&Object&/span&
&span class=&n&&monoScript&/span&&span class=&p&&;&/span&
&span class=&n&&protected&/span& &span class=&n&&virtual&/span& &span class=&kt&&void&/span& &span class=&nf&&OnEnable&/span&&span class=&p&&()&/span&
&span class=&p&&{&/span&
&span class=&n&&this&/span&&span class=&p&&.&/span&&span class=&n&&serializedTarget&/span& &span class=&o&&=&/span& &span class=&n&&new&/span& &span class=&n&&SerializedObject&/span&&span class=&p&&(&/span&&span class=&n&&this&/span&&span class=&p&&.&/span&&span class=&n&&target&/span&&span class=&p&&);&/span&
&span class=&n&&this&/span&&span class=&p&&.&/span&&span class=&n&&monoScript&/span&
&span class=&o&&=&/span& &span class=&n&&MonoScript&/span&&span class=&p&&.&/span&&span class=&n&&FromMonoBehaviour&/span&&span class=&p&&(&/span&&span class=&n&&this&/span&&span class=&p&&.&/span&&span class=&n&&target&/span& &span class=&n&&as&/span& &span class=&n&&MonoBehaviour&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&n&&protected&/span& &span class=&kt&&void&/span& &span class=&nf&&DrawMonoScript&/span&&span class=&p&&()&/span&
&span class=&p&&{&/span&
&span class=&n&&EditorGUI&/span&&span class=&p&&.&/span&&span class=&n&&BeginDisabledGroup&/span&&span class=&p&&(&/span&&span class=&nb&&true&/span&&span class=&p&&);&/span&
&span class=&n&&EditorGUILayout&/span&&span class=&p&&.&/span&&span class=&n&&ObjectField&/span&&span class=&p&&(&/span&&span class=&s&&&Script&&/span&&span class=&p&&,&/span& &span class=&n&&this&/span&&span class=&p&&.&/span&&span class=&n&&monoScript&/span&&span class=&p&&,&/span& &span class=&n&&typeof&/span&&span class=&p&&(&/span&&span class=&n&&MonoScript&/span&&span class=&p&&),&/span& &span class=&nb&&false&/span&&span class=&p&&);&/span&
&span class=&n&&EditorGUI&/span&&span class=&p&&.&/span&&span class=&n&&EndDisabledGroup&/span&&span class=&p&&();&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&ul&&li&首先,我们需要知道mono的脚本,其实是一个MonoScript类型的Asset,这个类型直接继承TextAsset,作为文本文件载入的。&/li&&li&其次,MonoScript.FromMonoBehaviour这个函数能够通过MonoBehaviour对象,找到MonoScript对象。&/li&&li&最后,EditorGUILayout.ObjectField方法能够绘制,一个Asset的选择框。默认选择的Project视图里的文件,就是第二个参数。&/li&&li&有些坑的是,禁用一个控件状态的函数,并不在EditorGUILayout里面,而是在EditorGUI里。BeginDisabledGroup 和 EndDisabledGroup。&/li&&/ul&&p&现在,自定义Inspector的代码,继承BaseEditor,然后重写OnInspectorGUI就可以了。&/p&&div class=&highlight&&&pre&&code class=&language-c&&&span&&/span&&span class=&n&&public&/span& &span class=&n&&override&/span& &span class=&kt&&void&/span& &span class=&nf&&OnInspectorGUI&/span&&span class=&p&&()&/span&
&span class=&p&&{&/span&
&span class=&n&&this&/span&&span class=&p&&.&/span&&span class=&n&&DrawMonoScript&/span&&span class=&p&&();&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&效果就是:&/p&&img src=&/v2-b33aad0d51ec1_b.jpg& data-caption=&& data-rawwidth=&269& data-rawheight=&274& class=&content_image& width=&269&&&p&&/p&
这是一个关于强迫症的故事。Unity中如果没有自定义脚本的Inspector,就会默认绘制出一个,不可编辑的脚本对应选取框。这有什么好处呢 ?鼠标点击的时候,能够在Project试图里定位脚本所在的文件夹和位置。当然如果没有,也可以鼠标右键进行Editor Script。…
&p&最早接触帧同步的概念是在2005年开发PS游戏高智能方程式赛车3的时候,当时负责赛车游戏的逻辑,物理,AI和录像回放等功能,录像回放就是使用点帧同步实现的。一场比赛只要保存玩家在不同时刻的操作即可,回放的时候就再跑一遍游戏在相同的时间执行相同的操作,得到相同的结果。对于主机游戏来说帧同步实现要简单很多,因为设备唯一,不存在浮点精度的问题,甚至都不需要逻辑层和表现层分离,只要简单的限帧即可。&/p&&img src=&/50/v2-2e62c85fbcf9f809ac2aa_b.jpg& data-caption=&& data-rawwidth=&980& data-rawheight=&550& class=&origin_image zh-lightbox-thumb& width=&980& data-original=&/50/v2-2e62c85fbcf9f809ac2aa_r.jpg&&&p&2015年开发一款3D战斗卡牌游戏的时候又使用了帧同步技术,因为当时服务器只有一个人战斗逻辑在客户端,一开始使用主机模式问题很多,迫不得已临时改成帧同步。因为是中途改的所以实现比较简单,使用FixedUpdate对逻辑限帧,使用TCP,可以说问题还是很多的。但因为1V1的横版游戏,玩家操作频率非常低,战斗也相对简单,有些不同步和延迟也还能接受。当时因为时间紧迫,开发的时候就遇到一个不同步问题解决一个,例如脚本更新顺序,逻辑帧更新等,其实也发现有浮点精度的问题,但因为时间有限只是对一些地方做了截断保护,后续项目又改成状态同步了也没有深究。&/p&&p&后来也了解过同类型游戏刀塔传奇的帧同步,刀塔传奇逻辑使用lua脚本,双精度浮点数double的精度问题比float好很多,另外2D游戏的运算相对3D简单,当时只遇到过一个数学运算有问题做了特殊处理就解决了。&/p&&p&&br&&/p&&p&最近在做一款射击类MOBA项目的时候,又采用了帧同步技术(帧同步和状态同步的对比和选择后续做更详细的介绍)。这是一款3D物理的俯视角射击MOBA项目,游戏中大量运用了真3D物理运算,双摇杆射击,最多支持16人战斗。游戏节奏非常快,操作频率非常高,一直会有大量玩家同屏团战,每个角色射速极高每帧有多发子弹,每个子弹都有弹道和物理计算,是一款对性能和延迟要求非常高的游戏。这时候同步就不能有一点问题了,任何一个Error或者运算的不同步就会导致结果的巨大差异,并且非常显而易见,使游戏无法进行,因此浮点精度问题也必须得到彻底解决了。&/p&&p&&br&&/p&&p&浮点精度的问题在PC上就有跨平台的问题,因为语言编译器不同使用的寄存器和运算过程中的舍入方式不同。就会导致在不同平台下相同的float运算会出现不同的结果,这方面有很多文章阐述就不多做阐述。而在手机上IOS还好比较单纯,Android设备系统硬件千差万别就更容易出现精度问题了。&/p&&p&&br&&/p&&p&&b&首先我做了一些单元测试。&/b&&/p&&img src=&/50/v2-8c846a4ee6_b.jpg& data-caption=&& data-rawwidth=&742& data-rawheight=&568& class=&origin_image zh-lightbox-thumb& width=&742& data-original=&/50/v2-8c846a4ee6_r.jpg&&&img src=&/50/v2-db6658ddfefc0380b05b_b.jpg& data-caption=&& data-rawwidth=&694& data-rawheight=&460& class=&origin_image zh-lightbox-thumb& width=&694& data-original=&/50/v2-db6658ddfefc0380b05b_r.jpg&&&p&*如上图,通过简单的单元测试函数对各种常规的数学运算做了测试。&/p&&p&&br&&/p&&p&&b&测试方法是:&/b&&/p&&ul&&li&首先在Windows64位电脑上生成浮点型测试数据,然后通过测试函数执行n次运算。&/li&&li&将测试结果的二进制保存到配置文件中。这里需要说明的是因为float是小数点后7位,在编辑中最多可以显示到9位例如1.比较起来不直观。另外也存在多个十进制数据对应一个二进制浮点数的情况,例如在编辑器中看到5.0,保存之后再读取显示可能就是4.9999999,他们两个对应相同的二进制是一样的。为了便于对比,我写了一个简单的函数将各种类型统一转成二进制,保存的时候按二进制写入和读取,输出的时候也对应输出浮点数的二进制表达方式。&/li&&/ul&&img src=&/50/v2-dad5edd18834_b.jpg& data-caption=&& data-rawwidth=&652& data-rawheight=&568& class=&origin_image zh-lightbox-thumb& width=&652& data-original=&/50/v2-dad5edd18834_r.jpg&&&p&*如上图,将各种类型转换成二进制字符串的函数。&/p&&ul&&li&在其他各种设备运行测试程序,读取浮点测试数据,执行相同的运算,显示测试数据和运算结果的十进制和二进制结果。&/li&&li&读取Windows64位电脑上的二进制测试结果,和当前运算结果进行比较,如果不同显示Error,并显示双方的二进制结果。&/li&&/ul&&p&&br&&/p&&p&&b&结果如下:&/b&&/p&&img src=&/50/v2-1ebf3ecde0978579ccdcc_b.jpg& data-caption=&& data-rawwidth=&752& data-rawheight=&340& class=&origin_image zh-lightbox-thumb& width=&752& data-original=&/50/v2-1ebf3ecde0978579ccdcc_r.jpg&&&p&可以发现连简单的x*x+y*y+z*z计算就出现了结果不一致,并且x*x,y*y,z*z和x*x+y*y都是一致的,就是y*y+z*z出现了不一致,猜测可能是不同设备的寄存器使用和舍入方式不同导致的误差,任何一个数学运算都有可能出现。&/p&&p&&br&&/p&&p&&b&进一步测试:&/b&&/p&&ul&&li&进过更细致的测试,我发现Windows,IOS,Android三个平台之间会出现float运算结果不一致的情况,其中Windows设备之间、IOS设备之间是一致的(也可能设备较少),Android平台下即使同一个平台不同机型之间也会有大量运算不一致。并且各种运算都有可能出现,没有规律可言(例如某个只有数学运算不一致)。&/li&&li&此外我又针对Unity的Physx物理引擎做了精度测试,创建一个3D世界,随机分布各种几何体胶囊,球,茶壶,立方体等等,然后从原点位置随机发射1000根射线,再用相同的方式记录和对比结果,最终发现物理运算也出现了不一致的现象!&/li&&li&最后我还让做AI的同事对Unity的Navmesh做了测试,在一张带Navmesh的场景上生成10000个测试路径对比。这次结果就比较有趣了,结果居然是一致的!&/li&&/ul&&p&&br&&/p&&p&&b&测试结果:&/b&&/p&&ul&&li&通过测试可以发现在如果逻辑代码中使用float连最基本的数学运算都保证不了,可见逻辑部分是不可能使用float了。&/li&&li&同样物理运算也会有不一致的问题,不能直接使用,但测试结果主要在浮点数位数的误差上。&/li&&li&使用Navmesh没有发现不一致的问题,可能有隐患但应该还是可以使用的。&/li&&/ul&&p&&br&&/p&&p&&b&解决方案:&/b&&/p&&ul&&li&代码中使用float的问题,我们通过在逻辑层使用定点数取代float来解决。我在刚入行的时候使用过定点数,当时主要是为了解决在手机上浮点数运算非常慢的问题。早期Doom,Quick等都使用过定点数的优化方式,在3D游戏编程大师的书中还提供过一套定点数学库。我的一个同事在此基础上实现了一套基于定点数的数学库,提供和Unity相似的接口,并对一些函数做了查表优化。另一个同事修改了导表工具,使得策划的填表数据也支持定点数,完美解决。后来我们还逆向了另外一款爆款帧同步游戏看了一下,他们也做了特殊处理,使用乘1000的方式来解决,类似我们的顶点数学库但更难使用。&/li&&/ul&&img src=&/50/v2-e3df61e31df_b.jpg& data-caption=&& data-rawwidth=&834& data-rawheight=&258& class=&origin_image zh-lightbox-thumb& width=&834& data-original=&/50/v2-e3df61e31df_r.jpg&&&ul&&li&因为大量使用了真实的3D物理,所以物理对我们来说是一道跨不过去的槛。我们尝试过多种解决方案,先是让公司引擎组的同事帮忙修改Unity和PhysX源码发现工作量巨大,然后又尝试修改bullet为定点数替换PhysX,但是修改后的Unity版本性能差了几百倍无法使用。最终迫于时间压力,我们还是采用了有些隐患的做法:只使用Unity最基本的射线和BoxCollider,在此基础上实现了一套简单的定点数物理引擎。但是即使这样还是会出现不一致的问题,我们又加入了尾数截断,按碰撞方向截断等方式保障一致性。最终在几十万把上线测试中还没有发现物理导致的不一致问题。(需要说明的是,如果要使用动态碰撞器,需要修改一下Unity源码,让物理引擎的Update可以再逻辑帧驱动,非常感谢引擎组同事的帮忙。Unity的新版好像提供了这个功能。)&/li&&li&Navmesh没有发现问题,我们实际使用也没出现问题,我们只使用了Navmesh的路点。&/li&&/ul&&p&&br&&/p&&p&&b&总结:&/b&&/p&&p&Float的一致性问题是帧同步方案的最基本的问题,也是相对比较好解决的问题,在后续开发过程中我们还遇到了无数帧同步的坑和难点,特别是同步和延迟的问题。帧同步是一个上手简单快速的技术,但是对操作频繁对延迟要求极高的大型游戏来说就变的非常难了。&/p&&p&针对同步问题我们还开发了一整套工具,当出现不同步的时第一时间就会上报,同时上传录像和日志到文件服务器,可以较快速的定位问题,统计不同步率。配合敏捷开发每日自动构建,代码Review,每次提交自动编译等,及时发现问题。最近一次上线测试玩家进行了39727次战斗未出现不同步,同步率至少达到王者荣耀的水平。&/p&&p&帧同步的不同步的测试还是比较困难和痛苦的,因为只要有一点没测到导致不同步上线之后可能就有非常大的风险,后续也会开发更强大的自动化测试工具,实现一种愉悦的开发方式!&/p&&p&&br&&/p&&p&&b&补充:&/b&&/p&&ul&&li&针对double类型我也做了测试,不一致性较float大幅下降,但还是会产生不一致问题。&/li&&li&PhysX有一个一致性开关,即使打开了,也还是会产生不一致问题。&/li&&li&在延迟上也做了大量优化,逻辑层和表现层完全分离,不使用FixedUpdate的方式降低输出延迟;同时使用了TCP,自己实现的可靠UDP和冗余包的非可靠UDP三种方式通信;极致压缩优化协议包降低在MTU范围以内;逻辑帧负载均衡;分地域部署和匹配;多线程收发等等。延迟数据接近王者荣耀的水平(双摇杆操作更多,服务器部署上延迟略高)。&/li&&/ul&&p&&/p&&p&&/p&
最早接触帧同步的概念是在2005年开发PS游戏高智能方程式赛车3的时候,当时负责赛车游戏的逻辑,物理,AI和录像回放等功能,录像回放就是使用点帧同步实现的。一场比赛只要保存玩家在不同时刻的操作即可,回放的时候就再跑一遍游戏在相同的时间执行相同的操…
&img src=&/50/v2-a5cf1e42f1afe6c90066_b.png& data-rawwidth=&898& data-rawheight=&226& class=&origin_image zh-lightbox-thumb& width=&898& data-original=&/50/v2-a5cf1e42f1afe6c90066_r.png&&&p&对于Android平台,Unity3D提供了两种原生的性能分析方法:Wi-Fi 与 ADB。&/p&&p&最为常见的是勾上Development Build 以及 Autoconnect Profiler。只要保证手机连接的Wi-Fi与正在Profiling的桌面电脑在同一网段,大多数情况下,游戏启动后Profiler都能正常找到手机。&/p&&p&&br&&/p&&p&&b&通过Wi-Fi连接有很大局限性&/b&,例如:&/p&&ul&&li&有时运行几十秒到&b&几分钟后编辑器就收不到数据了&/b&&/li&&li&&b&数据严重延迟&/b&,并随着时间的推移延迟越来越大&/li&&li&信号干扰大出现&b&卡顿&/b&&/li&&li&连接的Wi-Fi与电脑&b&不在一个网段&/b&&/li&&/ul&&p&遇到这些问题的时候你就需要通过ADB的方式来连接手机了&/p&&p&&br&&/p&&h2&ADB的方式&/h2&&p&你按照文档所说,勾了Development Build 与 Autoconnect Profiler,端口映射也做了&/p&&blockquote&adb forward tcp:34999 localabstract:Unity-包名&/blockquote&&p&接着,你选择了AndroidPlayer(ADB@127.0.0.1:34999)&/p&&p&&i&
注:不同版本默认端口有所不同&/i&&/p&&img src=&/v2-b28f2c38bf8a69e9af7db_b.jpg& data-caption=&& data-rawwidth=&392& data-rawheight=&143& class=&content_image& width=&392&&&p&&b&可Unity一点反应也没有&/b&&/p&&img src=&/v2-cfef3cf09ebacea1a518582_b.jpg& data-caption=&& data-rawwidth=&576& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&576& data-original=&/v2-cfef3cf09ebacea1a518582_r.jpg&&&p&接着,你又会尝试映射一个其他端口号,然后&/p&&img src=&/v2-5bd9e056ab40ae7c10eb317_b.jpg& data-caption=&& data-rawwidth=&385& data-rawheight=&209& class=&content_image& width=&385&&&p&&b&这回,Unity有反应了&/b&&/p&&img src=&/v2-82a970e269d65d6b608195_b.jpg& data-caption=&& data-rawwidth=&399& data-rawheight=&39& class=&content_image& width=&399&&&img src=&/v2-ae2b8c1a2aeb4ad66ccfc96_b.jpg& data-caption=&& data-rawwidth=&500& data-rawheight=&500& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&/v2-ae2b8c1a2aeb4ad66ccfc96_r.jpg&&&p&你开始四处问人,&b&别人告你,他也没成功过&/b&&/p&&p&&br&&/p&&p&你搜索、爬论坛,回复中都是&b&文档的机器翻译了贴给你&/b&&/p&&p&&br&&/p&&img src=&/v2-9fb813b103bce9dc7cf62e8bc298a14e_b.jpg& data-caption=&& data-rawwidth=&550& data-rawheight=&381& class=&origin_image zh-lightbox-thumb& width=&550& data-original=&/v2-9fb813b103bce9dc7cf62e8bc298a14e_r.jpg&&&h2&终于有一天,你发现了这篇文章!!!&/h2&&h2&终于有一天,你发现了这篇文章!!!&/h2&&h2&终于有一天,你发现了这篇文章!!!&/h2&&p&&br&&/p&&h2&&b&让我来告诉你,让人又气又好笑的真相&/b&&/h2&&p&&b&首先&/b&&/p&&img src=&/v2-37de5cdfbbc96_b.jpg& data-caption=&& data-rawwidth=&750& data-rawheight=&104& class=&origin_image zh-lightbox-thumb& width=&750& data-original=&/v2-37de5cdfbbc96_r.jpg&&&img src=&/v2-1fd114a055fcbd0cb4eaa8dc5f6279a8_b.jpg& data-caption=&& data-rawwidth=&479& data-rawheight=&81& class=&origin_image zh-lightbox-thumb& width=&479& data-original=&/v2-1fd114a055fcbd0cb4eaa8dc5f6279a8_r.jpg&&&p&&b&对不起,输入的不是IP:Port&/b&,这里输入的得是IP,ADB USB连接时显然应该是127.0.0.1&/p&&p&&br&&/p&&h2&然后使用默认的端口映射3是为什么还是不行?&/h2&&p&&br&&/p&&h2&&b&因为官方文档没写完整 &/b&&/h2&&p&&b&文档并不是要告诉你,手机上装好了APK,启动后如何通过ADB连接&/b&&/p&&img src=&/v2-7cbb144c2ebde_b.jpg& data-caption=&& data-rawwidth=&300& data-rawheight=&345& class=&content_image& width=&300&&&p&根据反编译,可以知道Unity的执行流程&/p&&img src=&/v2-f631c6a4cc5_b.jpg& data-caption=&& data-rawwidth=&952& data-rawheight=&297& class=&origin_image zh-lightbox-thumb& width=&952& data-original=&/v2-f631c6a4cc5_r.jpg&&&p&&b&ConnectToPlayer() 的流程概括如下&/b&&/p&&ol&&li&从55000端口开始尝试连接&/li&&li&直至55511端口&/li&&li&尝试4600端口&/li&&li&若没有成功的,返回第1步,最多重复三次这样的行为&/li&&/ol&&p&&br&&/p&&h2&说到这,想必已经知道该怎么做了&/h2&&p&&br&&/p&&ol&&li&&b&IP填写127.0.0.1&/b&&/li&&li&&b&adb forward 端口号选用55000 ~ 55511范围,或者4600 (5.x ~ 2017)&/b&&/li&&li&&b&4.X版本,引擎代码中写死了常量55000&/b&&/li&&/ol&&p&&br&&/p&&h2&&b&如果觉得这篇文章帮到了您,请不要吝啬点击“关注”...&/b&&/h2&&h2&&b&如果觉得感激之情无以言表,请点击“赞赏”... O(∩_∩)O&/b&&/h2&
对于Android平台,Unity3D提供了两种原生的性能分析方法:Wi-Fi 与 ADB。最为常见的是勾上Development Build 以及 Autoconnect Profiler。只要保证手机连接的Wi-Fi与正在Profiling的桌面电脑在同一网段,大多数情况下,游戏启动后Profiler都能正常找到手机。 …
&p&转载请注明出处。&a href=&///?target=http%3A//& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&原文链接:
&a href=&///?target=https%3A//ixulin.github.io//talk-bake-in-unity/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&谈光照图烘焙技巧 - 徐小厨 | 大道至简&i class=&icon-external&&&/i&&/a&&/p&&p&最近给美术整理的,这是知乎上最类似的问题了,所以挂在这,一个是看是否有人有类似的问题可以参考,二来刷一下自己网站的外链,增加被爬虫抓到的几率。。。&/p&&p&知乎貌似不能像markdown或者引用html代码样外链图片,大家点上面的链接看吧。&/p&&p&-------------------------------------------------------------------------------------&/p&&p&第二次更。周末在科目二集训和考试的时候发现忽然被很多人点赞和关注,受宠若惊,感谢大家认可和支持。之前因为知乎不支持直接粘贴图片,又怕麻烦,只放了第一张图片,既然大家这么捧场,还是把配图都加上~~
~~ [捂脸][允悲]&/p&&p&另外更多文章请访问我的博客,还有一些文章的补充和更新,还是会以博客为主,知乎上的回答尽量过来修改~~&/p&&p&--------------------------------------------------------------------------------------&/p&&p&&b&LightMap烘焙技巧&/b&&/p&&blockquote&前言:弱弱的说我是一个程序猿。
科普名词解释:
全局照明(GI):是指除了直接光之外包括天空,物件之间间接光照的总和。
环境闭塞(AO):是指间接光在物件间相互遮挡反射不充分导致的微弱阴影。通常在直接光照的暗部才会比较明显。
天光:从头顶来的天空颜色造成的间接照明,特别是在晴朗的天气。
LightMap:光照贴图
HDR:颜色高动态区间,指颜色亮度可以超过1,移动平台暂且不支持
间接照明(间接反射):指光源照亮A物体,A物体变亮以后充当间接光源对近距离内B物体有照亮的作用。这种现象只有当物体B在直接光照(比如阳光)的阴影里才会明显。&/blockquote&&h2&&b&足够多的明暗对比&/b&&/h2&&ul&&li&&b&适当&/b&打平灯光以增加阴影面积(暗部更多更容易做效果) &/li&&/ul&&img src=&/v2-6ef9c62eaeeae71bbfd8d4_b.jpg& data-rawwidth=&894& data-rawheight=&669& class=&origin_image zh-lightbox-thumb& width=&894& data-original=&/v2-6ef9c62eaeeae71bbfd8d4_r.jpg&&&p&&br&&/p&&ul&&li&&b&适当&/b&增大模型增加阴影面积(暗部更多更容易做效果)&/li&&/ul&&img src=&/v2-a3f77893afb51b893ad7dd_b.jpg& data-rawwidth=&988& data-rawheight=&695& class=&origin_image zh-lightbox-thumb& width=&988& data-original=&/v2-a3f77893afb51b893ad7dd_r.jpg&&&p&&br&&/p&&ul&&li&通过&b&只投射不接收&/b&来增加假阴影(作假)(不接受投影是因为看不见所以可以节省这种物体的渲染和它占用的litmap面积)&/li&&/ul&&img src=&/v2-38f7cf3ac3b232e_b.jpg& data-rawwidth=&1036& data-rawheight=&768& class=&origin_image zh-lightbox-thumb& width=&1036& data-original=&/v2-38f7cf3ac3b232e_r.jpg&&&p&&br&&/p&&h2&&b&模拟全局光照&/b&&/h2&&ul&&li&足够&b&充分&/b&的&b&暗部&/b&照明(暗部会有一种明快的感觉,用美术语言说就是暗部很“通透”)&/li&&/ul&&img src=&/v2-61d5db56acdd4e4f6bcce2_b.jpg& data-rawwidth=&1168& data-rawheight=&784& class=&origin_image zh-lightbox-thumb& width=&1168& data-original=&/v2-61d5db56acdd4e4f6bcce2_r.jpg&&&p&&br&&/p&&img src=&/v2-05ac093d9b2dfa45a8738027_b.jpg& data-rawwidth=&1166& data-rawheight=&793& class=&origin_image zh-lightbox-thumb& width=&1166& data-original=&/v2-05ac093d9b2dfa45a8738027_r.jpg&&&p&&br&&/p&&ul&&li&天光的使用:&/li&&ul&&li&理论上越晴朗的天气阴影暗部越偏蓝(同理也是为了有全局照明的效果,用美术语言说就是暗部很“通透”)(哪天北京晴空万里的时候去大楼的阴影里看看是不是有蓝色,为了对比饱和度的覆盖问题,可以拿一张白纸)&/li&&/ul&&/ul&&img src=&/v2-2f3b24a55c7c8c62d036c075b69a315c_b.jpg& data-rawwidth=&940& data-rawheight=&637& class=&origin_image zh-lightbox-thumb& width=&940& data-original=&/v2-2f3b24a55c7c8c62d036c075b69a315c_r.jpg&&&p&&br&&/p&&ul&&li&对&b&间接反射&/b&的&b&夸张&/b&:&/li&&ul&&li&比如守望先锋花村的樱花树下会有很强烈的蓝紫色,实际上是模拟粉红的樱花与天光蓝色的叠加造成的视觉,不过暴雪的美术有更加夸张的表达。(实现方法实际是在暗部增加与区域环境颜色相似的点光,实时GI现在效率跟不上,另外也不可能这么强。)&/li&&li&小幅&b&夸张&/b&:&/li&&/ul&&/ul&&img src=&/v2-f570e8d447bb1ff09eb6f_b.jpg& data-rawwidth=&1078& data-rawheight=&741& class=&origin_image zh-lightbox-thumb& width=&1078& data-original=&/v2-f570e8d447bb1ff09eb6f_r.jpg&&&p&&br&&/p&&ul&&ul&&li&&b&更夸张&/b&的做法:现实世界中不会有这么强烈的间接反射,就像叶子把光间接反射出来了一样,守望先锋就是例子&/li&&/ul&&/ul&&img src=&/v2-79cd0e59331cc46ebbb4e1eba6eb6fb1_b.jpg& data-rawwidth=&1166& data-rawheight=&712& class=&origin_image zh-lightbox-thumb& width=&1166& data-original=&/v2-79cd0e59331cc46ebbb4e1eba6eb6fb1_r.jpg&&&p&&br&&/p&&ul&&li&其实以上技巧都是借鉴自守望先锋&/li&&ul&&li&这是一个人的分析,只要&b&有心去找,仔细去看,去思考&/b&,网上有很多文章有可以借鉴的地方(因为实时GI还开销太大,暴雪真是能通过技巧把能用的东西用到最好)
&a href=&/p/& class=&internal&&原文链接&/a&&/li&&/ul&&/ul&&img src=&/v2-96281dac58f267dd097ffd657f75e576_b.jpg& data-rawwidth=&856& data-rawheight=&492& class=&origin_image zh-lightbox-thumb& width=&856& data-original=&/v2-96281dac58f267dd097ffd657f75e576_r.jpg&&&p&&br&&/p&&ul&&ul&&li&还有一个对&b&环境光源&/b&的理解
&a href=&/question//answer/& class=&internal&&原文链接&/a&&/li&&/ul&&/ul&&img src=&/v2-b3c32aad4ed3dd6cd658a7_b.png& data-rawwidth=&682& data-rawheight=&897& class=&origin_image zh-lightbox-thumb& width=&682& data-original=&/v2-b3c32aad4ed3dd6cd658a7_r.png&&&p&&br&&/p&&ul&&li&祭上守望先锋的场景,很夸张的暗部间接光照,实际上是通过&b&暗部打烘焙点光&/b&来实现的。更多细节请&a href=&///?target=https%3A//ixulin.github.io//talk-scene-design& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&参考我的另外一篇文章&i class=&icon-external&&&/i&&/a&。&/li&&/ul&&img src=&/v2-702eb17eb0e0c1ea5f0e5db0e20cccd0_b.jpg& data-rawwidth=&1474& data-rawheight=&848& class=&origin_image zh-lightbox-thumb& width=&1474& data-original=&/v2-702eb17eb0e0c1ea5f0e5db0e20cccd0_r.jpg&&&p&&br&&/p&&h2&&b&AO的使用&/b&&/h2&&ul&&li&AO能更真实的模拟现实世界,能使暗部有&b&更明显的立体感&/b&,用美术的话说就是暗部足够“实”,“不飘”&/li&&ul&&li&基础知识请参考&a href=&///?target=https%3A///blog/lightmapping-in-unity-5/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这篇文章&i class=&icon-external&&&/i&&/a&,这里讲了什么是AO,什么是间接反射等&/li&&li&暗部的&b&接缝处&/b&AO效果最明显&/li&&/ul&&/ul&&img src=&/v2-49b79ea3d749a02a4ca546d532f80036_b.png& data-rawwidth=&1150& data-rawheight=&693& class=&origin_image zh-lightbox-thumb& width=&1150& data-original=&/v2-49b79ea3d749a02a4ca546d532f80036_r.png&&&p&&br&&/p&&h2&&b&LightMap面积的优化&/b&&/h2&&ul&&li&LightMap面积(精度)说明:(&b&一个格子就是一个像素点&/b&,也就是占用在lightmap上面的面积)&/li&&/ul&&img src=&/v2-af348f2d6d68e9c7ceec62_b.jpg& data-rawwidth=&1178& data-rawheight=&819& class=&origin_image zh-lightbox-thumb& width=&1178& data-original=&/v2-af348f2d6d68e9c7ceec62_r.jpg&&&ul&&ul&&li&通过&b&Scale In LightMap&/b&这个参数可以单独调整单个物体的精度&/li&&/ul&&/ul&&img src=&/v2-ed2d78e88dd20ce546157f_b.jpg& data-rawwidth=&617& data-rawheight=&618& class=&origin_image zh-lightbox-thumb& width=&617& data-original=&/v2-ed2d78e88dd20ce546157f_r.jpg&&&p&&br&&/p&&ul&&li&更合理的分配LightMap面积(想要好效果又要节省lightmap面积,就是&b&要研究,并总结经验,没有捷径&/b&)&/li&&ul&&li&只投射不接受的物件Scale In Lightmap填0就行&/li&&li&地面 & 物件,重要物件 & 一般物件, 视觉中心 & 边远地区,大物件 & 小物件&/li&&/ul&&/ul&&img src=&/v2-aef8fc7d13c3ff0d305f249d_b.jpg& data-rawwidth=&1006& data-rawheight=&813& class=&origin_image zh-lightbox-thumb& width=&1006& data-original=&/v2-aef8fc7d13c3ff0d305f249d_r.jpg&&&p&&br&&/p&&ul&&ul&&li&&b&全部&/b&(或者几乎全部)在明处或者&b&全部&/b&在暗处的可以用&b&最低分辨率&/b&烘焙(比如当前光线下的这个椅子和不管影子多么正都是在暗处的这面墙壁,这种情况下,这两个lightmap精度可以填0.01),需要注意的是必须参加烘焙只是精度可以很低(因为纯白或者纯黑被压缩大小是不会损失精度的)&/li&&/ul&&/ul&&img src=&/v2-8ccd576f46c07fab8df64a1efe4a08f8_b.jpg& data-rawwidth=&986& data-rawheight=&598& class=&origin_image zh-lightbox-thumb& width=&986& data-original=&/v2-8ccd576f46c07fab8df64a1efe4a08f8_r.jpg&&&p&&br&&/p&&ul&&ul&&li&地面以下,地图的侧面,或者根本看不见的东西,烘焙占用面积请控制到最小(最惨的情况请参考下面说的浪费)&/li&&/ul&&li&避免完全没有必要的浪费&/li&&ul&&li&像这种&b&完全在别的物体以下&/b&,还参加烘焙的完全没有必要,而且浪费很大&/li&&/ul&&/ul&&img src=&/v2-e12c19ed3e70dfbd73de5_b.jpg& data-rawwidth=&1034& data-rawheight=&713& class=&origin_image zh-lightbox-thumb& width=&1034& data-original=&/v2-e12c19ed3e70dfbd73de5_r.jpg&&&p&&br&&/p&&ul&&ul&&li&树叶花草等透贴类似的推荐&b&只投射,不接受&/b&,而且接受烘焙阴影效果不见得好,会很“脏”&/li&&/ul&&/ul&&img src=&/v2-1d84c1da3e352_b.jpg& data-rawwidth=&1048& data-rawheight=&713& class=&origin_image zh-lightbox-thumb& width=&1048& data-original=&/v2-1d84c1da3e352_r.jpg&&&p&&br&&/p&&h2&&b&技巧及问题&/b&&/h2&&ul&&li&发现阴影比较虚,不实&/li&&ul&&li&检查是否间接光照反弹次数过大(可以理解成有过大的衍射效果)&/li&&li&增加&b&被投影物体&/b&的大小(比如放大花盆)(很显然)&/li&&li&增加&b&投影至物体&/b&所占lightmap面积(比如树叶投影到地面比较虚,则提高地面的精度)&/li&&/ul&&li&效果不好或者黑点、漏光过多&/li&&ul&&li&检查2u是否打开&/li&&li&检查顶点分布是否有异常,uv分布是否均匀或过少&/li&&li&如果都没问题而且这个物件很重要,则增加精度&/li&&li&自定义2u(高级,不推荐使用)&/li&&/ul&&li&过小物体效果太差&/li&&ul&&li&如果确实过小,先看能不能放大,或者说这么小的东西有没有存在的必要或者是否可替代(很显然)&/li&&li&如果确实需要,可以不参加litmap烘焙,而直接去diffuse贴图上花盆贴图的底部蹭两笔黑的&/li&&li&这个花盆之前参加烘焙会有很大的漏光和黑点,其实不需要参加烘焙,而且效果比烘焙更好,还能节省lightmap&/li&&/ul&&/ul&&img src=&/v2-e5f068ad4ab810a3ce60_b.jpg& data-rawwidth=&602& data-rawheight=&542& class=&origin_image zh-lightbox-thumb& width=&602& data-original=&/v2-e5f068ad4ab810a3ce60_r.jpg&&&p&&br&&/p&&h2&&b&压缩的效果优化&/b&&/h2&&ul&&li&通过我烘焙的经验,以kasaierxueyuannew场景为例,发现烘焙10-12张1024压缩到512,比直接烘焙2-3张1024的贴图来的精度和效果都更好&/li&&ul&&li&10张512 = 2.5张1024,而以之前的烘焙策略烘焙3-4张1024效果没有我这个好&/li&&li&此外通过合理分配lightmap精度,&b&能节省2-3张lightmap&/b&,没有仔细分配之前,保证效果的情况下能烘焙14张左右,现在这版只使用了11张,如果还细抠还能省1张甚至更多&/li&&/ul&&/ul&&img src=&/v2-f00e8f430c419ed4617cebf_b.png& data-rawwidth=&433& data-rawheight=&329& class=&origin_image zh-lightbox-thumb& width=&433& data-original=&/v2-f00e8f430c419ed4617cebf_r.png&&&p&&br&&/p&&ul&&li&从1024压缩到512肯定会损失精度,但是通过&b&仔细的分配lightmap精度&/b&能使这种&b&损失达到最小&/b&&/li&&ul&&li&方法一:&b&地面最有用&/b&,所以怎么省都&b&不要吝啬地面的精度&/b&,地面不管接受多少阴影,所占用的lightmap面积是一样的,所以多打点阴影(不增加消耗,还可以做效果,何乐而不为)&/li&&li&方法二:&b&纯背光&/b&和&b&纯亮光&/b&区域可以减少lightmap精度,因为压缩不影响(就像纯黑纯白的贴图压缩大小没有损失一样),而&b&复杂的结构&/b&并且能&b&同时受到阳光和阴影&/b&的影响,则也不需要节省精度,因为如果本来精度就不高,则压缩更惨&/li&&li&方法三:压缩大小比压缩格式带来的损失小,如果压缩格式影响巨大,可以&b&不压缩格式&/b&,而在&b&其他地方想想办法怎么省&/b&(省的办法参考上面)。所以推荐烘焙高质量的光照图来&b&压大小&/b&。&/li&&li&方法四(重要):&b&尽量使用大阴影&/b&,在不压缩情况下本来就很小很虚的阴影,被压缩了只会更惨,优化方法参考以上&/li&&li&方法五:&b&不推荐&/b&使用&b&复杂的结构&/b&,酌情使用,在压缩的时候很容易损失过大&/li&&/ul&&/ul&&h2&&b&个人经验&/b&&/h2&&ul&&li&暗部补光,感觉上并&b&不是光越多越好&/b&,最好灯光颜色来表达周围环境的间接光照,过多颜色的灯光会让人觉得没有重点和乱&/li&&li&点光通过&b&减小光照强度&/b&、&b&增加照明范围&/b&能得到更好的环境间接光的效果,还能防止有比较突兀的亮斑&/li&&li&个人倾向于用&b&天空材质球&/b&来代替全局环境光来烘焙,如果是晴朗天气,用默认纯蓝的天空即可&/li&&li&白模的情况下感觉lightmap很舒服而且很干净,而最终效果图的lightmap效果没有那么明朗。所以猜测为diffuse贴图的饱和度问题,因此推荐使用&b&较低饱和度的颜色&/b&,否则lightmap的颜色很容易被盖掉(不保证正确,希望美术同学尝试)&/li&&/ul&&h2&&b&跨平台的问题&/b&&/h2&&ul&&li&因为烘焙Lightmap用的exr,也就是HDR颜色编码,而现在手机平台不支持HDR编码,导致在手机平台和PC平台的解码方式不一样,所以不能使用过强的光来烘焙光照图,否则会造成android与pc差异巨大,因此&b&不推荐使用光照强度超过3&/b&的灯光来渲染。&/li&&/ul&&h2&&b&演示&/b&&/h2&&ul&&li&可以从&a href=&///?target=https%3A//ixulin.github.io/attach/demo/test-bake3.rar& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&此处下载&i class=&icon-external&&&/i&&/a&演示场景&/li&&ul&&li&给一张全貌&/li&&/ul&&/ul&&img src=&/v2-be7ad83ebcb8_b.png& data-rawwidth=&1270& data-rawheight=&789& class=&origin_image zh-lightbox-thumb& width=&1270& data-original=&/v2-be7ad83ebcb8_r.png&&
转载请注明出处。原文链接: 最近给美术整理的,这是知乎上最类似的问题了,所以挂在这,一个是看是否有人有类似的问题可以参考,二来刷一下自己网站的外链,增加被爬虫抓到的几率。。。知乎貌似…
&img src=&/50/v2-233a66aaf096f_b.jpg& data-rawwidth=&2560& data-rawheight=&1420& class=&origin_image zh-lightbox-thumb& width=&2560& data-original=&/50/v2-233a66aaf096f_r.jpg&&&p&&/p&&img src=&/50/v2-233a66aaf096f_b.jpg& data-caption=&& data-rawwidth=&2560& data-rawheight=&1420& class=&origin_image zh-lightbox-thumb& width=&2560& data-original=&/50/v2-233a66aaf096f_r.jpg&&&p&时间来到了金秋九月,北京UUG活动也来到了第九期。本次活动的主题为《Unity实战经验分享》,为此我们邀请了3位资深的行业大神。这次我们仍然在北京市海淀区丹棱街5号微软大厦举行活动,在这里感谢unity官方的支持以及微软的场地支持。同时也十分感谢认真工作的活动志愿者。&/p&&img src=&/50/v2-5e6d6c5a52f73c8d2bae_b.jpg& data-caption=&& data-rawwidth=&1440& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1440& data-original=&/50/v2-5e6d6c5a52f73c8d2bae_r.jpg&&&p&活动一开始由文刚向大家介绍一下UUG社区内容及发展。&/p&&p&&br&&/p&&p&接下来是有2年三维动画和影视后期工作经验,3年AR、VR工作经验,深入了解并参与多款AR、VR项目,熟悉项目开发的全流程的郭蒙蒙带来的基于Unity的AR项目开发的分享。&/p&&img src=&/50/v2-912dfe4f4af2b8db3d20ee13b8e6d2e7_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&720& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/50/v2-912dfe4f4af2b8db3d20ee13b8e6d2e7_r.jpg&&&p&分享中嘉宾介绍了微软、谷歌、苹果等大厂在AR技术上的最新成果。&/p&&img src=&/50/v2-b5474a5eef5ad3f2bbce6_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&960& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/50/v2-b5474a5eef5ad3f2bbce6_r.jpg&&&p&&br&&/p&&p&之后是有8年手游从业经验(6年游戏服务端开发,2年Unity客户端开发),现任威魔纪元技术负责人,从事VR游戏研发工作的李中元带来的分享——《基于UDP的状态同步实战》 。&/p&&img src=&/50/v2-9f787ed814c8_b.jpg& data-caption=&& data-rawwidth=&1080& data-rawheight=&1440& class=&origin_image zh-lightbox-thumb& width=&1080& data-original=&/50/v2-9f787ed814c8_r.jpg&&&p&在分享中,嘉宾介绍了永恒战士VR这款产品的网络同步经验。&/p&&img src=&/50/v2-8c7e5fb4eef1d3bb48f2d17c922f6444_b.jpg& data-caption=&& data-rawwidth=&1440& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1440& data-original=&/50/v2-8c7e5fb4eef1d3bb48f2d17c922f6444_r.jpg&&&p&而参会的各位朋友也听的十分认真投入。&/p&&img src=&/50/v2-ee5fd5a352a7a26ad64cb6f_b.jpg& data-caption=&& data-rawwidth=&1440& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1440& data-original=&/50/v2-ee5fd5a352a7a26ad64cb6f_r.jpg&&&p&&br&&/p&&p&接下来的中场茶歇,由我介绍了一下微软最有价值专家的招募项目。&/p&&img src=&/50/v2-c424df18abd3b96f1ac73ab_b.jpg& data-caption=&& data-rawwidth=&1440& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1440& data-original=&/50/v2-c424df18abd3b96f1ac73ab_r.jpg&&&p&在这里,也欢迎各位有志于成为微软mvp的小伙伴积极参与。当然,如果有需要也可以直接联系我。&/p&&p&&br&&/p&&p&最后一位讲师是来自北京星空智盛科技发展有限公司《FringeWars》项目组的主程管世超,FringeWars是一个主机项目,因此嘉宾带来的也是主机游戏开发相关的经验分享。需要说明的是FringeWars项目组已经在前几期的UUG上为我们带来过了很多很精彩的主机游戏开发经验。&/p&&img src=&/50/v2-ac4e4c65fd_b.jpg& data-caption=&& data-rawwidth=&1440& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1440& data-original=&/50/v2-ac4e4c65fd_r.jpg&&&p&由于本次活动正值TGS东京电玩展2017前几天,因此嘉宾也介绍了若干参展的内容。&/p&&img src=&/50/v2-b031dd03c2cffa68f8b226d_b.jpg& data-caption=&& data-rawwidth=&1080& data-rawheight=&1440& class=&origin_image zh-lightbox-thumb& width=&1080& data-original=&/50/v2-b031dd03c2cffa68f8b226d_r.jpg&&&p&而各位小伙伴自然也听的津津有味。&/p&&img src=&/50/v2-e753ec40d7_b.jpg& data-caption=&& data-rawwidth=&1440& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1440& data-original=&/50/v2-e753ec40d7_r.jpg&&&p&&br&&/p&&p&活动的最后,各位参会的小伙伴都收到了来自Unity的小礼品。&/p&&img src=&/50/v2-197f160b1ba7bf8fb5f0_b.jpg& data-caption=&& data-rawwidth=&1280& data-rawheight=&960& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&/50/v2-197f160b1ba7bf8fb5f0_r.jpg&&&img src=&/50/v2-bfa00b0bc7c6b86db3fdd229411bad08_b.jpg& data-caption=&& data-rawwidth=&960& data-rawheight=&1280& class=&origin_image zh-lightbox-thumb& width=&960& data-original=&/50/v2-bfa00b0bc7c6b86db3fdd229411bad08_r.jpg&&&p&&br&&/p&&p&UUG是一个开发者交流的社区,这里没有猎头、没有公司HR、没有商务、总之没有一切与技术无关的东西,我们都是由最纯正的一线写代码的程序员组成的。往后我们会邀请更多的大拿加入我们的讲师团队,为大家进行更给力的分享。也欢迎各路大拿自荐或者推荐。&/p&&img src=&/50/v2-fbd25fea4c7ebc52230ee8_b.jpg& data-caption=&& data-rawwidth=&1440& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1440& data-original=&/50/v2-fbd25fea4c7ebc52230ee8_r.jpg&&&p&&br&&/p&&p&&br&&/p&&p&嘉宾ppt链接:&/p&&p&&a href=&/?target=https%3A///s/1ctsrWq& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/s/1ctsrWq&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&p&&/p&&p&&/p&
时间来到了金秋九月,北京UUG活动也来到了第九期。本次活动的主题为《Unity实战经验分享》,为此我们邀请了3位资深的行业大神。这次我们仍然在北京市海淀区丹棱街5号微软大厦举行活动,在这里感谢unity官方的支持以及微软的场地支持。同时也十分感谢认真工…
开发中遇到了很多比较奇怪和难解决的问题,这里进行了一些记录,很多问题得到Unity官方技术支持同学的大力帮助,非常感谢!&/p&&p&&br&&/p&&ul&&li&Unity5.5.1p2版本,IL2CPP切到后台可能会报错:&/li&&/ul&&p&EGL&br&Unable to acquire context EGL_BAD_NATIVE_WINDOW a nativewindowtype argument&br&does not refer to a valid native window.&/p&&p&解决方案:&/p&&p&官方建议只要没有Crash可以忽略。&/p&&p&The&br&error message &Unable to acquire context - EGL_BAD_NATIVE_WINDOW: A&br&NativeWindowType argument does not refer to a valid native window& occurs&br&occasionally on some Android devices when restoring the app from a minimised&br&state.&/p&&p&This&br&issue has been reported as a bug and we are currently working on a fix.&/p&&p&Other&br&than creating noise in logs and crash dumps the the error causes no problems so&br&you are safe to ignore it.&/p&&p&&br&&/p&&ul&&li&第一次安装完apk包之后,在刚进游戏启动瞬间游戏切到后台必定会闪退。Unity会弹框提示:Error&br&
Failed to extract resources needed by il2cpp。&/li&&/ul&&p&解决方案:&/p&&p&官方反馈在5.6版本得到修复。因为升级版本风险太高,这个bug影响较小,继续尝试其他解决方案。&/p&&p&Having&br&looked through the forum post you mentioned. As-well as the bug reports&br&mentioned in there and searching for other reports:&/p&&p&It&br&looks like these particular reports, were possibly fixed in 5.6 via other fixes&br&and changes. But we have no local report that we have been able to reliably&br&find a concrete fix or evidence of a fix with.&/p&&p&The&br&error message is flagged when the file system fails to copy files needed.&/p&&p&Can&br&you check if the devices being affected have this problem have little disk&br&space free?&/p&&p&Have&br&you been able to test the issue in 5.6 and see if the problem persists?&/p&&p&&br&&/p&&ul&&li&Unity是否有获得设备唯一ID的功能?新版IOS唯一ID的接口SystemInfo.deviceUniqueIdentifier可能重复。&/li&&/ul&&p&解决方案:&/p&&p&没有直接的api。官方建议如下&/p&&p&&a href=&/?target=https%3A///threads/ios-advertising-identifier-rejection-faq.226187/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/threa&/span&&span class=&invisible&&ds/ios-advertising-identifier-rejection-faq.226187/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&ul&&li&升级UNITY5.5.1P2版本之后MAC机上报错:&/li&&/ul&&p&Extension&br&was not registered, that means it relies on default UnityExtensions settings,&br&please register extension and apply necessary settings for it in the callback.&/p&&p&解决方案:&/p&&p&官方建议如下。&/p&&p&The error is caused by importers&br&which have a zero length asset path name. This happens when you have a Unity&br&version installed with an addon, it's calling for an asset's physical location,&br&and if you save the project and open with a Unity version without the addon it&br&will return an empty string since the physical location of this asset doesn't&br&exist. So the fix in 5.6 Unity will skip initialization for these plugins. If&br&you later add the addon, upon project opening it will return a valid path and&br&settings for it will be initialized.&/p&&p&This issue is not supposed to&br&affect your project or the editor. &/p&&p&In order to get rid off this&br&error just try to reimport all assets, it should solve the issue.&/p&&p&&br&&/p&&ul&&li&升级Unity之后IOS出包时报错。Showing&br&
Recent Issues ld:&br&
'/Users/hanyufei/.jenkins/workspace/MGameIOSMacPro/mgame/Program/trunk/Client/0.0.17.0/Libraries/Plugins/iOS/libulua.a(array.o)'&br&
does not contain bitcode. You must rebuild it with bitcode enabled (Xcode&br&
setting ENABLE_BITCODE), obtain an updated library from the vendor, or&br&
disable bitcode for this target. for architecture armv7&/li&&/ul&&p&解决方案:&/p&&p&使用的Lua库不支持BitCode。一种是升级Lua库支持BitCode,一种是关闭BitCode功能,但是会增大包体。这个bug出现在升级Unity5.5之后,主要是Unity5.3.1p1开始,bitcode是默认打开的。&/p&&p&&br&&/p&&ul&&li&升级Unity5.5之后出包报错:&/li&&/ul&&p&&br&12:09:10.329 xcodebuild[52] [MT] PluginLoading: Required plug-in&br&compatibility UUID E0A62D1F-3C18-4D74-BFE5-A for plug-in at path&br&'~/Library/Application&br&Support/Developer/Shared/Xcode/Plug-ins/Unity4XC.xcplugin' not present in&br&DVTPlugInCompatibilityUUIDs &/p&&p&===&br&BUILD TARGET Unity-iPhone OF PROJECT Unity-iPhone WITH THE DEFAULT&br&CONFIGURATION (Release) ===&/p&&p&Check&br&dependencies &/p&&p&Signing&br&for &Unity-iPhone& requires a development team. Select a development&br&team in the project editor. &/p&&p&Code&br&signing is required for product type 'Application' in SDK 'iOS 10.2'&/p&&p&解决方案:&/p&&p&因为升级之后多了AutoSign选项并默认开启导致证书和签名设置不正确导致。&/p&&p&&br&&/p&&ul&&li&Animator性能的问题:&/li&&/ul&&p&为每个角色制作一个Animator&br&controller同为所有角色制作一个Animator controller并采用Animator controller&br&override去填充每个角色动画这两种方式的问题: &/p&&p&1-相同状态机结构下,两者之间在内存占用上,哪一种会更多? &/p&&p&2-相同状态机结构下,哪一种占用cpu会更多? &/p&&p&3-部分角色用不到全部的动作,如果不指定这些动作,是否会在内存占用以及cpu占用上更省? &/p&&p&4-一个角色一个独立animator&br&controller与一个角色独立animator controller并且使用Animator controller&br&override去替换自身动作在效率上有没有损害 &/p&&p&5-能否比较详细的描述下Animator&br&controller,Animator controller override的工作原理以及内存占用,cpu占用方面的详细情况&/p&&p&解决方案:&/p&&p&官方反馈如下。&/p&&p&第一和第二个问题:内存方面,使用Animator&br&override&br&controller会更加节省内存,开发效率上也会更高,cpu占用差异两者基本可以忽略。动画的瓶颈大多都在计算骨骼和skin上。如果使用blend&br&tree的话会有动画融合的消耗。特别的,使用一个大型、复杂的状态机(animator controller)需要注意其初始化开销。&/p&&p&第三个问题:&/p&&p&是的,理论上越精简的controller是会占用更少的资源的。不过因为不同角色使用相同的animator&br&controller并不会增大内存,角色只是引用了controller,而如果新建一个精简的controller则会有额外的内存消耗。所以是否新建controller需要斟酌一下。&/p&&p&第四个问题:&/p&&p&对于不同的角色使用animator&br&controller,我们建议的最佳实践是:尽可能简化animator controller的内部逻辑,可以适当把不同逻辑放在多个animator&br&controller中,再使用Animator controller override去动态替换animation&br&clip;而不要使用一个大型的、复杂的、全能的、包含所有逻辑的animator controller。&/p&&p&第五个问题:&/p&&p&简单来说,Animator&br&controller是一个动画状态树。而blend tree则类似于ue和cryEngine的blend space。Animator&br&controller如果使用blend tree的话,则内存占用会多一些。&/p&&p&Animator&br&override controller可以简单理解为一个实例化的animator controller,所以在内存占用上会小于它所引用的animator&br&controller。&/p&&p&PS:最后发现使用Animator性能开销还是比较高,并且把Animator下面的树删光开销也没有明显下降。最终还是把很多简单的动作改为了Animation。&/p&&p&&br&&/p&&ul&&li&我们不但使用了Bugly来收集错误和crash,还使用了Unity官方的GAMEPERFORMANCE,但是升级5.5之后虽然不用集成插件了,但是也不能自定义版本号和玩家ID了,这样就不能进行一些过滤甚至开发过程中编辑器出现的临时error也会上报,很是不方便。&/li&&/ul&&p&解决方案:&/p&&p&升级之后确实没有了,只能当作一个feature反馈,希望能早日开发。&/p&&p&&br&&/p&&ul&&li&魅蓝3S会无限旋转。&/li&&/ul&&p&解决方案:&/p&&p&确认是陀螺仪的问题导致,Unity开启陀螺仪在魅蓝3S上就会无限旋转,其他游戏有会有这个问题。可以在这个设备上关闭陀螺仪。&/p&&p&&br&&/p&&ul&&li&游戏开始时切出去,登陆画面会变窄&/li&&/ul&&p&解决方案:&/p&&p&确认是开始时切出去会连续切换两次分辨率。修改相关代码加判断防止切换两次。&/p&&p&&br&&/p&&ul&&li&Unity物理相关的崩溃:&/li&&/ul&&p&1#00 pc cbea16b0 &unknown& &/p&&p&2#01 pc 006a1920 libunity.so CastFilter::preFilter(physx::PxFilterData&br&const&, physx::PxShape const*, physx::PxRigidActor const*,&br&physx::PxFlags&physx::PxHitFlag::Enum, unsigned short&&)&br&[armeabi-v7a] &/p&&p&3#02 pc 00f32090 libunity.so&br&MultiQueryCallback&physx::PxOverlapHit&::invoke(float&,&br&physx::Sq::PrunerPayload const*, unsigned int) [armeabi-v7a] &/p&&p&4#03 pc 01053f90 libunity.so BucketPrunerOverlapTraversal&OBBAABBTest_SIMD,&br&false&::operator()(physx::Sq::BucketPrunerCore const&, OBBAABBTest_SIMD&br&const&, physx::Sq::PrunerCallback&, physx::PxBounds3 const&)&br&(.part.26) [armeabi-v7a] &/p&&p&5#04 pc
libunity.so&br&physx::Sq::BucketPrunerCore::overlap(physx::Sq::ShapeData const&,&br&physx::Sq::PrunerCallback&) const [armeabi-v7a] &/p&&p&6#05 pc 0104ce88 libunity.so physx::Sq::AABBPruner::overlap(physx::Sq::ShapeData&br&const&, physx::Sq::PrunerCallback&) const [armeabi-v7a] &/p&&p&7#06 pc 00f3383c libunity.so bool&br&physx::NpSceneQueries::multiQuery&physx::PxOverlapHit&(physx::MultiQueryInput&br&const&, physx::PxHitCallback&physx::PxOverlapHit&&,&br&physx::PxFlags&physx::PxHitFlag::Enum, unsigned short&, physx::PxQueryCache&br&const*, physx::PxQueryFilterData const&, physx::PxQueryFilterCallback*,&br&physx::BatchQueryFilterData*) const [armeabi-v7a] &/p&&p&解决方案:&/p&&p&升级Unity的物理引擎之后解决,应该是Physx的bug。&/p&&p&&br&&/p&&ul&&li&使用il2cpp的包比mono的大12M。&/li&&/ul&&p&解决方案:&/p&&p&因为会额外生成一些代码所以il2cpp会比mono大,官方提供一些缩小包体的建议&/p&&p&&a href=&/?target=http%3A///Manual/ReducingFilesize.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/Manual&/span&&span class=&invisible&&/ReducingFilesize.html&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///Manual/iphone-playerSizeOptimization.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/Manual&/span&&span class=&invisible&&/iphone-playerSizeOptimization.html&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///threads/il2cpp-build-size-improvements.322079/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/threa&/span&&span class=&invisible&&ds/il2cpp-build-size-improvements.322079/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&ul&&li&ANDROID的包在固定设备上,华为荣耀3X上启动黑屏闪退。&/li&&/ul&&p&解决方案:&/p&&p&只有这台设备会出现,存在兼容性问题。测试编译使用IL2CPP并且不开启Development开关不会闪退,使用mono或者开启Development必然闪退,可以保证release版没问题。&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&
开发中遇到了很多比较奇怪和难解决的问题,这里进行了一些记录,很多问题得到Unity官方技术支持同学的大力帮助,非常感谢! Unity5.5.1p2版本,IL2CPP切到后台可能会报错:EGL Unable to acquire context EGL_BAD_NATIVE_WINDOW a nativewindowtype argumen…
&h2&&b&什么是优化&/b&&/h2&&ul&&li&&b&为了达成相同目标,寻求并采用消耗更少资源的办法的过程&/b&&/li&&/ul&&p&对游戏来说通过特别的技巧,在实现相同的表现效果、流畅度的前提下对硬件机能的需求更低、更平民化。或者在相同性能的平台上,实现更好的画面表现效果、流畅度。&/p&&p&是追求极致。&/p&&p&&br&&/p&&ul&&li&&b&包括CPU,GPU,内存,闪存,网络等&/b&&/li&&/ul&&p&一般来说优化主要针对硬件因此分类也和硬件相关。此外优化也和职责相关,程序需要对代码优化,美术需要对资源优化,策划也需提供一些策划上的方案避免性能开销。&/p&&p&&br&&/p&&ul&&li&&b&一个永恒不变的话题&/b&&/li&&/ul&&p&人的欲望是无止境的,玩家的需求和项目的需求永远在不断增长。优化永无止境。&/p&&p&&br&&/p&&h2&&b&优化方法&/b&&/h2&&ul&&li&&b&根据性能指标设定优化目标&/b&&/li&&/ul&&p&没有目标就没有方向我们首先就是设立优化目标,这也是一种通用的优化方式。不仅仅针对Unity。&/p&&p&一般游戏的性能指标有:帧率,稳定性(卡顿),等待时间(Loading),内存占用(手机上最重要指标,绝大部分闪退的原因,理想值是内存占用低于150M),安装包大小,网络延迟,网络流量,耗电量(手机比较重要,限帧)等等。&/p&&p&例如可以订我们的目标是在低配机型红米上可以稳定30帧运行内存200M以内,在中配机型上稳定在45帧运行实现主流游戏效果内存300M以内,高配机型上60帧稳定运行实现次世代效果内存。&/p&&p&&br&&/p&&ul&&li&&b&根据性能指标设定优化目标&/b&&/li&&/ul&&p&一般来说游戏优化也遵循28原则,游戏优化又是很费时费力的一件事,我们需要找出性能瓶颈。按照优先级来进行优化。&/p&&p&望闻:根据优化目标,先大概分析一下性能指标。包括帧数多少,是否稳定,是否存在卡顿。较长时间运行,发热量如何,是否存在闪退。安装包多大。网络流量多大等。找到最优先需要解决的点。&/p&&p&问:询问相关开发人员性能热点大概从什么时候开始出现。我们之前的项目在开发到中后期会找测试同学测试每日构建的版本,及时监控性能指标,第一时间发现性能瓶颈,发现越早越容易优化。&/p&&p&切:通过一些工具分析来进行深度的分析,必要时需要自己开发分析工具,定位热点。&/p&&p&&br&&/p&&ul&&li&&b&优化性能热点&/b&&/li&&/ul&&p&找到性能热点指点之后工作就已经完成一大半了,然后针对热点指定方案优化。下面先介绍一些常用的分析工具。&/p&&p&&br&&/p&&h2&&b&优化工具&/b&&/h2&&ul&&li&&b&Unity Profile&/b&&/li&&/ul&&p&最常用的性能分析工具,官方自带可编辑器可连真机,不做过多介绍。&/p&&p&&br&&/p&&ul&&li&&b&Xcode&/b&&/li&&/ul&&p&苹果的性能分析工具,在IOS平台上是最好的选择。&/p&&img src=&/v2-01d3a06020f9ccd190ac746e9cdc00c2_b.png& data-rawwidth=&1026& data-rawheight=&360& class=&origin_image zh-lightbox-thumb& width=&1026& data-original=&/v2-01d3a06020f9ccd190ac746e9cdc00c2_r.png&&&p&&br&&/p&&ul&&li&&b&UWA&/b&&/li&&/ul&&p&有本地工具(详见使用使用UWA&br&GOT优化Unity性能和内存)和在线版。它通过自动化工具收集Unity&br&Profile的数据,并结合人工进行测试分析。可以提供一些采集分析过的性能数据和优化建议。&/p&&img src=&/v2-93b7bbaab9abde1c5ffcc5_b.png& data-rawwidth=&664& data-rawheight=&312& class=&origin_image zh-lightbox-thumb& width=&664& data-original=&/v2-93b7bbaab9abde1c5ffcc5_r.png&&&p&&br&&/p&&ul&&li&&b&ADB & AndroidStudio&/b&&/li&&/ul&&p&有时也会在Android设备上直接查看性能数据,日志等。&/p&&p&&br&&/p&&ul&&li&&b&Unity Frame Debugger&/b&&/li&&/ul&&p&Unity自带的图形调试工具。功能相对较弱,不过因为集成在了Unity中,使用方便。&/p&&p&&br&&/p&&ul&&li&&b&Xcode GPU Frame Caputre&/b&&/li&&/ul&&p&苹果平台下图形调试最好的选择。&/p&&p&&br&&/p&&ul&&li&&b&Adreno Profiler&/b&&/li&&/ul&&p&高通的GPU调试工具。使用Mono开发,特别介绍一下,这是唯一可以比较方便导出渲染资源的工具,可以在不破解的情况下扒取游戏贴图,模型,Shader等资源。不过导出的资源会丢失一些信息需要工具还原。提供记录渲染API和回放分析,小米2小米4都可以使用,需要安装AndroidSDK,使用Adb连接。&/p&&img src=&/v2-89ba48e5c2c18cf95185_b.png& data-rawwidth=&680& data-rawheight=&388& class=&origin_image zh-lightbox-thumb& width=&680& data-original=&/v2-89ba48e5c2c18cf95185_r.png&&&p&&br&&/p&&ul&&li&&b&GPA&/b&&/li&&/ul&&p&Intel的开发工具,DX版本的工具就非常强大(详见使用英特尔GPA优化《轩辕传奇》游戏的性能),现在也有OpenGL版本,使用方法类似。和DX版本兼容性非常好一样,各种GPU的手机基本都可以使用,不过一些深层次的性能分析只有Intel自家芯片才支持。。&/p&&img src=&/v2-6acfe9f3588ca82cebfb0a_b.png& data-rawwidth=&1920& data-rawheight=&1040& class=&origin_image zh-lightbox-thumb& width=&1920& data-original=&/v2-6acfe9f3588ca82cebfb0a_r.png&&&p&&br&&/p&&ul&&li&&b&NVIDIA Tegra Graphics Debugger&/b&&/li&&/ul&&p&Nvidia公司的分析工具,前身是大名鼎鼎的PerfHud,代替了PerfHud&br&ES。功能强大使用方便,和PerfHud一样使用的时候不是抓一帧而是实时冻结手机上一帧的显示,支持实时修改Shader并在手机上显示最终效果。缺点是使用Tegra的设备比较少,小米3和小米平板。&/p&&p&&br&&/p&&ul&&li&&b&Memprofile&/b&&/li&&/ul&&p&Unity官方出的内存分析插件。&/p&&img src=&/v2-2efdcbdcb2b9fe25edca067c_b.png& data-rawwidth=&712& data-rawheight=&412& class=&origin_image zh-lightbox-thumb& width=&712& data-original=&/v2-2efdcbdcb2b9fe25edca067c_r.png&&&p&&br&&/p&&ul&&li&&b&其他&/b&&/li&&/ul&&p&每个显卡厂商都有自己的分析工具:一般都是基于驱动层。另外开发过程中还会开发很多自己开发的性能分析工具和集成一些插件,例如BuildReport,WeTest&br&Cube,Emmagee等等。&/p&&img src=&/v2-457b5bb2b746fe2b8008d_b.png& data-rawwidth=&686& data-rawheight=&422& class=&origin_image zh-lightbox-thumb& width=&686& data-original=&/v2-457b5bb2b746fe2b8008d_r.png&&&p&&br&&/p&&ul&&li&&b&最后使用这些工具能干什么&/b&&/li&&/ul&&ol&&li&实时显示游戏运行时CPU,OpenGL&br&
runtime以及GPU上的性能数据。同时支持多种3D流水线的override模式。&/li&&li&可以看到3D流水线的渲染过程,API的调用过程,Shader的源代码和指令个数,使用的贴图格式等信息,mesh信息&/li&&li&可以分析DC是否过多,渲染状态是否调用过多,是否可以合并或者排序,地形,场景,角色,UI,后期处理等占比来定位性能热点。&/li&&li&可以分析贴图是否过多过大,是否使用显卡支持的压缩格式&/li&&li&Override模式下。Null Driver, Null&br&
Hardware,看定位性能是否在GPU上。关闭渲染或者一些相关API来定位性能瓶颈。例如ps,1像素贴图等&/li&&li&可以看一些工具提供的Shader优化建议,也可以修改Shader实时发送到设备,既可以分析其他游戏shader也可以自己调试。&/li&&li&分类开关不同类型的对象定位性能瓶颈。监控内存,当前引用资源数据,网络延迟,内存池开销等&/li&&li&等等&/li&&/ol&&p&未完待续...&/p&
什么是优化为了达成相同目标,寻求并采用消耗更少资源的办法的过程对游戏来说通过特别的技巧,在实现相同的表现效果、流畅度的前提下对硬件机能的需求更低、更平民化。或者在相同性能的平台上,实现更好的画面表现效果、流畅度。是追求极致。 包括CPU,GPU…
&p&下面介绍一下具体的优化方式,按照硬件划分分为CPU,GPU,内存&硬盘。&/p&&p&&b&CPU&/b&&/p&&ul&&li&&b&Top10&/b&&/li&&/ul&&p&使用Profile找到CPU占用最靠前的函数,从最高的开始依次分析优化。定位的方法有很多,Unity的Profile,UWA的性能测试工具,比较推荐的是使用XCode,可以抓取一段时间内函数的开销。更品均准确也可以看到更底层。&/p&&img src=&/v2-4b1d4adf0bfba2cd193f31_b.png& data-caption=&& data-rawwidth=&938& data-rawheight=&334& class=&origin_image zh-lightbox-thumb& width=&938& data-original=&/v2-4b1d4adf0bfba2cd193f31_r.png&&&p&如过函数比较复杂可以使用BeginSample/EndSample拆分,我在项目里通过添加条件编译进行了封装类似:MDebug.BeginSample(&Character.TakeDamage&);&/p&&p&这样可以跟随意和高效的定位到关心的地方。下面列举部分比较通用的优化方案。&/p&&p&&br&&/p&&ul&&li&&b&LOD,代码只在必要时才会运行&/b&&/li&&/ul&&p&最常用的优化方式。例如屏幕外的角色不计算动画更新,不计算技能效果冒字血条等,屏幕外的角色休眠,只有主角才会冒字等等。还可以做一些LOD,例如AI可以做行为树lod,动画LOD,粒子特效LOD,更新频率LOD(更新频率随着游戏帧率,离主角的距离,重要程度,视锥,类似CSM的提醒分段,以及周围的角色个数动态调整。例如轩辕城擂台,同屏高配200人,未优化在68帧左右优化的后到94帧左右)&/p&&p&&br&&/p&&ul&&li&&b&限帧,负载均衡&/b&&/li&&/ul&&p&为了降低耗电发热量我们会根据玩家机型进行限帧。另一方面我们将逻辑帧和渲染帧分开执行,逻辑代码以更低的帧率执行,部分逻辑也可以使用线程,负载均衡分段计算等方法提升性能。&/p&&p&&br&&/p&&ul&&li&&b&算法&/b&&/li&&/ul&&p&一些代码本身的运算。例如优化物理运算,空间换时间使用查表预计算等方式对计算提速,减少频繁索引FindGetComponentd以及各种运算,优化遍历利用稀疏矩阵九宫四叉树等等。&/p&&p&&br&&/p&&ul&&li&&b&服务器计算或者客户端计算&/b&&/li&&/ul&&p&根据不同类型的游戏也会调整一些运算是在服务器还是客户端,如果服务器性能强大可以让服务器计算物理,寻路,AI,战斗逻辑等复杂运算,客户端只要变现即可,特别是MMO的项目。而如果希望服务器开发较少提升开发效率和降低服务器性能要求,也可以将绝大部分运算放在客户端,例如帧同步的游戏我们就采取的这种方式。当然有时候也是两者相结合并没有绝对标准。&/p&&p&&br&&/p&&ul&&li&&b&Unity接口&/b&&/li&&ul&&li&OnGUI,FixedUpdate,Update等空函数也会有gc开销,因为会产生从C++到C#层调用的开销。&/li&&li&MainCamera是一个遍历操作Camera比较多的时候不要频繁调用。&/li&&li&尽量少使用GetComponent,AddComponent(还会产生GC),Find等操作。&/li&&li&使用Unity5.6有个新函数SetPositionAndRotation。因为Transform的Position每次脏了会有一次消息,Rotation也会有,并且会开一个线程来做这个操作极大提升性能。所以最好每帧只设置一次,并且使用SetPositionAndRotation一次性设置可以提升一倍的性能开销。&/li&&li&其他。&/li&&/ul&&/ul&&p&&br&&/p&&ul&&li&&b&物理&/b&&/li&&/ul&&p&Unity使用PhysX作为物理引擎,本身优化还是很好的,会做空间划分。Unity官方建议碰撞对小于100,其实这个标准非常严苛,我们测试在300左右物理的开销还是蛮少。优化方面可以通过分层减少碰撞对,尽量使用BoxCollider而不是MeshCollider,UI界面不需要点击的控件不要打开Raycaster。因为我们只使用了最基本的射线检测,其他物理是自己实现的,主要的优化还是在物理算法上。如过在Profile中发现Physucs.Simulate开销比较大就是物理需要优化了。&/p&&p&&br&&/p&&ul&&li&&b&IL2CPP & C++&/b&&/li&&/ul&&p&把Unity编译设置成IL2CPP,编译成C++版运行效率会有较大提升。还可以把一些运算逻辑放到C++的库里,这样可以优化更极致减少gc。&/p&&p&&br&&/p&&ul&&li&&b&动画&/b&&/li&&/ul&&p&如过Prifile中发现Animator.Update或者MeshSkinning.Udpate开销比较大就说明动作可能需要优化。&/p&&img src=&/v2-f8cf75aea0aef72ffe0d36_b.png& data-caption=&& data-rawwidth=&536& data-rawheight=&260& class=&origin_image zh-lightbox-thumb& width=&536& data-original=&/v2-f8cf75aea0aef72ffe0d36_r.png&&&ul&&ul&&li&优化:打开Optimize&br&
GameObject,可以把一些无效的节点骨骼去掉,注意如果有自定义的节点需要拖到不被优化列表里。&/li&&/ul&&/ul&&img src=&/v2-61cc578053daec7e1ef18a0e101cd427_b.png& data-caption=&& data-rawwidth=&236& data-rawheight=&100& class=&content_image& width=&236&&&ul&&ul&&li&压缩:打开Keyframe&br&
Reduction,可以压缩很多不必要的关键帧,这个值越大压缩比率越高失真越严重。&/li&&/ul&&/ul&&img src=&/v2-aa9bf12e39a64a5fe28c2e32cc6ce289_b.png& data-caption=&& data-rawwidth=&260& data-rawheight=&192& class=&content_image& width=&260&&&ul&&ul&&li&BoneWeights:顶点受骨骼影响,对要求不高的环境可能一个骨骼就够了。可以每个模型设置,也可以实时全局改变。&/li&&/ul&&/ul&&img src=&/v2-bb533ac68e14f337bc7bddb_b.png& data-caption=&& data-rawwidth=&292& data-rawheight=&74& class=&content_image& width=&292&&&ul&&ul&&li&BakeMesh:对于同屏需要显示大量模型可以使用SkinnedMeshRenderer.BakeMesh,把动画烘成模型,这样在渲染的时候可以合并(带动画不能合并)。可以大幅减少DC,省去蒙皮计算,不过缺点是内存增大,增加DynamicBatching的CPU开销,表现会差一些。&/li&&li&不使用Animator:Animator的开销比Animaton比一个量级。&/li&&li&不可见不更新设置CullCompletely,但是需要注意一些消息也会停掉如果对动画有依赖会出问题。&/li&&li&其他:骨骼LOD,GPU Skinning(有些设备和情况会更慢),使用Bone代替CS等等。&/li&&/ul&&/ul&&img src=&/v2-c46a885a3958f0bafd5c79bdb9275562_b.png& data-caption=&& data-rawwidth=&328& data-rawheight=&348& class=&content_image& width=&328&&&p&&br&&/p&&ul&&li&&b&UI&/b&&/li&&/ul&&p&UI也是个开销大头,一般会占到30%-50%。UGUI对应Profile中Canvas.BuildBatch &&br&Canvas.SendWillRenderCanvases开销,类似NGUI的LastUpdate,UI的优化又很多文章这里也简单列举一下。&/p&&ul&&ul&&li&动态静态分离:因为UI会合并。NGUI是按Panel进行重建的、UGUI是按Canvas进行重建的,防止动态UI触发合并导致静态UI也一起合并。&/li&&li&预加载,常驻,即时释放:UI按类型划分,比较大的常用的UI在创建的时候会卡顿,可以进行预加载。主城到战斗场景,在保证峰值内存的情况下,将英雄界面工会界面等常驻内存,可加快Loading速度,实测优化后提升一倍以上loading速度。其他不常用界面拆分成小界面,使用即时加载,关闭时卸载节省内存。需要注意的是,UI节点过多也会导致加载缓慢,我们曾经Loading要10秒,其中序列化UI占了一半左右的时间(贴图预先加载测试),减少UI节点数,太大了拆开。&/li&&li&图集:合理拆分UI图集,区分公共图集(常驻)和非公共图集。太大容易造成冗余加载,容易导致内存占用过大,导致内存显存交换开销。太小有容易导致显存碎片影响效率。规则很复杂。&/li&&li&内存池:UI冒字等频繁创建的UI使用内存池减少创建的时间和内存碎片。&/li&&li&Active/Deactive:不推荐通过Active/Deactive来频繁切换UI界面,因为会触发UI合并操作,可以通过移到屏幕外的做法或者设置Layer。但需要注意移到屏幕外还是会被合并渲染,如果是长时间不显示的还是Deactive比较好需要视情况而定。&/li&&li&UISprite来代替UITexture:Texture不会合并。&/li&&li&不移动不可见的UI不更新:例如血条名字等。&/li&&li&layout group, canvas group组件,任何子节点变了父节点都会用getcompent找到laygroup。这是Unity的UGUI的两大坑。&/li&&li&检查不需要拾取的Raycast target是否关了。&/li&&li&资源预加载:例如前面介绍的UI预加载,内存允许的情况下所有资源都应该预加载,结合内存池。我们游戏中所有变现逻辑,角色,怪物,道具,UI都会做预加载,并且有一套池膨胀和回收的策略。&/li&&li&Shader预加载。&/li&&li&等等。&/li&&/ul&&/ul&&p&&br&&/p&&ul&&li&&b&GC&/b&&/li&&/ul&&p&GC是一个非常高开销的系统调用也,是大部分卡顿的主要原因,不能完全控制。因此我们要尽量减少代码堆内存分配过量防止频繁触发GC,同时也可以在Loading或者对性能不敏感的时候主动GC。&/p&&ul&&ul&&li&升级Unity:Unity5.6修改了粒子系统的源码减少了lamda表达式的gc。&/li&&li&减少一些字符串拼接,使用StringBuilder代替string减少GC开销,不要使用富文本改变Text组件的颜色直接通过修改Text组件颜色来改。&/li&&li&内存池:前面说过GameObject的内存池,另外还有类对象的内存池。所有频繁反复创建删除的都应该使用。两个用途,减少加载创建释放的时间,减少内存碎片降低GC的频率。&/li&&li&Unity接口:AddComponent,OnGUI,UI合并频率,delegate,等(一些Foreach,协程等Unity已经优化)。&/li&&li&逻辑优化:避免频繁创建开辟空间。&/li&&li&插件的GC优化:对行为树,FMODStudio等一些插件的源码进行了修改减少GC。&/li&&li&等等。&/li&&/ul&&/ul&
下面介绍一下具体的优化方式,按照硬件划分分为CPU,GPU,内存&硬盘。CPUTop10使用Profile找到CPU占用最靠前的函数,从最高的开始依次分析优化。定位的方法有很多,Unity的Profile,UWA的性能测试工具,比较推荐的是使用XCode,可以抓取一段时间内函数的开…
&p&最近比较慢最后一篇写的有些晚了。最后介绍一下GPU,内存,闪存耗电和网络。因为介绍的比较广,每个点都比较简单,后续可能会针对某些部分做更深的介绍。&/p&&p&&br&&/p&&p&&b&GPU&/b&&/p&&ul&&li&&b&DC&/b&&/li&&/ul&&p&DrawCall实际上优化的CPU的时间,但因为DC的优化一般都是材质mesh合并,所以放到了GPU的部分。每次在准备数据并通知GPU渲染的过程称为一次Draw&br& Call。渲染一次拥有一个网格并携带一种材质的物体便会使用一次Draw Call。可以理解为调用一次DC就换一种画笔在画板上画一个物体。&/p&&img src=&/v2-39f09a2c59f0d50f18a143c8e1b3cb41_b.jpg& data-caption=&& data-rawwidth=&255& data-rawheight=&177& class=&content_image& width=&255&&&ul&&li&&b&多线程&/b&&/li&&/ul&&p&限于篇幅,虽然多线程是CPU的部分但都放在GPU这部分介绍。随着PC的主频达到瓶颈,手机也开始朝多核并行开发的方向前进了。所幸Unity这方面做的比较好,大部分开发者可以不用考虑多线程的开发方式。&/p&&ul&&ul&&li&多线程渲染:虽然叫多线程渲染其实节约的也是CPU时间。虽然CPU和GPU是并行工作的,但是因为CPU提交了渲染数据和指令之后,需要等显卡同步会阻塞逻辑的执行。多线程渲染就是把这个等待时间和逻辑的执行并行了起来。Unity5.5版本在PC和IOS上都默认开启了多线程渲染,但在Android设备上单独提供了多线程选项,这是因为Android系统设备太多碎片化严重,开启多线程会导致一些设备出错闪退等。亲测我们游戏开启多线程渲染后,能提高10%的性能,所以我们是默认开启的。王者荣耀的解决方案比较完善,他们会针对每个机型做大量测试,还和硬件厂商有合作,只针对测试通过的设备开启多线程。所以也会看到一些比较有趣的广告,xx手机对王者荣耀做了优化支持多核,其实只是一个配置参数而已。&/li&&li&GPU骨骼更新:利用GPU计算骨骼降低CPU的开销,但是Android的一些设备因为GPU非常弱(广告只介绍CPU),所以开启之后很多设备性能反而下降了,这个配置默认关闭。&/li&&li&网络多线程:我们是开了一个线程进行网络协议的收发处理,这也是比较常见的。&/li&&li&多线程并行计算:Unity5.6的位置更新其实就是开了线程计算,所以新版本的Unity设置位置和旋转的性能大幅提升。此外音频的计算相对独立也都是在其他线程里计算的。优化时也可以考虑把一些运算量比较大又相对独立的部分放到线程里计算,例如AI。&/li&&/ul&&li&&b&面数&/b&&/li&&/ul&&p&DC&200,面数小于10w是Unity建议。我在14年的测试,在红米1上,当dc超过100性能开始直线下降,面数超过6w面性能开始直线下降。&/p&&p&我们目前场景的标准是整个场景少于10个DC,由美术或插件合并输出,这样虽然不是十分灵活,但因为静态合并会增加Loading时间和内存,动态合并也会增加内存和合并CPU开销,所以还是采取这种优化方式。角色2000面左右,低配1个DC,高配3个DC(描边,实时阴影,主角还有额外的一个因为墙后半透效果)&/p&&ul&&li&&b&LOD&/b&&/li&&/ul&&p&对GPU的优化也可以通过LOD进行,可以通过模型LOD,骨骼LOD,粒子LOD,材质LOD的方式,地形LOD等等,例如不同配置开启不同的效果,开启后处理等。&/p&&ul&&li&&b&遮挡&/b&&/li&&ul&&ul&&li&遮挡剔除:顾名思义就是被遮挡看不见的地方不渲染,例如墙后的物体。遮挡剔除可以CPU计算也可以GPU计算。Unity自带了OcclusiongCulling,但5.x不建议使用。&/li&&li&UI遮挡:例如全屏UI可以隐藏背景,节省电量。&/li&&li&场景拆分:我们因为是俯视角,能遮挡的东西很少,只是采取了场景分割,小物件LOD的方式。&/li&&li&入口:一般用于室内,早起的Quick使用了二叉树和入口的优化方式。&/li&&/ul&&/ul&&li&&b&半透明&/b&&/li&&/ul&&img src=&/v2-d5f461b9ce6e354dcedf1_b.jpg& data-caption=&& data-rawwidth=&599& data-rawheight=&278& class=&origin_image zh-lightbox-thumb& width=&599& data-original=&/v2-d5f461b9ce6e354dcedf1_r.jpg&&&p&相对不透明半透明开销巨大,在PC和手游上都是,还会破化渲染管线的优化。另外使用alpha通道的贴图压缩也很困难(特别是IOS上的PVR格式Alpha像素压缩之后损失巨大,ETC,DDS,PVR等格式Alpha一个通道的压缩比就等于其他3个通道了)。半透明物体不写Z无法做像素级遮挡,需要做混合操作,半透明需要单独排序。以下有一些比较通用的优化点;&/p&&ul&&ul&&li&少用/减小面积:尽量少用,要用尽量减少占用屏幕的面积,减少像素填充率。&/li&&li&这里要说的是PowerVR的平台AlphaTest比AlphaBlend开销更高。因为会影响HSR(Hidden Surface Removal)优化,类似EarlyZ,和其他平台不同。&/li&&/ul&&li&&b&Culling&/b&&/li&&/ul&&p&这个其实也是优化的CPU。每个相机都会针对场景图做Culling,通过视锥和包围盒剔除这个摄像机看不见的物体,减少实际渲染物体个数。因为Culling操作比较耗时,也可以通过减少摄像机下对象的个数或者手工开关分层来做优化。这里需要注意的是,合并方式也会影响Culling,例如把整个游戏所有的树的都合并成一个DC,DC是下降了,但是只要有一棵树在摄像机里,所有合并的树模型都会被渲染,增大了渲染的带宽和负载需要权衡使用。例如手游穿越火线就是把整个场景优化成了3个DC,一个DC渲染所有地形,一个渲染所有的墙,一个渲染所有的箱子等。&/p&&ul&&ul&&li&&b&粒子&/b&&/li&&/ul&&/ul&&img src=&/v2-b82cc63c66d132d1e86c83aeb6d5ac2d_b.jpg& data-caption=&& data-rawwidth=&400& data-rawheight=&404& class=&content_image& width=&400&&&ul&&ul&&li&减小屏幕覆盖面积&/li&&li&避免使用Alpha&/li&&li&合并材质和mesh&/li&&li&LOD:根据机型或者距离降低粒子发射

我要回帖

更多关于 g helper手游是真的吗 的文章

 

随机推荐