如何在unity cpu usage制作的游戏中添加一个CPU检测器

游戏引擎 Unity 的入门易精通难体现在哪?为什么?
来源:互联网
Unity入门易:1、渲染对象上挂一个脚本组件就可以驱动该对象的逻辑,基于MonoBehaviour的脚本一上来就把初始化(Awake、Start),更新(Update、FixedUpdate)的接口留好了,初学者完全不用考虑程序框架一类的问题,直接填空就行。很像做早期flash游戏的感觉。2、编辑器非常强大,所见即所得的编辑方式,可以随时暂停、单帧执行游戏逻辑,提供场景和游戏多个窗口实时调试,观察效果。脚本组件面板上可以实时看到所有变量的当前值,这对于调试游戏逻辑非常方便。3、3D引擎功能很完善,与我们自研了5,6年的3D引擎相比,还是远远甩我们一大截,除了支持前向和后向的多种渲染管线,各种后渲染效果,还内置基于Beast的LightMap烘焙、基于Umbra的遮挡剔除这些商业中间件,要知道单采购这些中间件就得好几十万RMB,因此就算是个3D新手,要做个炫酷的3D效果也不是很难。虽然在渲染效果上可能比不上Unreal,Cry,但是U3D这玩意在中国,就算是免费的了,再说用U3D基本也是要发移动平台,目前的3D效果已经很够用。4、游戏其他方面的组件也很丰富,有基于PhyX的物理系统,你要做点什么疯狂小鸟、割绳子之类的游戏,真是很容易。另外还有基于NavMesh的导航系统、音乐音效系统(做音效的是FMOD的前开发者)等。5、良好的开发者社区生态系统。Unity最NB的就是建了个Asset Store,全世界的UNITY开发者在这里卖自己做的各种代码、组件、美术资源,分享经验。因此,学习成本大大降低。6、一键发布到各种平台,包括IOS、Andriod、WP、网页、Windows、Mac等,如果不是要接入其他平台相关的库(如内购等),几乎完全不用学习平台相关的编程知识(Object-C, Java等)7、作为证明Unity入门易的一个例子,本人在刚开始学Unity时,用了一个半月的业余时间,做了个推币小游戏,放在AppStore上,一个月基本上能收个几千块钱。给个链接吧,不算广告啊,只是说明下1个半月业余时间用Unity能做个什么样的出来:--------------------------------------------------------------------------------------------------------------------------------Unity精通难:1、基于MonoBehaviour的脚本,用得太顺手会有有很大的架构风险,你会情不自禁的A组件引用B组件,B组件又引用A组件.....项目一大写成一团乱麻。当然用其他引擎,其他语言也有这问题,但UNITY的一些特性必须用MonoBehaviour类来使用,所以要设计一个健壮的MVC架构需要顶住很多诱惑,绕一些弯。2、基于MonoBehaviour的脚本,组件的初始化顺序无法明确,这个坑也有回答提到了。3、底层代码不开源,尤其是Asset Store上卖的东西那帮开发者也习惯弄个dll封装起来,因此,一些底层修改需求没法改,有时候很头疼。4、C#的GC问题,这个不能说是Unity的错,C/C++的开发者会在长期的工作中变得对内存敏感,而C#开发者会弱得多,但游戏恰巧又是个内存敏感的应用程序。因此,开发者需要对C#的内存分配时刻非常敏感,否则就会出现频繁GC导致的顿卡现象。这里尤其要注意在每帧更新时的小内存分配。这方面要善用UNITY自带的内存和性能分析工具。5、Unity3D毕竟是个3D引擎,3D图形学知识毕竟门槛很高,要深入的做一个项目,需要对3D知识了解得很深,因此,在开发一些大型项目时,新手往往对于3D的各种需求和问题,如果Unity官方没有,或者Asset Store里找不到,就感到棘手。6、最大的坑!IOS发布时遇到跟AOT编译有关的运行时异常。简单说就是Unity采用mono对C#进行跨平台编译,但在iOS平台中,Mono是以Full AOT模式运行的,无法使用JIT引擎,于是引发了这个异常。所以经常出现的情况是在PC和Andriod上游戏都跑得很好,但在iOS平台会在运行时当掉!具体限制请参照:7、作为证明Unity精通难的例子,我司跨时代炫酷国际大作秒杀Appstore前20的Unity项目,做了大概8个月了吧,估计要出来还得小1年....--------------------------------------------------------------------------------------------------------------------------没想到真的已经过了一年了......我们的项目叫《进化:启示录》,目前在XY越狱平台提供试玩版下载
虫母简单—在线播放—优酷网,视频高清在线观看
/v_show/id_XMTI4MjQ3OTY0MA==.html?from=y1.2-1-99.3.5-1.1-1-1-4-0
巨臂丧尸容易—在线播放—优酷网,视频高清在线观看
/v_show/id_XMTI4MjQ3OTY1Mg==.html?from=y1.2-1-99.3.4-1.1-1-1-3-0
============================================================================跟这一年伴随的还有一个叫《坑.xlsx》的文件:祝各位好运!
为什么入门简单,看一下官网的文档和视频教程就知道了,看完几段视频和例子就能让初学者做出能玩的东西,其他同类商业引擎都做不到。物体+组件的结构,所见即所得的编辑方式,都把初学者的门槛降到了最低。再说说难精通的体现。其实任何可以拿来做高大上酷炫屌游戏的商业引擎都是难精通的,这个由引擎的功能深度和泛用性决定。一个集成了无数商业中间件的引擎,包括动画系统、GUI、光照系统、寻路、物理等各个部分,任何一部分单独拿出来都需要用户用心掌握。从这个角度来说Unity和Unreal基本是差不多的。那么Unity特有的坑有哪些呢?1. 脚本执行顺序:MonoBehavior是Unity组件系统的核心,离开这个类所有易上手和高效开发的特性都无法施展。但多个组件脚本的执行顺序控制始终是令人头痛的问题。不了解这一点的用户很容易陷入各种隐藏bug的泥沼。2. 组件式功能结构给每个人更大的控制权力,但无法很好的区分团队不同成员的责任。相比Unreal把编程分为C++,UnrealScript和Kismet三层的做法,Unity让每个开发者都能看到脚本源码并在需要时进行修改。对于独狼开发者来说非常方便,但如果一个游戏逻辑同时可能受到脚本程序、prefab参数配置和场景引用关联三方制约,维护起来就非常的乱,出了问题也很难第一时间分清责任。3. 内存分配和垃圾回收造成的效率问题初学者很难了解。Unity的一个重要特征就是为了让整个引擎有更广的受众,故意隐藏了很多复杂的使用方法。比如说全自动的垃圾回收,就是为了让不懂内存分配的用户也能无障碍使用。但很快进阶一点的用户就会发现大量运行时垃圾回收造成的拖慢,以至于成为一个入门必经的陷阱。如果能在官方文档里告诉用户哪些操作会分配内存,情况会改善许多。4. 功能迭代推新迅速,造成大量不成熟不完善的工作流程。这一点很难说是缺点,毕竟能第一时间用到酷炫的新功能对很多用户来说是求之不得的,当然如果你是商业项目的技术负责人就要小心了。一般来说,官方推出的功能至少要在一年后稳定性和适用性才会超过Asset Store上的同类第三方插件。总的说来,由于优秀的可扩展性,上述这些问题都不致命。总有人在制作优秀的工具来弥补这个引擎的各种不足。而配合其天下无敌的易用性,unity整体的技术方向是非常成功的。
接触Unity一年多,参与过两款上线游戏的开发(iOS/Android)。根据个人感受回答一下。细节中有错误的地方欢迎指正。个人认为Unity相比于其他引擎易用性较好的原因主要有:基于组件(Component)的关卡设计更符合直觉Unity通过将系统或用户的脚本抽象为可重用的组件(Component)并附着在游戏对象上来控制游戏的行为。相较于传统的基于脚本的开发方式,关卡设计师可以更灵活、更快速地搭建界面和关卡,有一种“搭积木”的感觉。虽然这种设计牺牲了一部分扩展性(例如难以实现嵌套Prefab),但对初学者来讲是非常友好的。虚幻引擎4.7版本的更新也效仿Unity,向组件化的方向靠拢,使关卡结构更容易理解和维护。使用Mono作为脚本运行的平台C#/Mono相比C++和其他脚本语言,有更好的稳定性和抽象能力,有容易使用的.NET框架和易于移植的各类开源库,相对完善的语言服务(如GC和反射)也使开发复杂逻辑容易许多。虽然降低了门槛的同时也让低质量的代码更容易产生,但不管对于初学者还是老鸟来说,我觉得都是利大于弊的。引擎本身的功能相对简单 + 丰富的Asset Store插件和虚幻等超级引擎相比,Unity提供的功能算是非常基础的,组件数量和各组件可配置的内容都不多,所以在学习的时候更容易产生比较直观的感受,不至于迷失在细节当中。另一方面,Asset Store模式的成功造就了大量功能强大的第三方插件,填补了Unity开发中的各种空白,进一步降低了开发门槛。而难于精通方面,我觉得主要原因在于:对综合能力要求高首先,不仅对Unity,对任何游戏引擎或者对游戏开发本身来说,想要精通都是很难的一件事。因为游戏客户端开发本身是一项综合性非常强的活动,整合的技术非常多,例如:建模关卡制作脚本逻辑网络通信平台特性集成动画制作特效制作工作流集成调试和优化而对于将这些技术粘合在一起的Unity工程师来说,虽然不需要精通方方面面,但将团队成员的工作高效率高质量地结合在一起,也是非常考验其能力的,只有长期地,全方面地参与整个开发过程并了解团队成员的工作方式,才能逐渐成长为一名优秀的Unity工程师。举例来说,Unity工程师需要:与设计和美术团队沟通,评估设计对于游戏性能的影响,实现原型,进行各种性能测试。与服务器工程师沟通,确定互相之间的接口和协议内容的细节。Unity本身没有一个Gameplay Framework,场景管理、游戏数据管理等相对底层的框架都需要Unity工程师来搭建,如何减少团队中其他成员的错误实践,是主程序的责任,也很考验其架构能力和对Unity Runtime的理解。一些特效需要自己编写Shader才能实现。动画师和美术团队产生的资产,根据项目的需要常常要自己写Pipeline来导入和进行优化处理。一部分还需要以合适的方式打包,供客户端增量下载,需要对Unity的资源管线有较好的理解才可以。而且看似简单的决定之中,常常蕴含了很多性能上的考量。根据关卡设计师的需要,制作编辑器扩展工具,提高其工作效率。这方面的文档稀少,同时也需要对Unity独特的序列化机制有比较深的理解才行。想利用iOS和Android以及各种平台特有的功能时,需要针对特定的平台编写一些Native插件,如本地Push通知,自定义系统键盘,系统弹窗等等。要懂一些iOS开发和Android开发的知识才能驾驭。有些做Unity的工程师可能只是搭建关卡,写一些控制脚本,而优秀的Unity工程师的价值往往在于其能够承担更多的团队职责。所以说想要精通这些,真的需要付出很多的时间和努力才行。难在细节任何事想精通,细节都是非常重要的,比如:内存管理避免和排查脚本中的内存泄漏。例如没有清空的委托和静态闭包造成的引用。优化GC,了解Mono和.NET GC算法的差别。比如Unity采用的是较老版本的Boehm GC,不分世代,GC分页为1KB,内存碎片无法合并,单线程,缺少LOH,托管堆一旦扩大就很难向系统返还内存。如果按照.NET的思路优化GC,有时候并没有理想的效果。而Unity最近引入的IL2CPP运行时,采用了新版本的Boehm GC,算法又有所改变,优化策略也应适当调整。了解Unity的内存模型,哪些资源分配在Native堆上,哪些分配在Mono的托管堆上。Native上不同种类的资源分别用哪些方法能够释放干净。Native堆上的引用计数是如何工作的。如何减轻Unity自动释放场景时的压力。AssetBundle的内存结构是怎么样的,各个部分如何不依赖GC而精准地释放。暂时隐藏起来的图片或物体如何暂时性地释放,在显示时又如何重新加载回内存。了解哪些API和操作会分配内存,什么时候使用值类型更好或更不好。这都需要对C#有很深入的理解。网络和下载AssetBundle如何打包,什么样的图片用什么粒度打包效率最高。如果使用Json反序列化数据,怎么才能避免内存碎片降低整个App的性能。不断更新的素材需要增量下载,Unity内置的下载方式瓶颈在哪,怎么自己实现一个比Unity内置API更高效的下载机制和更精准的缓存控制机制。脚本执行能够将较复杂的操作(如反序列化数据,较重的IO操作)放在后台线程执行,再调度回主线程更新游戏界面,以避免UI卡顿。Unity的线程优先级又是怎样的?能否理解Unity Coroutine的迭代器本质,怎样对Coroutine中的异常进行处理,如何使Coroutine具有返回值,Coroutine启动时将分配多少内存,为什么复杂的Coroutine会使用更多的内存,如何将多个Coroutine合并为一个从而消除内存分配。在与Native插件(如iOS插件)交互时,如何让C#与Objective C或Java共享内存,从而减少大型数据封送造成的CPU负担。iOS平台上AOT异常的根本原因是什么,有哪几种。值类型和泛型的组合更容易引发AOT异常的原因是什么,如何绕过。怎么安全的使用Linq,使用C#标准事件为什么会触发AOT异常,怎样避免。Mono AOT的trampoline又是什么,哪种风格的代码更容易耗尽trampoline并引发AOT异常。Unity的C#编译器有哪些弱点,哪些代码通过Visual Studio编译成DLL再放到Unity中可以提高执行效率和内存使用效率。场景加载缓慢等Unity内部表现出来的问题如何从自身脚本下手进行优化。或者说不同性能问题在自己代码中的Critical Path都是哪些部分。渲染Draw Call是什么。不同AssetBundle中的小图片如何Batch到一个Draw Call中。移动平台常用的Tile-based GPU有哪些弱点,如何避免。Retina等高清屏幕上制作2D游戏时,如何动态为图片生成最小的Mesh网格以节约fill rate。团队协作自己编写Gameplay框架的情况下,如何控制队友代码中的内存泄漏。使用版本管理系统时会产生哪些难以解决的冲突,如何建立开发规则。自己开发的框架或工具是否能有效避免队友间发生冲突。如何实现资源管线的自动化。如何将各种奇葩动画编辑器的输出转换成Unity标准的动画资源。制作编辑器扩展时,是否能正确序列化复杂的数据结构。能否让自己的工具和脚本也实现所见即所得,让队友更快的搭建场景。是否会使用Gizmo和Handle来扩展场景编辑器。当不得不修改MonoBehaviour的定义时,怎样让已经上线的老版本中的数据正确地反序列化到新版本。要有能力编写模块划分明确,依赖关系合理清晰的可重用代码和组件,作为公司的资产加速新项目的开发。这些都是Unity开发中会不断面对的问题,如果不能从始至终中控制住这些细节,积累起来往往会使团队效率底下,难以产出高质量的应用。所以我觉得Unity难以精通之处就在于对细节知识的把握,以及在整合团队价值的过程中如何做到扬长避短。Unity开发团队中常常不是所有人都会这个引擎有很深刻的认识,大家术业有专攻,有人搭场景,有人做后端,对自己不熟悉的领域,难免有错误的认知和实践。我们尚可以通过时间和努力精通细节,然而到头来真正缺少的,其实是团队成员间的信任所带来的沟通成本的降低。【更新】回答一些朋友的疑问。关于资料来源细节问题很难有系统的资料来源,而像AssetBundle Dynamic Batch这种几乎找不到答案的问题只能自己慢慢摸索。在此列举几个最主要的知识来源。官方手册。例如搜索Unity Optimization可以找到官方在GPU,CPU和Mobile方面的几篇优化手册。官方资料常常包含最核心也最容易被忽略的原则,深入理解往往会有新的收获。官方博客。博客上不时会有一些技术类文章,如关于IL2CPP和序列化机制的知识几乎只能看那几篇博客。Unite的视频和Slide。对某些领域有比较深入的探讨,特别在内存管理,AssetBundle和代码组织方面。YouTube和SlideShare上搜Unite或Unity能找到。值得注意的是Unite的分会场,如日本和韩国,有时会有一些更加深入的分析。如 Unity的Mono fork: ,关于GC和AOT方面是第一手的资料。比如gc的配置,Enumerable类的实现如何导致Linq容易触发AOT异常,以及泛型CompareExchange中存在的JIT Hack导致C#事件和一些线程同步操作触发AOT异常等等。另外GC方面也可以参考 ,有详细的机制解释。UI的源代码: ,修改优化后可以直接集成到游戏中,很方便。随Unity安装的PDB调试文件。Unity的安装目录下其实是有Editor和Player当中所有C++源码的PDB文件的,而且居然都是private PDB。需要探查Unity内部数据结构和过程实现的时候,通过WinDbg配合这些PDB文件调试Unity进程可以获得很多最底层的信息。当然,如果公司买了Unity的源码就不必这样麻烦了。关于优化策略不只是Unity,优化程序最重要的原则就是先测量。而且在没有丰富经验和自信的情况下,不要自己写测量代码,而要依赖Unity自己Profiler和Profiler API。这里只说一些Unity特有的内容。使用Profiler时,切忌猜测。一定要弄清各种数据的精确涵义,如Self %,Self ms,GC Alloc等,如果弄不清楚,优化常常是南辕北辙。另外诊断CPU Spike时,一定要打开Deep Profile,否则只能看到误导性很强的表面数据。找到真正的Hot Line才能着手优化改善性能。当Hot Line在自己的代码中时,可以尝试将CPU密集的操作分派到后台线程,然后在需要与Unity API交互时调度回来。粒度较好的操作可以尝试用Coroutine分派到其他帧分别执行。大量GC Alloc造成的Spike需要重新设计内存分配策略,小对象(目前版本是小于1KB)较多的时候也可以尝试预先扩大托管堆(如分配很多小于1KB的缓冲区,然后再释放),这样可以加速后续内存分配。因为Boehm GC的堆扩展策略是时间线性而非空间线性的,所以每次扩大后的容量都是翻倍的,需要注意。而当Hot Line在Unity API中时,常常是自己的错误实践造成的,需要重新审视设计。一方面要减少昂贵API的调用次数,一方面要降低Unity内部处理数据的规模。例如场景加载缓慢时,可能需要简化场景本身,然后在场景启动后再手动、增量地加载场景中的其他内容。另外要了解一些底层知识。例如App启动时性能较差的原因,在非AOT平台上可能是因为大量的JIT编译造成的,而在AOT平台上则可能是因为初始化代码过于复杂导致CPU缓存命中率很低,和操作系统频繁地Page Fault。这也是为什么启动代码一定要精简,并且要尽量实现批处理。GPU方面,如果没有复杂的特效,瓶颈常常在Draw Call和Fill Rate上。Draw Call需要Batch,能共享的材质一定要共享。Fill Rate的问题通常在高分辨率的2D游戏中比较明显,Profiler中的Transparency渲染占比很大时就应该着手优化。GPU优化策略上Unity相比其他引擎并没有很多特异的方面,准确测量的基础上通常能找到比较通用的解决方法。
入门易是因为它的编程脚本话(非常对象化),这个是核心。然后在这个核心之外,价格因素吸引了很多的开发者和公司。加上它的插件化技术形成了很好的生态环境,因此学习资料比其他引擎多了不止很多两个字就能说的清。这些都形成了入门的门槛很低。精通难是因为3D本身,而不是unity这个工具。
不打算说【入门易】的体现,没觉得入门易。这里只尝试说几点【精通难(坑)】的体现。1. 游戏上线后的逻辑更新问题,主要是游戏上线后的持续开发和BUG修复一类的内容。Unity3D在安卓平台上可顺畅的做到逻辑更新,而在IOS平台上因为FULL AOT的限制,只能借助一些第三方的脚本方案来做逻辑更新,而这些第三方的脚本方案用起来限制多,不舒服是一方面,更要命的就是性能差,有无法绕开的性能瓶颈=&【反射】。故目前看来,IOS平台上的逻辑更新解决方案全都是鸡肋,基本不具备实用价值,除非你只打算做斗地主类型的游戏。2. 底层不开源的问题,这一点前面也都有提到过,一些问题只能靠猜(不停的测试)来解决。3. 整体包大小的问题,这个似乎也没什么好的办法来解决。这一点从去年上线的一些U3D游戏包的大小上可以看出。4. 整体性能优化的问题,不易搞,不了解底层,注定无法采用科学的方式来优化性能。 这一点也可以从去年上线的U3D游戏的表现上看出来。5. 直接的MonoBehaviour脚本式写逻辑,会带来的代码维护和理解上的问题,对开发者的结构设计能力有要求。
入门易:最大限度的不用造轮子精通难:坑多难调,程序员对程序资源内存等掌控度低的让人发指(并非不能提高,而是提高方面成本很高,这也是难点啊)
入门简单是因为u3d editor做得易用,精通难在于因易用而隐藏了更多实现细节和牺牲了部分灵活性。先不说精通,想学深点要做的也和其他技术差不多:掌握好基础知识,边实践边看文档,观摩优秀实现,造轮并改进。说下我用u3d的经历吧。两三年前用u3d做了半年项目,仿2d toolkit和ngui(作者后被u3d收编,出u3d官方ui)插件造轮,用上itween和playmarker插件。因涉及custom editor及无专业游戏开发经验,整个过程遇坑无数。不过unity整个平台还是挺有意思的,editor学得真心酷炫。现在如果要为计算机视觉算法做复杂点的三维demo,一般就用u3d。c dll + u3d c# 配合,杠杠的!
入门易: 很多开发者看下视频,就可以上手开发游戏,甚至不用怎么看官方文档。精通难:大都会碰到以下问题1 代码管理
基于组件式的开发,简单粗暴,但是MonoBehaviour本身是个伪Component,既有数据又有逻辑。在项目稍大一点,就会发现引用乱套,即使用了各种Manager还是无法很好的集中控制一类逻辑功能的脚本。2 内存管理
Mono版本过低,GC本身效率就不高。加上一些api底层会生成额外如string之类的数据。一旦乱用,频繁会触发GC。如果对C#语言掌握不够,错误使用一些方便语法或高级特性也会导致额外内存分配。3 资源管理
为了达到资源动态更新的目的使用Assetbundle,会发现一堆坑。Build,加载,释放等会遇到效率和内存的各种问题。需要不少时间去慢慢摸索,实践。4 功能的不稳定
一般情况下,发布了新功能,大家别急于用 :)5 入门易,很多开发者觉得自己已经掌握了unity的精髓,然后出了各种问题。(以上都是个人观点,无责任。)
如果把跟教程做出个demo叫做入门的话,那确实容易
真心不觉得入门易,当初寻找怎么控制资源的预加载的办法什么的寻找了很久然而最后却放弃了……反正我好鶸,还是去试试Egret或者Cocos2d-js之类的吧……QAQ
Slayer Qix:
脚本简单但是美工难做啊
编辑器直观,所见即所得,所以简单,很快就能写个demo。概念太多,能用的工具太多,可选择的太多,所以难。就好比写字容易,但要写的一手漂亮的字体就。。。。。。
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动Unity3d性能优化(CPU) - 简书
Unity3d性能优化(CPU)
性能优化是项目开发中一个永恒的话题。用户的需求和项目的要求总在不停地增长,同屏人数、屏幕特效和场景复杂度永远在向着“榨干”硬件的趋势逼近。所以,无论硬件设备发展到何种程度、研发团队有多么丰富的经验积累,性能优化依旧是一个令人棘手却又难以规避的问题。项目的性能优化主要围绕CPU、GPU和内存三大方面进行。今天,我们就这三方面来谈谈当前普遍存在的性能问题和相应的解决方案。此文为第一篇:CPU专讲,同时如果各位在UWA上已经提交了性能测试,请结合报告阅读本文,效果更佳
通过大量的性能测评数据,我们发现渲染模块、UI模块和加载模块往往占据了游戏CPU性能开销的Top3。渲染模块渲染模块可以说是任何项目中最为消耗CPU性能的引擎模块。几乎所有的游戏或VR项目都离不开场景、角色和特效的渲染。对于渲染模块的优化,主要从以下两个方面入手:●降低Draw CallDraw Call是渲染模块优化方面的重中之重。一般来说,Draw Call越高,则渲染模块的CPU开销越大。究其原因,要从底层Driver和GPU的渲染流程讲起,限于篇幅我们不在这里做过多的介绍。有兴趣的朋友可以查看以下链接中的说明(),或者自行Google相关的技术文献。
降低Draw Call的方法主要是减少渲染物体的材质种类,并通过Draw Call Batching来减少其数量。Unity文档对于Draw Call Batching的原理和注意事项进行了非常详细的讲解,感兴趣的朋友可查看其官方文档()。但是,需要注意的是,游戏性能并非Draw Call越小越好。这是因为决定渲染模块性能的除了Draw Call之外,还有用于传输渲染数据的总线带宽。当我们使用Draw Call Batching将同种材质的网格模型拼合在一起时,可能会造成同一时间需要传输的数据(Texture、VB/IB等)大大增加,以至于造成带宽“堵塞”,在资源无法及时传输过去的情况下,GPU只能等待,从而反倒降低了游戏的运行帧率。Draw Call和总线带宽是天平的两端,我们需要做的是尽可能维持两者的平衡,任何一边过高或过低,对性能来说都是无益的。●简化资源简化资源是非常行之有效的优化手段。在大量的项目中,其渲染资源其实是“过量”的,如过量的网格资源、不合规的纹理资源等等。所以,我们在UWA测评报告中对资源的使用进行了详细的展示,如每帧渲染的三角形面片数、网格和纹理资源的具体使用情况等。
我们知道,在项目中美术设计师对资源的把控可谓举足轻重。UWA测评中特有的项目管理功能,支持项目内成员相互邀请,使得开发团队能更高效地查找和完善存在问题的各种资源。关于渲染模块在CPU方面的优化方法还有很多,比如LOD、Occlusion Culling和Culling Distance等等。我们会在后续的渲染模块专题中进行更为详细的讲解,敬请期待。UI模块UI模块同样是几乎所有项目中必备的模块。一个性能优异的UI模块可以让用户体验再上一个台阶。在目前国内的大量项目中,NGUI作为UI解决方案的占比仍然非常高,因此UWA也对NGUI的性能分析进行了深度的研究。我们会根据用户使用的UI解决方案(UGUI或NGUI)提供相应的性能分析和优化建议。
在NGUI的优化方面,UIPanel.LateUpdate为性能优化的重中之重,它是NGUI中CPU开销最大的函数,没有之一。UI模块制作的难点并不在于其表现上,因为UI界面的表现力是由设计师来决定的,但两套表现完全一致的UI系统,其底层的性能开销则可能千差万别。如何让UI系统使用尽可能小的CPU开销来达到设计师所期望的表现力,则足以考验每一位UI开发人员的制作功底。通过对大量的UWA测评数据进行统计,我们将NGUI中CPU开销最为耗时的几个函数一一展示,并提供详细的CPU占用和堆内存分配。这样,研发团队既可以对UI系统的性能有更为清晰的了解,又可以结合运行截图对性能瓶颈进行直观的定位。
对于UIPanel.LateUpdate的优化,主要着眼于UIPanel的布局,其原则如下:●尽可能将动态UI元素和静态UI元素分离到不同的UIPanel中(UI的重建以UIPanel为单位),从而尽可能将因为变动的UI元素引起的重构控制在较小的范围内;●尽可能让动态UI元素按照同步性进行划分,即运动频率不同的UI元素尽可能分离放在不同的UIPanel中;●尽可能让动态UI元素按照同步性进行划分,即运动频率不同的UI元素尽可能分离放在不同的UIPanel中;控制同一个UIPanel中动态UI元素的数量,数量越多,所创建的Mesh越大,从而使得重构的开销显著增加。比如,战斗过程中的HUD血条可能会大量出现,此时,建议研发团队将运动血条分离成不同的UIPanel,每组UIPanel下5~10个动态UI为宜。这种做法,其本质是从概率上尽可能降低单帧中UIPanel的重建开销。另外,限于篇幅限制,我们在此仅介绍NGUI中重要性能问题,而对于UGUI系统以及UI系统自身的Draw Call问题,我们将在后续的UI模块专题中进行详细的讲解,敬请关注。加载模块加载模块同样是任何项目中所不可缺少的组成部分。与之前两个模块不同的是,加载模块的性能开销比较集中,主要出现于场景切换处,且CPU占用峰值均较高。这里,我们先来说说场景切换时,其性能开销的主要体现形式。对于目前的Unity版本而言,场景切换时的性能开销主要体现在两个方面:前一场景的场景卸载和下一场景的场景加载。下面,我们就具体来说说这两个方面的性能瓶颈:●场景卸载场景卸载一般是由引擎自动完成的,即当我们调用类似Application.LoadLevel的API时,引擎即会开始对上一场景进行处理,其性能开销主要被以下几个部分占据:(1)Destroy.引擎在切换场景时会收集未标识成“DontDestoryOnLoad”的GameObject及其Component,然后进行Destroy。同时,代码中的OnDestory被触发执行,这里的性能开销主要取决于OnDestroy回调函数中的代码逻辑。(2)Resources.UnloadUnusedAssets.一般情况下,场景切换过程中,该API会被调用两次,一次为引擎在切换场景时自动调用,另一次则为用户手动调用(一般出现在场景加载后,用户调用它来确保上一场景的资源被卸载干净)。在我们测评过的大量项目中,该API的CPU开销主要集中在500ms~3000ms之间。其耗时开销主要取决于场景中Asset和Object的数量,数量越多,CPU开销越大。
●场景加载场景加载过程的性能开销又可细分成以下几个部分:(1)资源加载。资源加载几乎占据了整个加载过程的90%时间以上,其加载效率主要取决于资源的加载方式(Resource.Load或AssetBundle加载)、加载量(纹理、网格、材质等资源数据的大小)和资源格式(纹理格式、音频格式等)等等。不同的加载方式、不同的资源格式,其加载效率可谓千差万别,所以我们在UWA测评报告中,特别将每种资源的具体使用情况进行展示,以帮助用户可以立刻查找到”问题资源“并及时进行改正。(2)Instantiate实例化。在场景加载过程中,往往伴随着大量的Instantiate实例化操作,比如UI界面实例化、角色/怪物实例化、场景建筑实例化等等。在Instantiate实例化时,引擎底层会查看其相关的资源是否已经被加载,如果没有,则会先加载其相关资源,再进行实例化。这其实是大家遇到的大多数“Instantiate耗时问题”的根本原因,也是为什么我们在之前的AssetBundle文章中所提倡的资源依赖关系打包并进行预加载,从而来缓解Instantiate实例化时的压力(关于AssetBundle资源的加载又是另一个很深远的话题,我们会在以后的AssetBundle加载专题中进行详细的讲解)。
另一方面,Instantiate实例化的性能开销还体现在脚本代码的序列化上,如果脚本中需要序列化的信息很多,则Instantiate实例化时的时间亦会很长。最直接的例子就是NGUI,其代码中存在很多SerializedField标识,从而在实例化时带来了较多的代码序列化开销。因此,这一点是大家在为代码增加序列化信息时需要时刻关注的。以上是游戏或VR项目中性能开销最大的三个模块。当然,游戏类型的不同、设计的不同,其他模块仍然会有较大的CPU占用。比如,ARPG游戏中的动画系统和物理系统,音乐休闲类游戏中的音频系统和粒子系统等。对此,我们会在后续的技术专题中进行深入的讲解。代码效率逻辑代码在一个较为复杂的项目中往往占据较大的性能开销。特别地,在MOBA、ARPG、MMORPG等移动游戏类型中非常多见。
在项目优化过程中,我们经常会想知道,到底是哪些函数占据了大量的CPU开销。同时,绝大多数的项目中其性能开销都遵循着“二八原则”,即80%的性能开销都集中在20%的函数上。所以,我们在UWA测评报告中将项目中代码占用的CPU开销进行统计,不仅可以提供代码的总体累积CPU占用,还可以更近一步看到函数内部的性能分配,从而帮助大家更快地定位逻辑代码的性能瓶颈。
当然,我们还希望可以为大家提供更多信息,比如更为具体的性能分配、更为准确的截图信息等等。这些都是我们目前正在努力研发的功能,并将在后续版本中提供给大家进行使用。
狗狗,被黑了

我要回帖

更多关于 unity占cpu很高 的文章

 

随机推荐