unity list初始化vuforie初始化失败是什么意思

&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&&figure&&img src=&/50/v2-39f09a2c59f0d50f18a143c8e1b3cb41_b.jpg& data-caption=&& data-rawwidth=&255& data-rawheight=&177& class=&content_image& width=&255&&&/figure&&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&&figure&&img src=&/50/v2-d5f461b9ce6e354dcedf1_b.jpg& data-caption=&& data-rawwidth=&599& data-rawheight=&278& class=&origin_image zh-lightbox-thumb& width=&599& data-original=&/50/v2-d5f461b9ce6e354dcedf1_r.jpg&&&/figure&&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&&figure&&img src=&/50/v2-b82cc63c66d132d1e86c83aeb6d5ac2d_b.jpg& data-caption=&& data-rawwidth=&400& data-rawheight=&404& class=&content_image& width=&400&&&/figure&&ul&&ul&&li&减小屏幕覆盖面积&/li&&li&避免使用Alpha&/li&&li&合并材质和mesh&/li&&li&LOD:根据机型或者距离降低粒子发射器的个数和效果&/li&&li&序列帧:对一些俯视角游戏使用序列帧做特效也能大幅提升效率。这个是一个典型的空间换时间的优化,会增大内存,使用受视角影响如果压缩较大会损失一些效果,要有选择的使用。之前在做一款3d战斗卡牌游戏时特地写了序列帧录制工具。&/li&&/ul&&li&&b&其他&/b&&/li&&/ul&&figure&&img src=&/50/v2-e5f261df13cf7cc1fc2b_b.jpg& data-caption=&& data-rawwidth=&425& data-rawheight=&338& class=&origin_image zh-lightbox-thumb& width=&425& data-original=&/50/v2-e5f261df13cf7cc1fc2b_r.jpg&&&/figure&&ul&&li&渲染设置:阴影,雾,抗拒齿,垂直同步,各项异性,多线程渲染,GPU计算骨架,顶点受骨骼影响,软粒子等等。每个项目要求不同。&/li&&ul&&ul&&li&降低渲染的分辨率:缩小Framebuff分辨率,减少ps开销和内存显存,但是会模糊,王者荣耀等很多主流游戏在Android上都降了分辨率。&/li&&li&智能动态调节:根据玩家配置和游戏环境实时调整配置,低配设备或者战斗降低配置进行限帧,高配插电或者低开销场景,动态提升配置,提高限帧。有一篇文档有更详细的介绍。&/li&&li&后处理:Unity里可以通过看Graphics.Blit性能了解后处理的开销。后处理一般是像素级别的计算,手机设备上分辨率有普遍比pc高,使用的时候更需要注意。&/li&&li&不使用多维子材质材质:我在真机上实测,三个子材质,50个物体,使用多维自材质12帧,330个dc,343面。拆开之后20帧,154dc,134面。多维子材质Unity无法动态合并。&/li&&/ul&&/ul&&/ul&&p&&br&&/p&&p&&b&内存&/b&&/p&&figure&&img src=&/50/v2-e9ec8ba2de0ebc770dcd12_b.jpg& data-caption=&& data-rawwidth=&642& data-rawheight=&476& class=&origin_image zh-lightbox-thumb& width=&642& data-original=&/50/v2-e9ec8ba2de0ebc770dcd12_r.jpg&&&/figure&&p&其实在手机上内存的优化才是最重要的,绝大部分闪退都是内存不足导致,都闪退了其他优化还有什么用呢?内存分析工具有很多,使用Unity的Profile,memoryprofile,XCode,,UWA。一般简单快速分析用Profile,具体内存资源使用memoryprofile和uwa,内存泄露代码级内存优化使用xcode。&/p&&ul&&ul&&li&Mono托管堆:逻辑代码的堆内存分配 ,一旦分配,不会返还给系统。代码级别比较难查。以前在PC上自己写过通过钩子的方式记录内存分配的工具,Unity推荐编译成IL2cpp使用XCode的工具分析,也可以自定义采样点逐帧查看或者通过二分法。&/li&&li&GfxDriver:显存资源。&/li&&li&FMOD音频资源:比较单纯,profile就可以看出来了。&/li&&li&Texture,Mesh,Animaiton,Audio等等:推荐使用memory或者uwa。&/li&&/ul&&/ul&&p&下面介绍一些具体的优化方式。&/p&&ul&&ul&&li&压缩贴图ETC/PVR:贴图是占用资源最大的部分。我对3D贴图基本上都会压缩,2DUI贴图部分压缩。在Android上尽量使用etc格式,IOS上使用pvr格式,非半透有1/8的压缩比。这两种压缩格式类似DX的dds,可以直接被显卡渲染,即降低内存又能减少包大小,提升加载速度(JPG等格式虽然压缩比高但是需要解压成32位色再渲染,增加加了内存和显存还有额外的解压开销)。需要注意以下几点:&/li&&ul&&li&如果压缩效果不好还可以减成16位色。&/li&&li&关Mipmap:UI或者俯视角游戏不需要Mipmap可以关闭减小1/3的体积&/li&&li&如果使用ETC,PVR,DDS压缩贴图必须是2的幂(因为区块颜色索引的压缩算法,如果不是2的幂压缩后也会补成2的幂),正方形(PVR还必须是正方形否则会自动补成正方形浪费空间)。处于渲染效率和显存碎片的考虑贴图的大小建议最大1024,最小64,最大不能超过2048。&/li&&/ul&&li&使用九宫,对称贴图:提高贴图复用率&/li&&li&Shader:利用Shader合并贴图通道,实现灰度图等。Alpha通道存alphatest和高光,贴图一个通道存阴影一个通道存ao等,alpha通道存在贴图的其他通道便于压缩等等。这点在做轩辕传奇的时候大幅使用。&/li&&li&压缩动画减少关键帧:前面有介绍&/li&&li&及时卸载&b&:&/b&在进出场景时,或者打开UI界面等对性能不敏感的时候,卸载资源并调用Resource.UnloadAsset清理引用资源和destroy,System.GC.Collect清理系统资源,前面有介绍。AssetBundle加载时生成、卸载时销毁,这也是比较大的一个坑:)&/li&&li&在代码级别上避免不必要的堆内存分配:可以通过静态代码分析检查,另有一篇文章详细介绍。&/li&&ul&&li&避免频繁New Class:使用内存池。&/li&&li&Constainer:新版本Unity Constainer已经优化。&/li&&li&控制Log输出:我们使用条件限制,Release自动屏蔽一些不重要的日志&/li&&li&For代替Foreach:新版本Unity已经优化。&/li&&li&String连接:减少字符串拼接,使用StringBuilder等等。&/li&&li&delegate:因为内部的链表和装箱拆箱操作,使用频率较高时GC也很高。&/li&&li&合理的使用Lambda表达式:例如Unity的粒子系统5.6版本以前GC较高就是这个原因。&/li&&li&频繁的临时变量或者list生成,建议定义一个全局的list每次都用该list来计算。&/li&&li&需要注意的是类申请在堆上,结构申请在栈上,有时可以使用结构。&/li&&li&等等,这方面优化点和文章较多不再累述。&/li&&/ul&&li&内存泄露: Unity是基于引用计数的,一般内存泄漏是资源被Hold住无法释放,内存增长趋势明显、反复切换场景内存膨胀。针对这种情况可以自己写工具输出每个场景的资源日志。也可以使用XCode分析一段时间的内存。&/li&&li&表数据。表一般不会卸载,15年帮一个项目做优化,发现光表数据就占用40M。建议使用二进制反序列化使用不要直接使用字符串,并且不在内存中做多份缓存,表数据非常巨大的情况下可以考虑使用完删除。&/li&&li&冗余顶点数据:UI贴图Mesh把color,normal等不适用都导出,静态合并会导致内存增大。&/li&&li&抗锯齿/Rendertexture:开了抗锯齿会增大内存,高分辨率会增大内存,后期处理可以交换使用Rendertexture不要创建多份。&/li&&li&GameObject数量:小于1w,节点书过多也会导致加载更新缓慢内存膨胀,可以写工具监控并作为测试时的一项性能指标&/li&&li&其他&/li&&/ul&&/ul&&p&&br&&/p&&p&&b&闪存&/b&&/p&&p&在PC上也就是硬盘。具体表现在包大小,资源加载速度等。闪存的优化和内存大部分共同,但是也有例外,例如使用jpg就是减少包大小增大内存消耗CPU的方法。&/p&&ul&&ul&&li&压缩和内存一样。贴图,动画,导表等等。&/li&&li&在移动平台上可以打开code strip功能来减少代码带来的内存和容量消耗。对于使用了反射的类,可以使用link.xml配置解决。code strip是Unity提供的一个优化功能,他会预判断代码的执行路径,将没有使用的函数去掉。&/li&&/ul&&/ul&&figure&&img src=&/50/v2-fe44baed587899d_b.jpg& data-caption=&& data-rawwidth=&445& data-rawheight=&167& class=&origin_image zh-lightbox-thumb& width=&445& data-original=&/50/v2-fe44baed587899d_r.jpg&&&/figure&&ul&&ul&&li&部分SDK很大,可以和第三方协商减少重复包含的库。&/li&&li&l2cpp 中会包含 ARMv7 和 ARM64 位两个版本的代码,因此,会有两份代码的体积。&/li&&li&动态下载:类似微端。但在手机上并不推荐,可能会导致使用玩家流量。&/li&&li&冗余资源:导出包的时候利用插件或者自己写的工具分析资源。在prefab中搜索资源是否被引用。&/li&&li&贴图mesh动态生成:对于一些规则画贴图和模型可以通过计算生成出来,例如以前使用过的著名的substance,还有之前端游优化地形的时候只保存地形的高度,通过多留的方式在GPU中还原成地形信息,可以减少1/3等等。&/li&&li&其他:包体的优化相对CPU,GPU,内存没有那么重要,但是对游戏的推广非常重要,也值得花精力去优化。&/li&&/ul&&/ul&&p&&br&&/p&&p&&b&网络&/b&&/p&&ul&&ul&&li&减小包体和压缩:在二进制上进行一些重用和合并减小包体,对协议包做压缩。&/li&&li&合包:按一定频率进行合包操作,把几个包合并在一起降低发送频率,减小包头。MMORPG为了防止包过大可以采取裁包,当玩家同屏较多时抛弃一些不重要的协议。最近的项目为了防止超过MTU,会做一些负载均衡,当操作过多的时限制每帧的操作数,把一些操作放到后面的包广播。&/li&&li&网络同步框架和策略。最近开发的一款射击MOBA游戏,就使用了帧同步。对于大量小兵的RTS和MOBA类游戏,帧同步的协议量可以比状态同步小n倍,我们的延迟和流量已经优化到和王者荣耀类似,而状态同步的全民超神比帧同步的王者荣耀高3倍左右。具体帧同步和状态同步的优缺点会写更详细的文章讨论。&/li&&/ul&&/ul&&p&&br&&/p&&p&&b&耗电&/b&&/p&&p&耗电可能不会被大家所重视,但其实在手游上这是一个非常重要的指标。如果游戏打一两个小时就没电了,那出门在外谁敢玩呢?火遍全国的王者荣耀就在省电上做了非常多的优化,我们游戏也是。那么有哪些优化方案呢?&/p&&ul&&ul&&li&降低CPU/GPU:CPU和GPU非常影响耗电,因为手机CPU和GPU封装一个SOC上的,因此主要体现在手机CPU占用上,当CPU低于25%会非常省电当CPU高于80%耗电就会从呈指数上升。和CPUGPU的优化是重合。&/li&&li&内存闪存:内存闪存的使用频率也会影响耗电,和内存闪存的优化重合。&/li&&li&网络:和网络的优化重合。&/li&&li&限帧:限帧是比较常用的优化手段,手游一般会限帧30帧,早期苹果系统强制限帧30帧后来才开放的。王者荣耀已经把限帧作为一个广告手段了,哪个设备支持都会做一番宣传。但是限帧会降低手感需要权衡。&/li&&li&省电模式:当检查到玩家没有插电的时候,配合限帧,降低画质和效果,降低更新频率和LOD等。&/li&&li&其他&/li&&/ul&&/ul&&p&&br&&/p&&p&&b&总结&/b&&/p&&ul&&ul&&li&&b&扁鹊三兄弟VS过早的优化是万恶之源&/b&&/li&&/ul&&/ul&&p&优化有两个理论,Donald Knuth曾说过“过早的优化是万恶之源”,因为让正确的程序更快,要比让快速的程序正确容易得多。但与之相反的就是扁鹊三兄弟的段子,最好的医生是再出问题之前就先避免问题的,特别是游戏等到后期美术资源代码都非常庞大的时候再优化成本非常高甚至来不及优化。&/p&&p&在这个方面上我认为两种观点都有道理,对软件开发来说更倾向中后期优化,在产品开发程度在50%的时候开始测试崩溃率,在完成度80%的时候启用兼容性测试。而对游戏来说因为美术的原因又比较特殊,个人感觉前期应该先验证玩法,效果。等到立项阶段就开始测试并制定各种规范,因为美术的优化后期成本非常高。最后在游戏的中后期做有针对性的持续优化。&/p&&ul&&ul&&li&&b&持续的过程&/b&&/li&&/ul&&/ul&&p&优化是一个持续的过程,因为游戏开发是一个变化非常大的过程。随着开发和需求的变更,会不断出现性能瓶颈。优化一般会持续到游戏的整个生命周期。&/p&&ul&&ul&&li&&b&没有万金油,具体问题具体分析&/b&&/li&&/ul&&/ul&&p&优化其实没有通用的方法,例如预加载是空间换时间,资源压缩是时间换空间。具体的优化方案要根据需求根据项目更具优先级来制定。&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&
最近比较慢最后一篇写的有些晚了。最后介绍一下GPU,内存,闪存耗电和网络。因为介绍的比较广,每个点都比较简单,后续可能会针对某些部分做更深的介绍。 GPUDCDrawCall实际上优化的CPU的时间,但因为DC的优化一般都是材质mesh合并,所以放到了GPU的部分。…
&figure&&img src=&/50/v2-c281ae29ace6b3eafdd64a6_b.png& data-rawwidth=&1278& data-rawheight=&546& class=&origin_image zh-lightbox-thumb& width=&1278& data-original=&/50/v2-c281ae29ace6b3eafdd64a6_r.png&&&/figure&&p&&i&图片与内容无关~纯粹是愁的。&/i&&/p&&hr&&p&通讯一直是人类一直依赖一种手段,古代的书信,现在email。如果互相没有通讯那每个人的世界就周围的一亩三分地了。&/p&&p&unity有自己封装的network,但是这次我们不用这个。我们用socket。&/p&&p&socket是封装好的一个长连接手段。通过一个IP地址和一个端口来连接彼此。&/p&&p&其中数据的交流有两种模式,分为TCP和UDP。&/p&&p&UDP是只管发送。TCP是发送后确定收到。&/p&&p&&i&UDP是比较贴近现实的,古代送镖,路上就有呗劫镖的可能。&/i&&/p&&p&&i&TCP是比较贴近理想的。古代镖到地了,就会寄封书信回去,确认收到镖了。&/i&&/p&&p&下面我们就来建立两个程序间的通讯&/p&&p&把这两个脚本分别建两个项目,挂载运行,来运行。&/p&&p&&b&服务端代码&/b&&/p&&div class=&highlight&&&pre&&code class=&language-csharp&&&span&&/span&&span class=&k&&using&/span& &span class=&nn&&System.Net&/span&&span class=&p&&;&/span&
&span class=&k&&using&/span& &span class=&nn&&System.Net.Sockets&/span&&span class=&p&&;&/span&
&span class=&k&&using&/span& &span class=&nn&&UnityEngine&/span&&span class=&p&&;&/span&
&span class=&k&&using&/span& &span class=&nn&&System.Text&/span&&span class=&p&&;&/span&
&span class=&k&&public&/span& &span class=&k&&class&/span& &span class=&nc&&Server&/span& &span class=&p&&:&/span& &span class=&n&&MonoBehaviour&/span&
&span class=&p&&{&/span&
&span class=&k&&private&/span& &span class=&n&&Socket&/span& &span class=&n&&socket&/span&&span class=&p&&;&/span&
&span class=&k&&private&/span& &span class=&kt&&byte&/span&&span class=&p&&[]&/span& &span class=&n&&data&/span& &span class=&p&&=&/span& &span class=&k&&new&/span& &span class=&kt&&byte&/span&&span class=&p&&[&/span&&span class=&m&&1024&/span&&span class=&p&&];&/span&
&span class=&k&&private&/span& &span class=&k&&void&/span& &span class=&nf&&Start&/span&&span class=&p&&()&/span&
&span class=&p&&{&/span&
&span class=&c1&&//127.0.0.1为本地回环IP&/span&
&span class=&n&&IPAddress&/span& &span class=&n&&localAddr&/span& &span class=&p&&=&/span& &span class=&n&&IPAddress&/span&&span class=&p&&.&/span&&span class=&n&&Parse&/span&&span class=&p&&(&/span&&span class=&s&&&127.0.0.1&&/span&&span class=&p&&);&/span&
&span class=&c1&&//端口号&/span&
&span class=&kt&&int&/span& &span class=&n&&port&/span& &span class=&p&&=&/span& &span class=&m&&8888&/span&&span class=&p&&;&/span&
&span class=&c1&&//新建连接,连接类型&/span&
&span class=&n&&socket&/span& &span class=&p&&=&/span& &span class=&k&&new&/span& &span class=&n&&Socket&/span&&span class=&p&&(&/span&&span class=&n&&AddressFamily&/span&&span class=&p&&.&/span&&span class=&n&&InterNetwork&/span&&span class=&p&&,&/span& &span class=&n&&SocketType&/span&&span class=&p&&.&/span&&span class=&n&&Stream&/span&&span class=&p&&,&/span& &span class=&n&&ProtocolType&/span&&span class=&p&&.&/span&&span class=&n&&Tcp&/span&&span class=&p&&);&/span&
&span class=&c1&&//绑定IP和端口&/span&
&span class=&n&&socket&/span&&span class=&p&&.&/span&&span class=&n&&Bind&/span&&span class=&p&&(&/span&&span class=&k&&new&/span& &span class=&n&&IPEndPoint&/span&&span class=&p&&(&/span&&span class=&n&&localAddr&/span&&span class=&p&&,&/span& &span class=&n&&port&/span&&span class=&p&&));&/span&
&span class=&c1&&//设置监听数量&/span&
&span class=&n&&socket&/span&&span class=&p&&.&/span&&span class=&n&&Listen&/span&&span class=&p&&(&/span&&span class=&m&&1&/span&&span class=&p&&);&/span&
&span class=&c1&&//开始接收&/span&
&span class=&n&&Socket&/span& &span class=&n&&_socket&/span& &span class=&p&&=&/span& &span class=&n&&socket&/span&&span class=&p&&.&/span&&span class=&n&&Accept&/span&&span class=&p&&();&/span&
&span class=&c1&&//将收到的数据取出来&/span&
&span class=&kt&&int&/span& &span class=&n&&len&/span& &span class=&p&&=&/span& &span class=&n&&_socket&/span&&span class=&p&&.&/span&&span class=&n&&Receive&/span&&span class=&p&&(&/span&&span class=&n&&data&/span&&span class=&p&&);&/span&
&span class=&c1&&//将数据按照UTF8编码为字符串&/span&
&span class=&n&&Debug&/span&&span class=&p&&.&/span&&span class=&n&&Log&/span&&span class=&p&&(&/span&&span class=&n&&Encoding&/span&&span class=&p&&.&/span&&span class=&n&&UTF8&/span&&span class=&p&&.&/span&&span class=&n&&GetString&/span&&span class=&p&&(&/span&&span class=&n&&data&/span&&span class=&p&&,&/span& &span class=&m&&0&/span&&span class=&p&&,&/span& &span class=&n&&len&/span&&span class=&p&&));&/span&
&span class=&c1&&//关闭连接&/span&
&span class=&n&&_socket&/span&&span class=&p&&.&/span&&span class=&n&&Close&/span&&span class=&p&&();&/span&
&span class=&n&&socket&/span&&span class=&p&&.&/span&&span class=&n&&Close&/span&&span class=&p&&();&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&b&客户端代码&/b&&/p&&div class=&highlight&&&pre&&code class=&language-csharp&&&span&&/span&&span class=&k&&using&/span& &span class=&nn&&System.Net&/span&&span class=&p&&;&/span&
&span class=&k&&using&/span& &span class=&nn&&System.Net.Sockets&/span&&span class=&p&&;&/span&
&span class=&k&&using&/span& &span class=&nn&&UnityEngine&/span&&span class=&p&&;&/span&
&span class=&k&&using&/span& &span class=&nn&&System.Text&/span&&span class=&p&&;&/span&
&span class=&k&&public&/span& &span class=&k&&class&/span& &span class=&nc&&Client&/span& &span class=&p&&:&/span& &span class=&n&&MonoBehaviour&/span&
&span class=&p&&{&/span&
&span class=&k&&private&/span& &span class=&n&&Socket&/span& &span class=&n&&socket&/span&&span class=&p&&;&/span&
&span class=&k&&private&/span& &span class=&kt&&byte&/span&&span class=&p&&[]&/span& &span class=&n&&data&/span& &span class=&p&&=&/span& &span class=&k&&new&/span& &span class=&kt&&byte&/span&&span class=&p&&[&/span&&span class=&m&&0&/span&&span class=&p&&];&/span&
&span class=&k&&private&/span& &span class=&k&&void&/span& &span class=&nf&&Start&/span&&span class=&p&&()&/span&
&span class=&p&&{&/span&
&span class=&c1&&//127.0.0.1为本地回环IP&/span&
&span class=&n&&IPAddress&/span& &span class=&n&&localAddr&/span& &span class=&p&&=&/span& &span class=&n&&IPAddress&/span&&span class=&p&&.&/span&&span class=&n&&Parse&/span&&span class=&p&&(&/span&&span class=&s&&&127.0.0.1&&/span&&span class=&p&&);&/span&
&span class=&c1&&//端口号&/span&
&span class=&kt&&int&/span& &span class=&n&&port&/span& &span class=&p&&=&/span& &span class=&m&&8888&/span&&span class=&p&&;&/span&
&span class=&c1&&//新建连接,连接类型&/span&
&span class=&n&&socket&/span& &span class=&p&&=&/span& &span class=&k&&new&/span& &span class=&n&&Socket&/span&&span class=&p&&(&/span&&span class=&n&&AddressFamily&/span&&span class=&p&&.&/span&&span class=&n&&InterNetwork&/span&&span class=&p&&,&/span& &span class=&n&&SocketType&/span&&span class=&p&&.&/span&&span class=&n&&Stream&/span&&span class=&p&&,&/span& &span class=&n&&ProtocolType&/span&&span class=&p&&.&/span&&span class=&n&&Tcp&/span&&span class=&p&&);&/span&
&span class=&c1&&//建立连接&/span&
&span class=&n&&socket&/span&&span class=&p&&.&/span&&span class=&n&&Connect&/span&&span class=&p&&(&/span&&span class=&n&&localAddr&/span&&span class=&p&&,&/span& &span class=&n&&port&/span&&span class=&p&&);&/span&
&span class=&c1&&//将发送的数据按照UTF8编码为byte数组&/span&
&span class=&n&&data&/span& &span class=&p&&=&/span& &span class=&n&&Encoding&/span&&span class=&p&&.&/span&&span class=&n&&UTF8&/span&&span class=&p&&.&/span&&span class=&n&&GetBytes&/span&&span class=&p&&(&/span&&span class=&s&&&我是CarefreeQ!&&/span&&span class=&p&&);&/span&
&span class=&c1&&//发送数据&/span&
&span class=&n&&socket&/span&&span class=&p&&.&/span&&span class=&n&&Send&/span&&span class=&p&&(&/span&&span class=&n&&data&/span&&span class=&p&&);&/span&
&span class=&c1&&//关闭连接&/span&
&span class=&n&&socket&/span&&span class=&p&&.&/span&&span class=&n&&Close&/span&&span class=&p&&();&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&其中服务端的项目Console面板回收到如下信息:&/p&&figure&&img src=&/v2-06f89c7bffc2e73f38ba3b_b.png& data-rawwidth=&745& data-rawheight=&136& class=&origin_image zh-lightbox-thumb& width=&745& data-original=&/v2-06f89c7bffc2e73f38ba3b_r.png&&&/figure&&p&&br&&/p&&figure&&img src=&/v2-e1be51b9ab_b.png& data-rawwidth=&454& data-rawheight=&43& class=&origin_image zh-lightbox-thumb& width=&454& data-original=&/v2-e1be51b9ab_r.png&&&/figure&&p&这里是设置连接IP的位置,如果是服务端,则是本机IP。&/p&&p&这里的127.0.0.1是回环IP,在实际测试中,其实是会产生一些BUG的。&/p&&p&&i&btw:当能够成功建立连接后,推荐更换为本机IP。&/i&&/p&&p&&br&&/p&&figure&&img src=&/v2-609a596cb6f2c15f9a6cb5bf8e34f2fc_b.png& data-rawwidth=&698& data-rawheight=&45& class=&origin_image zh-lightbox-thumb& width=&698& data-original=&/v2-609a596cb6f2c15f9a6cb5bf8e34f2fc_r.png&&&/figure&&p&这里的参数我就列出MSDN,就不多做解释了。&/p&&figure&&img src=&/v2-bdd6c36dbb3c7da2c24e6ca_b.png& data-rawwidth=&391& data-rawheight=&43& class=&content_image& width=&391&&&/figure&&p&&br&&/p&&figure&&img src=&/v2-3f0e006a7e1e871e3592cb_b.png& data-rawwidth=&758& data-rawheight=&78& class=&origin_image zh-lightbox-thumb& width=&758& data-original=&/v2-3f0e006a7e1e871e3592cb_r.png&&&/figure&&p&&br&&/p&&figure&&img src=&/v2-6a0bc7abe40d9c5ead449ef_b.png& data-rawwidth=&761& data-rawheight=&40& class=&origin_image zh-lightbox-thumb& width=&761& data-original=&/v2-6a0bc7abe40d9c5ead449ef_r.png&&&/figure&&p&&br&&/p&&figure&&img src=&/v2-5de5fa5cd7e4dfbfe844ac3_b.png& data-rawwidth=&302& data-rawheight=&37& class=&content_image& width=&302&&&/figure&&p&当代码执行到这里时,会卡住。是因为Accept是个阻塞函数。&/p&&p&他会一直等待,直到接收到一个连接为止。&/p&&p&所以之前让建两个项目,一个用来运行服务端脚本,一个运行客户端脚本。&/p&&p&那如何避免阻塞,&/p&&p&一种是调用socket的异步函数BeginAccept。&/p&&figure&&img src=&/v2-bb9074abc8f168cbba416_b.png& data-rawwidth=&462& data-rawheight=&202& class=&origin_image zh-lightbox-thumb& width=&462& data-original=&/v2-bb9074abc8f168cbba416_r.png&&&/figure&&p&一种是新建一个线程来运行该阻塞函数。道理都是一样的。&/p&&figure&&img src=&/v2-52fc3eba868cfbdd505f15_b.png& data-rawwidth=&458& data-rawheight=&218& class=&origin_image zh-lightbox-thumb& width=&458& data-original=&/v2-52fc3eba868cfbdd505f15_r.png&&&/figure&&p&这两种方法都能避免阻塞的情况发生。&/p&&p&下面的就是一个将字符串按照UTF8编码储存为btye数组发送,一个按照UTF8编码读取byte数组。&/p&&p&&i&btw:如果在连接中,出现&b&目标计算机积极拒绝,无法连接&/b&的问题,可以用排除法逐渐排查。&/i&&/p&&p&&i&try catch服务端代码,是否正常启动监听。查看端口是否被占用。等等。&/i&&/p&&p&&br&&/p&&p&那可以试试建立一个基本连接来通讯下试试。&/p&&p&那Unity是单线程的,异步时会出问题吗?&/p&&p&单纯的字符串并不能满足我们如何传递数据?&/p&&p&数据流在传递过程中会发生怎样的问题?&/p&
图片与内容无关~纯粹是愁的。通讯一直是人类一直依赖一种手段,古代的书信,现在email。如果互相没有通讯那每个人的世界就周围的一亩三分地了。unity有自己封装的network,但是这次我们不用这个。我们用socket。socket是封装好的一个长连接手段。通过一个IP…
&h2&0. 牢骚&/h2&&p&我发现,每个月的20+号是我有精力写博客的时间……&br&这次项目算是经历的第一次严格意义上的渠道测试,更换了正式名称,见了更多玩家,开发组也经历的更多通宵……评价和数据如何暂时还未揭晓,趁着没那么忙,来还欠自己的“文章债务”。。。&/p&&p&这篇博客主题是移动平台的天气系统,做这个系统的主要原因是美术需求——大世界沙盘的动态效果太少了,需要一些动态变化的东西来增加效果。之前也看过一篇博客&a href=&/?target=http%3A//blog.csdn.net/qq/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Unity3D手游开发日记(7) - 适合移动平台的天气效果》&i class=&icon-external&&&/i&&/a&,作者对于每种天气效果大致聊了原理,我也挺感兴趣,就在今天五一假期(是的,没看错,就是半年前的五一……)蹲在家里花了一天多时间照着文章的思路撸了一个简单版本,在加上之前积累的多云的效果,算是我们项目中天气系统的雏形。过了假期放出来给同事体验了下,感觉还不错,然后稍微修改了一些bug就被其他事情搁置下来了,所以7月份测试也没有放出来。&/p&&p&7月技术测试之后,美术效果的增强也就被逐渐放到更高的优先级,天气系统也就成为了我的工作重点之一。经历整体结构的重构和一些效果实现方式的改变,才有了目前测试在用的这个版本。本篇文章就以当前已经实现的几种天气效果为例来聊一下在移动平台上实现一套简单的天气系统的思路和方法。&/p&&h2&1. 综述&/h2&&p&整体来说,移动平台的性能还不足以支撑端游上完整的一套天气系统,Unity的Asset Store上有一些不错的天气效果实现,也只能看着流流口水,并不敢用,比如这个&a href=&/?target=https%3A//www./cn/%23%21/content/60955& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Weather Maker - Sky, Weather, Fog, Volumetric Light and Dynamic Environment&i class=&icon-external&&&/i&&/a&,还有&a href=&/?target=https%3A//www./cn/%23%21/content/2714& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&UniStorm&i class=&icon-external&&&/i&&/a&。(UniStorm有一个Mobile版本,效果也还不错,有兴趣的同学可以去搜索看下。)&/p&&p&那么,在移动端,天气系统效果简答来说也就成了美术做做特效,程序按照需求写写挂特效的脚本罢了。的确,在制作各个天气的效果的时候,并没有用到什么特别的技术点,但整个实现天气系统的过程中,我没有依赖于美术,而是自己寻找所有需要的资源,编写逻辑进行整合简化,过程还比较有趣,体会到非常直接的成就感,一些小的细节也自己去处理,非常开心。目前实现的天气效果包括晴天、多云、阴天、雨天和雪天这几种比较常见的效果,逐一来进行说明。&/p&&h2&2. 晴天效果&/h2&&p&我们项目中美术制作的所有场景都是按照晴天的效果来制作的,所以对于程序来说,晴天效果就是没效果,实现最简单,性能最优,哈哈~(就是注意把其他效果清空不要残留……)&/p&&h2&3. 多云效果&/h2&&p&先看一下最终实现的多云效果截图,动态图比较容易看出效果,静态图感觉比较怪,可以注意主城的模型有一半是被云遮住了。为了凸显效果云阴影的浓度被我故意调整得比较高。&/p&&p&&br&&/p&&figure&&img src=&/50/v2-bf6ad2b948bb4b2a7802_b.jpg& data-rawwidth=&1071& data-rawheight=&687& class=&origin_image zh-lightbox-thumb& width=&1071& data-original=&/50/v2-bf6ad2b948bb4b2a7802_r.jpg&&&/figure&&p&多云效果截图&/p&&p&这个效果是之前美术想要的一个内容。如果使用真正移动一个半透的云模型在空中移动并且产生投影,移动设备上所能支持的shadowmap尺寸无法提供足够的阴影精度,而直接进行投影的方法又比较难做到在高低不平的山、建筑等物体表面计算投影效果。经过调研之后,使用了一个购买的插件&a href=&/?target=https%3A//www./cn/%23%21/content/57352& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Screen Space Cloud Shadow&i class=&icon-external&&&/i&&/a&。插件页面有动态效果视频,想看动态效果的可以去看下。当时同样调研了另外一个插件&a href=&/?target=https%3A//www./cn/%23%21/content/63050& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Cloud Shadows&i class=&icon-external&&&/i&&/a&,都试玩了下。后者是基于light的cookie的,在当时的unity版本中有些小问题没有解决掉,而且我自己试验的cookie在移动设备上有点小问题,所以就没有选用。Screen Space Cloud Shadow这个插件使用起来比较方便,只需要把prefab丢场景里就好,开关也很简单,代价就是需要深度图,场景内所有物件都要绘制两遍,draw call和面数都会翻倍。这也是整个天气系统中消耗最大的一块,因此多云天气在最终版本里也只有高配下才会开启。&/p&&p&由于是购买的插件,因此贴代码不太合适,简单说一下实现的原理:shader使用Transparent渲染队列,在OnWillRenderObject中将一个平面放到相机的远平面,并且把尺寸缩放成和相机的远平面一样,这样就保证它的绘制过程是在最后,用FrameDebugger抓帧看绘制顺序和参数如下图:&/p&&figure&&img src=&/50/v2-c479bac021c4b2efb9df7dc8e2c625d4_b.jpg& data-rawwidth=&1175& data-rawheight=&419& class=&origin_image zh-lightbox-thumb& width=&1175& data-original=&/50/v2-c479bac021c4b2efb9df7dc8e2c625d4_r.jpg&&&/figure&&p&云阴影的绘制过场截图&/p&&p&在Shader的frag过程中,根据深度图和世界空间的摄像机方向射线来计算出阴影应该绘制的浓度。这里包含了一些magic value,我也有些细节没有看得特别懂……再加上本身并不是我自己设计的算法,因此不在这里详述了,有兴趣想了解的朋友可以自己去购买一份插件,source code include。&/p&&p&这里只说明三个遇到并解决的小坑:&/p&&ol&&li&由于云的阴影是飘动的,因此涉及到&b&uv的流动&/b&,这个是根据时间来计算的,最初的时候这个时间直接取了Time.time的值,当游戏运行一段时间之后,这个值就会变得很大,在移动设备上会导致云的移动出现顿卡的感觉。这也是在很多使用uv流动的过程中很容易出现的一个问题,通过取余的方式可以保证精度,但是可能会在取余的那一帧出现采样不连续的问题。由于我们不会非常长时间开启这个效果,因此这个问题可以通过在开关的时候把时间参数重置来规避。&/li&&li&&b&fixed类型在移动设备上精度问题导致马赛克&/b&。原来Shader中使用了fixed的值,在PC上并没有问题,安卓设备上发现了&b&马赛克的现象&/b&,修改几个关键值为float类型可以解决马赛克问题。&/li&&li&由于使用了&b&深度图&/b&,因此深度图的精度对于云的效果影响比较大。我们最初相机的远平摄设置得非常远,近平面又非常近,0.1-1000这样的值域范围。在PC上没有问题,手机上就有非常明显的马赛克,将近平面和远平面都调整一下,变为1-300,效果好了很多。(顺便再推荐一下在UWA群里推荐过的调试插件,&a href=&/?target=https%3A//www./cn/%23%21/content/61863& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Hdg Remote Debug - Live Update Tool&i class=&icon-external&&&/i&&/a&,可以在电脑上连接移动设备进行实时调试,用于排查和调试这种问题比频繁打包要方便很多,节省太多时间,已经被我默认打包进了dev版本的工程里。)&/li&&/ol&&h2&4. 阴天&/h2&&p&阴天的效果其实就是天色变暗的感觉,如果是实时光照的话可以通过调暗方向光的亮度或者颜色来处理,但是由于手游上目前大都还是烘焙的,因此比较方便的方案就是通过后处理来实现。&/p&&p&考虑过Color Grading方案,但是感觉稍微有点耗,而且和昼夜系统实现会有些小冲突,最后实现的时候选择了直接在颜色上乘以一个Tint Color的方案来做,由于我们整合了整个后处理效果栈,因此在开启别的后处理的情况下,这个tint color的过程消耗非常小,每个像素多一个乘法而已。&/p&&blockquote&这里也再推荐一下钱康来一直推荐的将所有的后处理Pass进行整合的方案,也就是参考Unity官方的Github实现:&a href=&/?target=https%3A///Unity-Technologies/PostProcessing& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Post Processing Stack&i class=&icon-external&&&/i&&/a&,Asset Store上也有&a href=&/?target=https%3A//www./cn/%23%21/content/83912& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Post Processing Stack&i class=&icon-external&&&/i&&/a&。&/blockquote&&h2&5. 雨天&/h2&&p&雨天的效果实现了两个版本,最初的版本是基于前文提到的博客里的思路来实现的,就是挂一个uv流动的面片在镜头前,闪电的效果就是把这个面片调整为白色再调整回来。实现非常简单,这里只贴一下Shader代码好了,因为没有真正在项目中使用,所以只算私货。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Shader &Shader/Scene/Rain& {
Properties{
_RainTex(&Main Texture:&, 2D) = &white& {}
_RainIntensity(&Intensity of Rain:&,Float) = 0.0
_FallSpeed(&Fall Speed of Rain:&,Float) = 1
_ThunderLighting(&Thunder Lighting&, Color) = (0, 0, 0, 0.5)
SubShader{
Tags{ &Queue& = &Transparent& &IgnoreProjector& = &True& &RenderType& = &Transparent& }
Blend SrcAlpha One
ZWRITE Off
Lighting Off
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include &UnityCG.cginc&
sampler2D _RainT
float4 _RainTex_ST;
fixed _FallS
fixed _RainI
float4 _ThunderL
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
struct v2f {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
v2f vert(appdata_t v)
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = TRANSFORM_TEX(v.texcoord, _RainTex);
fixed4 frag(v2f i) : SV_Target
fixed2 UV = i.
float Time = _Time.y;
fixed vValue = _FallSpeed * T
UV = fixed2(UV.x, UV.y + _FallSpeed * Time);
fixed4 col = tex2D(_RainTex, UV);
col.rgb = col.rgb * col.a * _RainIntensity + _ThunderLighting.
col.a = 1.0f;
&/code&&/pre&&/div&&p&实现的效果截图如下图所示。镜头前的面片使用的贴图也是我从网上找的雨滴噪声贴图自己修改的,因此有不连续的问题,截图中可以看出来,这个也是自己P图的基本功不够的原因……&/p&&figure&&img src=&/50/v2-d654bd920fc38529cbcf9caf_b.jpg& data-rawwidth=&1024& data-rawheight=&566& class=&origin_image zh-lightbox-thumb& width=&1024& data-original=&/50/v2-d654bd920fc38529cbcf9caf_r.jpg&&&/figure&&p&初版的下雨效果截图&/p&&p&这里学习到一个小的技巧是可以使用Unity的AnimationCurve来做一些曲线供游戏逻辑使用,从而做出来一些变化的效果,这里就用曲线控制了雨的浓度和与雷声配合的闪电效果,C#代码也贴一下。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&using UnityE
namespace ThorFramework.Weather
[DisallowMultipleComponent]
public class RainController : MonoBehaviour
public AnimationCurve rainC
public AnimationCurve thunderC
private Color lightingColor = Color.
private Material weatherM
private float startTime = 0.0f;
private AudioSource thunderA
// Use this for initialization
void Start()
MeshRenderer r = gameObject.GetComponent&MeshRenderer&();
if (r != null)
weatherMaterial = r.
startTime = Time.
thunderAudio = gameObject.GetComponent&AudioSource&();
void OnEnable()
startTime = Time.
// Update is called once per frame
void Update()
float curveTime = Time.time - startT
if (weatherMaterial == null)
if (rainCurve != null)
float val = rainCurve.Evaluate(curveTime);
weatherMaterial.SetFloat(&_RainIntensity&, val);
thunderAudio.volume = 2.0f *
if (thunderCurve != null)
float val = thunderCurve.Evaluate(curveTime);
weatherMaterial.SetColor(&_ThunderLighting&, lightingColor*val);
&/code&&/pre&&/div&&p&这种实现OverDraw会直接翻倍,但是没有其他的太多额外消耗,因此性能上还比较节省,大致测试了下对于性能几乎感受不出来影响,特别是被降低了分辨率的情况下。但是最终我们还是没有采用这种方案,主要原因是这种效果很难做出深度感,就是雨滴真的在空间中有分布的感觉。最终还是用了粒子特效,一个一直挂在相机前的特效,在区域范围内一直产生垂直坠落的雨滴。&/p&&p&在这之前我没怎么玩过粒子系统,这里从头学习制作一个粒子特效,还是挺有趣的。粒子系统可以用比较简单的方法制作出非常酷炫的效果。最终实现效果的截图如下:&/p&&figure&&img src=&/50/v2-e9dbc814f_b.jpg& data-rawwidth=&1017& data-rawheight=&573& class=&origin_image zh-lightbox-thumb& width=&1017& data-original=&/50/v2-e9dbc814f_r.jpg&&&/figure&&p&雨天效果截图&/p&&p&这里雨的效果包括三个部分:&/p&&ol&&li&跟随相机移动的一个产生雨滴的特效,截图中雨滴不是很密集,但是动起来的效果还是不错的。这里为了追求效果粒子数量上限给到了500左右,但是仍然不是非常密集,做不到暴风雨的感觉,还需要添加一些面片来做更加密集的雨滴效果。&/li&&li&跟随角色移动的地面涟漪。在通常的做法中,雨滴涟漪的制作是用粒子系统的碰撞来做的。当粒子产生了碰撞之后就会产生一个新的粒子效果,这样可以做到很精准的感觉,包括落在树叶上、建筑房顶上等,但是消耗也比较大。我们采用的是比较讨巧的方法,角色脚底挂一个不断随机产生涟漪的粒子特效,在斜坡、桥上等地方会有穿帮的小问题,但是也基本满足的策划的需求。&/li&&li&与阴天一样,下雨的时候会阴暗一些,所以同样挂了一个tint color调色的后处理。&/li&&/ol&&blockquote&总结:雨的效果花费了挺多精力来制作,最终的效果基本满意。使用特效的方案整体的overdraw没有那么高,但是为了出效果粒子数量用得还算比较多,因此在粒子系统上的性能消耗还挺大的。对比之前面片的方案各有优劣,只是出了追求高品质效果的考虑选择了效果上限较高的粒子系统来实现。&/blockquote&&h2&6. 雪天&/h2&&p&在实现雨天的效果之后,雪天的效果制作就非常简单了,雾效果加上一个和雨滴相似的粒子特效挂在镜头前就可以啦。由于雪花生命周期比较长,飘落速度比较慢,粒子数最多在300左右就可以达到不错的效果。实现的效果截图如下(这里有一些序列帧动画之类的小技巧可以优化雪片的效果,不过不属于程序的技术了,特效同学应该都会的):&/p&&figure&&img src=&/50/v2-c47fc0fd32ac140b3af0b9_b.jpg& data-rawwidth=&1019& data-rawheight=&576& class=&origin_image zh-lightbox-thumb& width=&1019& data-original=&/50/v2-c47fc0fd32ac140b3af0b9_r.jpg&&&/figure&&p&雪天效果截图&/p&&blockquote&也同样研究了一下《镇魔曲》中雪花效果的实现,发现比较讨巧的是他们没有让一个雪花是一个粒子,而是用一张图来表现几片雪花的效果,然后大约只需要同时存在十几个粒子就可以做到比较密集的下雪效果。当然代价是仔细观察的话会发现一些重复感,overdraw也会稍微有些提高,但是粒子数量降低得会比较多,值得借鉴。(我们美术同学尝试了一个版本之后告诉我不太满意,当然在看了完全随机的效果之后,对于略有重复的效果自然能感觉出来瑕疵,没有对比才没有伤害……)&/blockquote&&h2&7. 风&/h2&&p&风不属于任何一个天气,而是用于辅助表现其他天气效果的元素,在我们游戏中主要能做的表现是树木的摇摆和一些相应的音效。摇摆的效果采用顶点动画来实现,已有的实现方案可以参考&a href=&/?target=http%3A//blog.csdn.net/qq/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity3D手游开发日记(5) - 适合移动平台的植被随风摆动&i class=&icon-external&&&/i&&/a&这篇文章,网上也有很多实现细节的讨论,但比较好的方案追本溯源还是《GPU Gems》中的一篇文章:&a href=&/?target=https%3A///gpugems/GPUGems3/gpugems3_ch16.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Chapter 16. Vegetation Procedural Animation and Shading in Crysis》&i class=&icon-external&&&/i&&/a&。它主要描述了在CryEngine中的实现原理,考虑到树干和树叶的不同,使用顶点色来对振幅进行控制,估计很多人都读过,实现细节可以去参考原文。&/p&&p&这里只说几个我们移植时的几个修改:&/p&&ol&&li&&b&使用Shader的全局变量&/b&。Shader.SetGlobalXXX一系列的接口就是为这种全局参数来设计的,简单易用。&/li&&li&临近测试我们美术比较忙,表示没时间对每棵树的模型去刷顶点色,于是摇摆的幅度控制采用了一个简化的方案——由顶点高度和一个美术设定的模型高度的比值来决定,目前只采用的线性差值,效果一般,勉强够用。&/li&&li&GPU Gem中的实现比较复杂,考虑了横向的和纵向的抖动,有不少计算在里面,这块可以根据自己项目的游戏类型和需求来修改和简化。&/li&&/ol&&h2&8. 整合&/h2&&p&把实现的各个天气效果整合成天气系统,由一个管理器来控制,可以模拟游戏中各个国家的气候风格,这是最后整合进游戏进行实际应用的步骤。由于我们大世界和战斗场景是两种完全不同的镜头方式,因此最终特效挂接的部分实现了两套不同的控制逻辑。除此之外,根据不同国家的特性,也将雨天和雪天统一为了特殊天气,比如在燕国这样靠北的国家,就只会下雪,而其他国家则是下雨。这其中有很多繁杂的与游戏业务相关的逻辑就不谈了,只聊几个实现过程中比较有感触的点:&/p&&ol&&li&&b&渐变需求&/b&。天气效果中所有的控制效果都有不同的渐变细节需要处理,比如下雪天气停止不能突然没有,而是要有渐渐消失的感觉;天气由晴天变阴天,也不应该突然黑下来,而是要有一个亮度渐变的过程。这些需要各个天气系统针对自己的效果做好差值的处理,这个过程使用了&b&DoTween&/b&来做,代码实现非常简单高效。&/li&&li&&b&对于需要跨天气控制的效果进行统一的管理&/b&。在最初的版本里,用于表现变暗效果的Tint Color由每一个天气进行各自的管理和差值,这里就有一些非常恶心的特殊代码要做处理,比如阴天效果的停止函数中,当进入晴天的时候需要把亮度逐渐调整到1,如果从阴天进入雨天,则不需要做这样的调整。天气效果的控制也就像是一个状态机,在单独的状态中如果需要考虑变换的前后逻辑,代码里就需要非常多if-else这样的逻辑判断。在迭代的过程中,把这块的控制抽象成为一个天气亮度管理器——BrightnessManager,它负责控制亮度并按照设定的速度在当前亮度和目标亮度之间做差值,这样对于任何天气效果,只需要在开启的时候设置默认的亮度值给亮度管理器,其他细节都不需要关心。同样还有用于风的参数控制的WindManager。&/li&&li&&b&效果与实现逻辑的分离&/b&。从表面上看,下雨和下雪是两个不同的天气效果,但是他们在程序的逻辑是有很大相似性的——都是控制特效的挂接和跟随逻辑。因此从逻辑实现上这两个天气效果有相同的逻辑,只是数据(特效)不同而已。另外下雨的效果有额外的一些涟漪的处理。于是使用面向对象的思路抽取一个FXWeather的公共父类来做代码的复用,方便维护。&/li&&/ol&&p&经过一些思考和迭代之后,最终C#代码中的类图如下所示。&/p&&figure&&img src=&/50/v2-ebabb0fee09198_b.jpg& data-rawwidth=&1370& data-rawheight=&923& class=&origin_image zh-lightbox-thumb& width=&1370& data-original=&/50/v2-ebabb0fee09198_r.jpg&&&/figure&&p&最终实现的天气系统类图&/p&&h2&9. 总结&/h2&&p&回顾整个天气系统的实现,其实没有特别有难度的东西,只是一些效果的应用和业务逻辑的编写。使用面向对象的继承和组合,再加上状态模式就完成了最后的需求。在效果方面,由于要兼顾移动平台的性能限制,相比端游的动态天气效果做了很多妥协和简化,尽量用20%的性能消耗做到60%的表现力,对于真实感等方面做了不少的妥协。&/p&&p&当然,现在实现的各种天气效果还很简陋,比如下雨还可以添加地面湿滑的材质效果,还可以制作暴风雨这样更动感刺激的天气效果,在沙漠中实现沙尘暴的感觉等等。这些东西,还需要更多的时间和精力来填满缺失的细节。&/p&&p&无论如何,希望这篇文章可以给期望增强游戏效果的同学一些启发,也同样期望有更好实现效果和方法的朋友不吝赐教,给予更多思路和经验的分享。&/p&&p&日凌晨 于杭州家中&/p&
0. 牢骚我发现,每个月的20+号是我有精力写博客的时间…… 这次项目算是经历的第一次严格意义上的渠道测试,更换了正式名称,见了更多玩家,开发组也经历的更多通宵……评价和数据如何暂时还未揭晓,趁着没那么忙,来还欠自己的“文章债务”。。。这篇博客…
&figure&&img src=&/50/v2-3d7c84d71630eb0eafefb5471662caf0_b.jpg& data-rawwidth=&1200& data-rawheight=&630& class=&origin_image zh-lightbox-thumb& width=&1200& data-original=&/50/v2-3d7c84d71630eb0eafefb5471662caf0_r.jpg&&&/figure&&h2&&b&官方资料&/b&&/h2&&p&&a href=&/?target=https%3A///Manual/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity User Manual 手册&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A///ScriptReference/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity - Scripting API&i class=&icon-external&&&/i&&/a&(API 详解)&/p&&p&&a href=&/?target=https%3A///cn/learn/tutorials& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity - Learn - Modules&i class=&icon-external&&&/i&&/a&(官方视频教程,适合英语好的同学)&/p&&p&&br&&/p&&h2&&b&Coursera&/b&&/h2&&p&&a href=&/?target=https%3A//www.coursera.org/specializations/wangluo-youxi-sheji-kaifa& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&基于 Unity 引擎的网络游戏设计与开发(复旦大学) | Coursera&i class=&icon-external&&&/i&&/a&&/p&&p&主要分为五个课程(可免费旁听):&/p&&ol&&li&游戏产业概论&/li&&li&游戏策划与设计&/li&&li&基于 Unity 引擎的游戏开发基础&/li&&li&基于 Unity 的游戏开发进阶&/li&&li&网络游戏与开发毕业项目&/li&&/ol&&p&&br&&/p&&h2&&b&国内教程达人&/b&&/h2&&p&对国内 Unity 学习者影响很大的两位:&/p&&p&一位是宣雨松,我是看他的《Unity3D 游戏开发》入门的。&/p&&p&&a href=&/?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&雨松MOMO程序研究院|专注移动互联网与Unity3D游戏开发的技术博客&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&p&一位是 Siki ,主要出教程,讲课逻辑非常清楚。原来是泰课在线的讲师,现在已经自己创办了一个教学网站。&/p&&p&&a href=&/?target=http%3A///user/7/teach& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Siki - 泰课在线&i class=&icon-external&&&/i&&/a&(里面有很多免费的教程)&/p&&p&&a href=&/?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&siki学院 - Unity游戏开发从入门到独立开发&i class=&icon-external&&&/i&&/a&(非广告,里面也有免费课程)&/p&&p&&a href=&/?target=https%3A//mp./s%3F__biz%3DMzA3ODY0MDIxMA%3D%3D%26mid%3D%26idx%3D1%26sn%3D27c3a0bca23c86fc8524f4ef%26chksm%3D84123aecb365b3fad836e5c9e7f0e5f8764593acd4bad%26mpshare%3D1%26scene%3D1%26srcid%3D0911rpG2TnpPcAvFs038J7sm%26key%3Dbb8bbafef0aa259b046dae2e62aed7be7da6b2bcea37fb180f7dd731a502ccefea%26ascene%3D0%26uin%3DMjI2MzQ2NTc4MQ%253D%253D%26devicetype%3DiMac%2BMacBookPro11%252C4%2BOSX%2BOSX%2B10.12.3%2Bbuild%%26version%3Dnettype%3DWIFI%26fontScale%3D100%26pass_ticket%3DwKyKQq2YgAo0oYlkBux58CDrVT8vkoxnlPDcd5XN2GoeYInAEoPIcKVuZNJ%252BJIiI& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity游戏开发视频教程目录 v17.3 - Siki 精心整理&i class=&icon-external&&&/i&&/a&(内含大量百度云课程链接)&/p&&p&&br&&/p&&p&&b&其他视频教程&/b&&/p&&p&&a href=&/?target=http%3A//www.mkcode.net/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&擅码网 - 专注于Unity3d游戏开发培训,unity3d,unity3d教程,unity3d视频教程&i class=&icon-external&&&/i&&/a&&/p&&p&顺别列出来擅码网的学习路线供大家参考(从入门到进阶):&/p&&p&Tips:仅知识点列举,完全可以靠看博客和自学学习以下知识点。有兴趣自行购买,不存在广告行为。&/p&&p&&b&第一阶段&/b&&/p&&ol&&li&C# 语言基础&/li&&li&Unity3D 引擎基础&/li&&li&C# 语言进阶(数据结构入门)&/li&&li&Unity3D 界面 UI(NGUI)&/li&&li&简单完整项目实例&/li&&/ol&&p&&b&第二阶段&/b&&/p&&ol&&li&角色动画控制(动画系统,导航系统)&/li&&li&C# 语言强化(委托与事件,常用设计模式)&/li&&li&客户端核心技术(UGUI,Lua)&/li&&li&中级项目实战&/li&&li&AI 人工智能&/li&&li&3D 数学基础(向量,欧拉角,四元数,矩阵等)&/li&&li&客户端资源管理(编辑器扩展, AssetBundle)&/li&&li&项目实战&/li&&/ol&&p&&a href=&/?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&泰课在线 - 国内专业的Unity在线学习平台&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///search/course/unity-1/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity 视频教程-麦子学院&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&蛮牛教育 - Unity在线学习平台&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&h2&&b&优质分享&/b&&/h2&&p&&a href=&/?target=https%3A///x/page/d016340mkcu.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&UNITE -Unity项目架构设计与开发管理&i class=&icon-external&&&/i&&/a&(Unity 大中华区总监分享游戏架构)&/p&&p&&a href=&/?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Learn OpenGL, extensive tutorial resource for learning Modern OpenGL&i class=&icon-external&&&/i&&/a&( 非常好的 OpenGL 英文教程,下面是翻译版)&/p&&p&&a href=&/?target=https%3A//learnopengl-cn.github.io/intro/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LearnOpenGL 中文翻译版&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&h2&&b&优质问答&/b&&/h2&&p&&a href=&/question//answer/& class=&internal&&宋健:计算机专业大学生如果想毕业后进入游戏行业,在大学期间应该怎样准备?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&会飞的路飞:怎么规划一个零基础学习Unity3D的“方法”或者“流程”?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&HellomotoV:怎么规划一个零基础学习Unity3D的“方法”或者“流程”?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&邓凯:通过Unity2D独立开发一款瓷砖式RPG游戏需要学习哪些知识?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&豆一:有哪些推荐的Unity3D开发方面的博客?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&王楠:Unity3D 游戏开发团队中,各角色划分是怎样的?&/a&&/p&&p&&a href=&/question//answer/& class=&internal&&王选易:如何学好 Unity?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&游侠:C# 如何进阶?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&权然:游戏引擎 Unity 的入门易精通难体现在哪?为什么?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&王楠:游戏引擎 Unity 的入门易精通难体现在哪?为什么?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&邓凯:游戏引擎 Unity 的入门易精通难体现在哪?为什么?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&钱康来:Unity 开发工作流程?&/a&&/p&&p&&a href=&/question//answer/& class=&internal&&周华:在Unity中StartCoroutine/yield return这个模式到底是怎么应用的?其中的原理是什么?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&彼得潘-朱涛:github上有什么好的unity开源项目?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&王致远:基于 Unity 中的 UGUI 或者 NGUI 插件,如何设计尽可能通用的 UI 框架?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&Jackie Run:Unity 游戏开发有哪些让你拍案叫绝的技巧?&/a&&/p&&p&&a href=&/question/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_1&utm_division=ge13_2& class=&internal&&Milo Yip - Unity 高级程序员应该具备怎样的能力?要怎样成长为 Unity 高级程序员?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&伍一峰:如何在Unity中实现MVC模式?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&康托耶夫:Unity有哪些让做项目事半功倍的插件值得推荐?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&庞巍伟:如何评价腾讯在Unity下的xLua(开源)热更方案?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&梁伟国Waigo:Unity3D如何有效地组织代码?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&kUANG tOBY:Unity3d客户端开发,要深入学习,更需要先从哪方面入手?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&凉鞋:使用Unity开发游戏,有流行的框架嘛?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&庞巍伟:Unity 项目中怎样正确的使用 Lua?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&Vinjn张静:如何系统的学习 Unity 3D 中的 shader 编写(nvidia cg 编程)?&/a&&/p&&p&&a href=&/question//answer/?utm_source=wechat_session&utm_medium=social&utm_campaign=ge13_2&utm_division=ge13_3& class=&internal&&Prodesire:如何系统的学习 Unity 3D 中的 shader 编写(nvidia cg 编程)?&/a&&/p&&p&&br&&/p&&h2&&b&论坛&/b&&/h2&&p&&a href=&/?target=http%3A//forum./forum.php& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity官方中文论坛 - &i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&游戏蛮牛 - 虚拟现实,unity3d教程&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///forum/index.php%3Fc%3Dcate%26fid%3D1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity3D论坛 - Unity圣典社区&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///forum.php& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity3D 联盟&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&h2&&b&博客&/b&&/h2&&p&&a href=&/?target=https%3A///zh-cn/dotnet/csharp/programming-guide/index& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&C# 编程指南 - 微软&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///archives/category/unity/%25E3%ugui%25E7%25A0%%25A9%25B6%25E9%%25E3%& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【UGUI研究院】 | 雨松MOMO程序研究院&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/p/& class=&internal&&利用Unity UGUI制作酷炫UI效果(制作篇)&/a&&/p&&p&&a href=&/?target=http%3A//blog.csdn.net/aa/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&全面理解 Unity UI 系统&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A//bitbucket.org/Unity-Technologies/ui& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity-Technologies / UI - Bitbucket&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/uwa4d& class=&internal&&UWA:简单优化、优化简单&/a&&/p&&p&&a href=&/?target=https%3A///2012/11/memory-in-unity3d/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity 3D中的内存管理&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A//blog.csdn.net/candycat1992/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【Unity技巧】Unity中的优化技术 - candycat - CSDN博客&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///crazylights/p/3897742.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity3D热更新全书-PageZero - 疯光无线 - 博客园&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A//blog.csdn.net/pbymw8iwm/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&关于游戏架构设计的一些整理 - 高科的专栏 - CSDN博客&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///game/39.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity 5 中的全局光照技术详解(建议收藏)&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A//blog.csdn.net/poem_qianmo/article/category/2681301& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity3D Shader 毛星云(浅墨)的专栏 - CSDN博客&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A//blog.csdn.net/zhuangyou123/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&猫都能学会的Unity3D Shader入门指南&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///BLoodMaster/archive//1769774.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&C# Socket编程 同步以及异步通信 - BLoodMaster - 博客园&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A///articles/unity-now-youre-thinking-with-components--gamedev-12492& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity: Now You're Thinking With Components&i class=&icon-external&&&/i&&/a&(英文)&/p&&p&&a href=&/?target=http%3A///game/67.html%3Futm_source%3Dtuicool%26utm_medium%3Dreferral& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&漫谈游戏中的人工智能 - CocoaChina_让移动开发更简单&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A///r/Unity3D/comments/1nb06h/unity_design_patterns_and_concepts_looking_for/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity design patterns and concepts, looking for good sources o r/Unity3D&i class=&icon-external&&&/i&&/a&(外国人在开发过程中搜集的文章链接)&/p&&p&&a href=&/?target=http%3A//liweizhaolili./blog/%23m%3D0%26t%3D1%26c%3Dfks_082071& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&阿赵的博客&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///neverdie/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&王选易 - 博客园&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&技术人生 · &i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A//www.unity3d.top/unity_web/linkList.php& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity学习屋&i class=&icon-external&&&/i&&/a&(里面有针对多个知识点的优质博客和分享)&/p&&p&&br&&/p&&h2&&b&书籍(部分我看过关于 Unity 的书,参考链接为豆瓣书评)&/b&&/h2&&p&&br&&/p&&p&&a href=&/?target=https%3A///subject/3351935/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《C# 图解教程》&i class=&icon-external&&&/i&&/a&&/p&&p&入门不错的书。&/p&&p&&a href=&/?target=https%3A///subject/1793123/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《C# 入门经典》&i class=&icon-external&&&/i&&/a&&/p&&p&很经典的书。&/p&&p&&a href=&/?target=https%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Unity3d游戏开发》&i class=&icon-external&&&/i&&/a&&/p&&p&宣雨松著,适合入门级新手。&/p&&p&&a href=&/?target=https%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Unity 4.x从入门到精通》&i class=&icon-external&&&/i&&/a&&/p&&p&官方教材,现在来说,有点老了。&/p&&p&&a href=&/?target=https%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Unity3D 脚本编程》&i class=&icon-external&&&/i&&/a&&/p&&p&适合 C# 和 Unity 进阶。&/p&&p&&a href=&/?target=https%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Unity 游戏设计与实现》&i class=&icon-external&&&/i&&/a&&/p&&p&万代南梦宫的资深开发人员编写,不适合初学者,适合有一定项目基础的人。&/p&&p&&a href=&/?target=https%3A///subject/1400419/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《3D 数学基础》&i class=&icon-external&&&/i&&/a&&/p&&p&学习需要掌握的 3D 数学知识。&/p&&p&&a href=&/?target=https%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《游戏编程模式》&i class=&icon-external&&&/i&&/a&&/p&&p&还未看完,不过感觉还不错。&/p&&p&&a href=&/?target=https%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《设计模式与游戏完美开发》&i class=&icon-external&&&/i&&/a&&/p&&p&结合着案例学习设计模式。&/p&&p&&a href=&/?target=https%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Shader 入门精要》&i class=&icon-external&&&/i&&/a&&/p&&p&Shader 入门非常不错。&/p&&p&&a href=&/?target=https%3A///subject//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Unity 人工智能游戏开发》&i class=&icon-external&&&/i&&/a&&/p&&p&学习游戏开发中的人工智能,还不错。&/p&&p&&br&&/p&&h2&&b&Unity 面试经验&/b&&/h2&&p&&a href=&/p/?utm_source=wechat_session&utm_medium=social& class=&internal&&整理的前人Unity 面试的笔记&/a&(已经整理大量面经)&/p&&p&&a href=&/?target=http%3A///yougoo/p/7241139.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity 工作经历+近期面试经历&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A//blog.csdn.net/mylefteyeisl/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity3D面试--真实的面试 - 我的Unity3D - CSDN博客&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///p/59ad5e8ba457& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&unity3d游戏公司面试常见问题全接触&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A//blog.csdn.net/dingxiaowei2013/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity全面的面试题(包含答案) - 学无止境的专栏 - CSDN博客&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///sitonmoon/p/5510617.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity游戏程序员面试题及解答 - 拔丝煎面 - 博客园&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///blog-.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Unity3D面试题整合(转载) - 何惜一笑的博客&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&h2&&b&持续更新中,整理不易,欢迎点赞!&/b&&/h2&
官方资料(API 详解)(官方视频教程,适合英语好的同学) Coursera主要分为五个课程(可免费旁听):游戏产业概论游戏策…
&figure&&img src=&/50/v2-7f398fcdfa9_b.jpg& data-rawwidth=&1920& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1920& data-original=&/50/v2-7f398fcdfa9_r.jpg&&&/figure&&p&全局光照(Global Illumination,简称 GI), 作为图形学中比较酷的概念之一,是指既考虑场景中来自光源的直接光照,又考虑经过场景中其他物体反射后的间接光照的一种渲染技术。&/p&&p&大家常听到的光线追踪,路径追踪等同样很酷的概念,都是全局光照中人气较高的算法流派。&/p&&p&&br&&/p&&p&而这篇文章将围绕全局光照技术,介绍的要点有:&/p&&ul&&li&全局光照的基本概念&/li&&li&全局光照的算法主要流派&/li&&li&全局光照技术进化编年史&/li&&li&光线追踪 Ray Tracing&/li&&li&路径追踪 Path Tracing&/li&&li&光线追踪、路径追踪、光线投射的区别&/li&&li&环境光遮蔽 Ambient Occlusion&/li&&/ul&&p&&br&&/p&&p&&br&&/p&&h2&一、行文思路说明&/h2&&p&&br&&/p&&p&阅读过《Real-Time Rendering 3rd》第九章的读者们都会发现,作为一章关于全局光照的章节,作者讲了不少在严格意义上全局光照主线以外的内容,如Reflections、Refractions、Shadow等节,而这些内容在《Real-Time Rendering 2nd》中,其实是放在Chapter 6 Advanced Lighting and Shading一节的。&/p&&p&既然《Real-Time Rendering 3rd》第九章标题就叫全局光照,核心内容也是全局光照,本文即决定脱离原书安排的100来页的多余内容,以全局光照的主线内容为主,构成一篇包含全局光照基本概念,主要算法流派,以及全局光照技术进化编年史,和全局光照算法中人气较高的光线追踪、路径追踪等算法的综述式文章。&/p&&p&&br&&/p&&p&&br&&/p&&h2&二、全局光照&/h2&&p&&br&&/p&&p&全局光照,(Global Illumination,简称 GI), 或被称为Indirect Illumination, 间接光照,是指既考虑场景中直接来自光源的光照(Direct Light)又考虑经过场景中其他物体反射后的光照(Indirect Light)的一种渲染技术。使用全局光照能够有效地增强场景的真实感。&/p&&p&即可以理解为:全局光照 = 直接光照(Direct Light) + 间接光照(Indirect Light)&/p&&figure&&img src=&/v2-18804e7acb378cd88c0caf3d3768faf2_b.jpg& data-rawwidth=&1270& data-rawheight=&948& class=&origin_image zh-lightbox-thumb& width=&1270& data-original=&/v2-18804e7acb378cd88c0caf3d3768faf2_r.jpg&&&/figure&&p&
图1 Direct illumination&/p&&figure&&img src=&/v2-71fca685f697dc44ad0ab1f8b0d04fb8_b.jpg& data-rawwidth=&1270& data-rawheight=&948& class=&origin_image zh-lightbox-thumb& width=&1270& data-original=&/v2-71fca685f697dc44ad0ab1f8b0d04fb8_r.jpg&&&/figure&&p&
图2 Global illumination = Direct illumination +Indirect illumination&/p&&p&上述两幅图片来自CMU 15-462/15-662, Fall 2015 Slider,Lecture 14: Global Illumination,当然,细心的朋友也可以发现,它也被《Physically Based Rendering,Second Edition From Theory To Implementation》选作封面。&/p&&p&同样可以看到,加入了Indirect illumination的图2,在直接光源(阳光)照射不到的地方,得到了更好的亮度和细节表现,从而使整张渲染效果更具真实感。&/p&&p&&br&&/p&&p&虽说实际应用中只有漫反射全局照明的模拟算法被称为全局照明算法,但其实理论上说反射、折射、阴影都属于全局光照的范畴,因为模拟它们的时候不仅仅要考虑光源对物体的直接作用还要考虑物体与物体之间的相互作用。也是因为,镜面反射、折射、阴影一般不需要进行复杂的光照方程求解,也不需要进行迭代的计算。因此,这些部分的算法已经十分高效,甚至可以做到实时。不同于镜面反射,光的漫反射表面反弹时的方向是近似“随机”,因此不能用简单的光线跟踪得到反射的结果,往往需要利用多种方法进行多次迭代,直到光能分布达到一个基本平衡的状态。&/p&&p&&br&&/p&&p&&br&&/p&&h2&三、全局光照的主要算法流派&/h2&&p&&br&&/p&&p&经过几十年的发展,全局光照现今已有多种实现方向,常见的全局光照主要流派列举如下:&/p&&ul&&li&Ray tracing 光线追踪&/li&&li&Path tracing 路径追踪&/li&&li&Photon mapping 光子映射&/li&&li&Point Based Global Illumination 基于点的全局光照&/li&&li&Radiosity 辐射度&/li&&li&Metropolis light transport 梅特波利斯光照传输&/li&&li&Spherical harmonic lighting 球谐光照&/li&&li&Ambient occlusion 环境光遮蔽&/li&&li&Voxel-based Global Illumination 基于体素的全局光照&/li&&li&Light Propagation Volumes Global Illumination&/li&&li&Deferred Radiance Transfer Global Illumination&/li&&li&Deep G-Buffer based Global Illumination&/li&&li&等。&/li&&/ul&&p&而其中的每种流派,又可以划分为N种改进和衍生算法。&/p&&p&如光线追踪(Ray Tracing)派系,其实就是一个框架,符合条件的都可称为光线追踪,其又分为递归式光线追踪(Whitted-style Ray Tracing),分布式光线追踪(DistributionRay Tracing),蒙特卡洛光线追踪(Monte Carlo Ray Tracing)等。&/p&&p&而路径追踪(Path tracing)派系,又分为蒙特卡洛路径追踪(Monte Carlo Path Tracing),双向路径追踪(Bidirectional Path Tracing),能量再分配路径追踪(Energy Redistribution Path Tracing)等。&/p&&p&其中有些派系又相互关联,如路径追踪,就是基于光线追踪,结合了蒙特卡洛方法而成的一种新的派系。&/p&&p&&br&&/p&&p&&br&&/p&&h2&四、全局光照技术进化编年史&/h2&&p&&br&&/p&&p&这节以光线追踪和路径追踪派系为视角,简单总结一下全局光照技术发展早期()的重要里程碑。&/p&&p&&br&&/p&&h2&4.1 光线投射 Ray Casting [1968]&/h2&&p&光线投射(Ray Casting),作为光线追踪算法中的第一步,其理念起源于1968年,由Arthur Appel在一篇名为《 Some techniques for shading machine rendering of solids》的文章中提出。其具体思路是从每一个像素射出一条射线,然后找到最接近的物体挡住射线的路径,而视平面上每个像素的颜色取决于从可见光表面产生的亮度。&/p&&figure&&img src=&/v2-328f1c086efb234a96f06e_b.jpg& data-rawwidth=&1478& data-rawheight=&888& class=&orig}

我要回帖

更多关于 unity 初始化 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信