关键词不能为空

当前您在: 主页 > 英语 >

Unity之工作总结

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-01 21:59
tags:

-

2021年2月1日发(作者:really是什么意思)



图片格式






--------------- -------------------------------------------------- -------1


DrawCall





--------------- -------------------------------------------------- --------2





































?



图片格式:



NGUI


生成的图集的图片格式是


PNG


格式,但是无论是什么 格式的图片



Unity


都会自己生成 一套格式,并


且打包的时候不会用文件夹下面的格式,而是


Un ity


自己格式。




如果你用的


UITexture


你可 以对每一张图来修改格式,比如颜色数比较少的图片可以使用


16bit


,如果没有


透明,可以使用


pvr

或者


etc


这样图片会小很多。



如果是


UISprite


只要有透明的



就必须使用


RGBA32


要不然


UI


会很难看。



除去



UITextuer

< p>


Atlas


的图片之外(因为有透明),其余的 贴图必须是


2


的幂次方。因为只有


2< /p>


的幂次方


图片,并且没有透明通道的才会被压缩。


Ios


会被压缩成


pvr


格式 ,


Andriod


会压缩成


etc


格式。压缩之后会


小很多。



人物贴图



场景题图



特效贴图



一定要是

< br>2


的幂次方。



贴图透明通道分离,压缩格式设为


ETC/PVRTC


最初我们使用了


DXT5


作为贴图压缩格式 ,希望能减小贴图的内存占用,但很快发现移动平台的显卡是不


支持硬件解压

< p>
DXT5


的。因此对于一张


1024x1024< /p>


大小的


RGBA32


贴图,虽然


DXT5


可将它从


4MB


压缩



1MB


但系统将它送进显卡之前,


会先用


CPU

< br>在内存里将它解压成


4MB



R GBA32


格式


(软件解压)



然后再将这


4MB


送进显存。于是在这段时间 里,这张贴图就占用了


5MB


内存和


4 MB


显存;而移动平台


往往没有独立显存,需要从内存里抠一块 作为显存,于是原以为只占


1MB


内存的贴图实际却占了


9MB





所有不支持硬件压缩格式都有相同的问题。



解决方案:





现在


Andriod


硬件最广泛支持的时


Etc ,IOS


上支持的时


PVRTC


。但 这两种格式都是不带透明(


Alpha



通道的,因此我们需要将每张原始贴图的透明通道分离出来,写进另一张贴图的红色通道里,这两张特图


都采用


Etc/Pvrtc


压缩。

< p>
渲染的时候



将两张贴图都送进显存。


同时



我们修改了


NGUI



shader


在渲染时第


二张贴图的红色通道写入到第一张 贴图的透明通道里恢复原来的颜色:



1.



2.



3.



4.



5.



6.



}



fixed4 frag (v2f i) : COLOR



{



fixed4 col;



= tex2D(_MainTex, rd).rgb;



col.a = tex2D(_AlphaTex, rd).r;



return col *




这样,


一张


4MB



1024x1024


大小的


RGBA32


原始贴图,


会被分离并压缩成两张


0.5MB



ETC/PVRTC


贴图(我们用的是


ETC/PVRTC 4 bits


)。它们渲染时的内存占用则是


2x0.5+2x0.5=2MB





?



DrawCall



当两个


renderQueue


相邻的


DrawCal l


使用了相同的贴图、材质和


shader

实例时,这两个


DrawCall


就可以

< br>合并。但需要注意的是


DrawCall


合并不见得会提 高性能,有时反而会降低性能




< /p>


如果是


UIGeometry


为了渲染绘 制准备数据,那么


UIDrawCall


其实是定义了渲染绘制 需要的基本组件。这


里拿煮菜做个比喻帮助理



解:


UIGeometry


好比为煮菜准备食材,


UIDrawCall


好比是煮菜的工具(锅,炉

< br>子等),


UIPanel


就是大厨了决定着什么时候该煮



菜,


UIWidget



UILabel



UIS prite



UITexture


)是 这道


菜怎么样的最终呈现。



UIWi dget


分别用


UpdateGeometry



WriteToBuffers


< br>UIGeometry



ApplyTransform




WriteToBuffers< /p>



行封装调用,


ApplyTransf orm


是根据


UIPanel


的坐标调 整


Vertices


的坐


< p>
标,


WriteToBuffers


< p>
UIGeometry



Vertices



UVs



Colo rs


添加进


UIPanel



Vertices



UVs



Colors



BetterList


中。





这里还有一个细节就是:


UIGeometry


中的


Vertices< /p>



UVs



Co lors



BetterList


的< /p>


buffer


什么时候得到,


因为这些都




UIWidget


或其子类的信息,


所以在


UIWidget

< p>
的子类


UILabel



UISprite



UITexture



OnFill


函数生成



UIGeometry



BetterList



buffer



UIWidget


这个脚本中的两个函数:


WriteToBuffers



OnFill



UpdateGeometry




WriteToBuffers



OnFill


这两个函数都是将


Vertice s



UVs



Colors



add


进参数的


List


中去,查看



WriteToBuffers


的调用出发现其参数是


UIP anel



Vertices



UVs



Colors




OnFill


的参数是



UIGeometry


Vertices



UVs



Colors







WriteToBuffers< /p>


只是对


UIGeometry


的封装调用 ,也就是说将


UIGeometry



Vertices



UVs



Colors



信息


a dd



UIPanel


的对应


List


中。



UIG eometry


的脚本,一直有一个疑问:


UIGeometr y



Vertices



UVs



Colors


的< /p>


List


没有看到


add


方法的


执行,



只有在


WriteToBuffers



add


。直到看到了


OnFill


才恍然大悟,虽 然


UIWidget



OnFill< /p>


是虚函数,


没有具体实现,看了下



UISprite


重写的


OnFill


函数,就是把


Vertices



UVs



Colors


添加到


UIGeometry



Ve rtices



UVs



Colors


中。所有


UI


组件的


Vertices



UVs



Colors


都汇集到

< br>UIPanel



Vertices


UVs



Colors


去了,然后



UIPanel

< br>指定给


UIDrawCall


渲染就行了



UIWidget


的一些实现细节,


MakePixelPerfect():



game Object



localPosition

< br>和


locaScale


进行微调和纠正。


SetDirty():


调用


UIPanel



SetDirty()


对组件的变更进行重建 (


rebuilt)




Uiwidge UIGeometry& UIDrawCall


的关系:



UIWidget


中有两个变量


UiDrawCall mDrawcall



UIGeometry mGeo



verts uvs cols



BetterList,


然后


UiWi dget



UpdateGeometry

< br>函数对


UIGeometry



ApplyTransform()



WriteToBuf fer()


调用进行更新


.



一个


UIwidget


都有一个


UIGeometry


但是不都有一个


UIDra wCall,


而是通过


Batch


合并 达到减少


DrawCall


的数量,


U iDrawCall


是有


UiPanel


生成的。







DrawCall


的数量优化





根据上述描述可以得出一个结论: 使用相同


material


的连续的


U iwidget(UILable UiSprite)


公用一个


UIDrawcall


。通过这个结论我们可以得到一个解决


DrawCall


过多的问题,


UIPanel


生成


DrawCall


时是


F ill()


方法。


Fill


方法对< /p>



进行检测把使用相同


Material< /p>


的连续的


Uiwidget


合并生成一个


DrawCall ,


的排序是根据


UiWidget



Depth


进行的 。所以解决方案有两种:



1.


修改< /p>


UiWidget(UiLable UIwidget )


的< /p>


Depth,


限定



的排序



2.


重写

< br>Uiwidget



CompareFunc()


方法。


(重写


UIWidget

< p>


CompareFunc


也是可以的,


按照


Material



name


优先排序,只有当


material


一样是才考虑


depth


进行排序:)



3.


无重叠时自动重排。



绘制顺序按照


Hierarchy








采用第二种方式减少


DrawCall:



Material leftMat = al;



Material rightMat = al;


if (leftMat == rightMat)


{



if ( < ) return -1;



else if ( > ) return 1;



else return 0;



}



if(leftMat !=null & rightMat != null)



return e(,);



if (leftMat != null) return -1;



if (rightMat != null) return 1;







return (tanceID() < tanceID()) ? -1 : 1;



夹层问题:



因为

Material


使用的


Shader

使用了透明,这样就不能做深度测试,也就是


Mesh


的“ 深度”是不影响的,


这样最终的显示就跟


Shader




renderQueue

< br>有关了,即


renderQueue


越大,显示的越靠前 面(重叠的图层,


renderQueue


越大,


越靠前)



当然现在只有增加一



DrawCall


(如多使用 一个


UIPanel


或用另外一个


Ma terial)


来做到


Material


的夹层效果。






特效层级:






粒子系统的渲染顺序列默认为


3000



NGUI


的渲染顺序默认是从


30 00


开始,当有嵌套的


Panel


或者


Deoth


更高的


panel


时,


NGUI


的渲染顺序会高于


3000






解决方案:



1.


修改


Ngui


中的


panel


脚本中的默认


RenderQueue


调整到


3000


以下,这样就不会挡住 粒子特效。当


窗口显示在特效上面时把窗口的


RenderQu eue


调整到


3000


以上,就解决了 。







2.


使用另外一个摄像机显示特效, 但是


Ui


窗口切换时不太好控制



3.


修改例子特效的


shader


中的


RenderQueue


的值(需要考虑特 效中的层级关系)



一级界面



二级界面



..


浮动窗口




1.


不同图集







项目中做到复杂一些的界面,经常会用到多个图集,以技能界面为例,项目中常用的图片放到 共用图


集中,



这是一个图集,技能界 面本身独有的元素,比如跟技能职业相关的背景,算作第二个图集,还有一


些技能图标,



图标单独归类到一个图集中,再一个就是字体的图集。基本一 个界面如此分法,最多需要


4


个图集。


NGUI


的图集之间的



处理,默认是 靠调整控件的


Z


值来区分的,但是这里他可以调整同一个图集< /p>


每个一个控件的


Z


值,其实不是很好。经 常会出现图层相互遮挡的情况,尤其对于控件比较多的界面,一


段时间回过来再修改界面 的时候,整个要崩溃。



解决方案:



UIPanel


中,


为每一个


Material


添加一个


layer


的变量,


当同一图层靠


depth


来决定前后关


系,不同图层靠


layer


来决定前后关系,在绘制


UIDrawCall


的时候,根据


layer


对跟节点做一定偏移。


这样就能从


Z


值中解放出来。



如果大家也有碰到图层的问题,


可以参考这样的做法,以此种方 法来处理图


层关系,简单,做过项目的圈套


UI


,还未有不能解决的情况。




?



UI


自适应




Scaling Style


的作用是制定

< br>UiRoot


的缩放类型,如果是


PixelPerfe ct ,Minimum Height



Maximum


Height


才起作用,


scaling style


选择的是



Pixelperfect


要对


Minimum Height



Maximum Height


进行设置。


(


如果是


Pixe lPerfect


缩放类型,当屏


幕的分辨率大于


Maximum Height



则以


Maximum Height


为基础缩放,


反之,


如 果屏幕分辨率小于


Minimum


Height


则以


Minimum Height


为 基础进行缩放。例如,如果屏幕高度为


1000


,而设置的


Maximum Height


值为


800


,则


UI


界面整体放大为原来的


1000/800=1.25


倍。


)


FixedSize :



Manual Height


有关



FixedSizeOnMobiles :



Manual Height


有关




只是针对


IOS



Andro id


上的判断,也就是说只有


IOS



Android


平台下


FixedSi zeOnMobiles


才起作用


.


FixedSize



FixedSizeOnMobiles



则缩放只以


Manual Heig ht


为参考,


屏幕分辨率的高度值不同于此设

< br>置值时,则根据其比例(即


Screen Height / Manual H eight


)对整棵


UI


树的进行“等 比”缩放(宽度的缩放


比也是此比例值)。


< br>注释:如果设置


FixedSize,


(以


UiRoot


默认值进行高度缩放)是不会改变的,不管实际屏


幕分辨率的像素是多少,


Anchor Stretch

的背景图片高度始终是



下的


UIW idget



height


参数一直都 是实际的值




UIRoot


是基于高度进行缩放的如何做以宽度适配。


< br>UIRoot


是基于高度放缩的,即放缩的比例是以高度为参考的,所以


UIRoot


有一个


manualHeight


的参


数。那么对于横版游戏显然不行,要是


能实现基于宽度放缩。所以可以通过设置一个“


manu alWidth


”的


参数来做。比如我们项目中使用的是



1024


作为


U I


的宽屏尺寸,通过换算设置


manualHeight


的值:



int height = (2, );


manualHeight = * 1024 /


//


基于宽度的屏幕分辨率自适应




注释:


UIRoot


其实就做了一件事情:根据




Height


的比例来调整


UIRoot




loaclScal


,从而保证


UIWidget



UISprite



UILabel


)可以按照其本身的 大小进行设置,而不用经过复杂


的换算过程。




?



资源分离打包与加载



资源分离打包与 加载是最有效的减小安装包体积与运行时内存占用的手段。一般打包粒度越细,这两个指


标就越小。但打包粒度也并不是越细就越好。如果运行时要同时加载大量小


bundle


,那么加载速度将会非


常慢——时间都浪费在协程之间的调度和 多批次的小


I/O


上了。此需要有策略地控制打包粒度。一般只 分


离字体和贴图这种体积较大的公用资源。




?



关闭贴图的读写选项




Unity


中导入的每张贴图都有一个启用可读可写(


Read/Write Enable


)的开关,对应的参数是


able



选中贴图后可在


Impo rt Setting


选项卡中看到这个开关。


只有打开这个开 关才可


以对贴图使用


el


,读取或改写 贴图资源的像素,但这就需要系统在内存中保留一份贴图的


拷贝,


以供


Cpu


访问,


但是一般游戏运行 过程中不会有这样的需求,


因此我们对所有贴图都关闭这个开关,


只在中做贴图导入后处理(比如对原始提贴图分离透明通道)时需要打开这个选项。这样,上文提到的


1024x1024


大小的贴图,其运行时的


2 MB


内存占用又可以少一半,减小到


1MB



Texture


图片空间和内 存占用分析



纹理大小影响:



可以将其他(非二的幂



-

< p>


NPOT


”)纹理大小用于


Unity


非二的幂纹理大小通常占用的内存稍多一点, 由



GPU


进行读取的速度可能较慢 ,


因此考虑到性能,


最好尽可能使用二的幂大小。


如果平台或



GPU


不支持



NPOT


纹理大小,




Unity


会缩放纹理并将其填补为下一个二的幂大小,


这甚至会使用更多内存并使加载


更慢




Iphone




空项目




空间占用量


42.3M





ipa



10M


10



1200*520


无压缩


Texture



单张图占用量


2.8M




空间占用两


70.2M



ipa




22.9M


10


< br>1200*520


压缩成


1024*1024 PVRTC4



单图占用量


0.5M


空间占用量


47.3M



ipa




13.2M


10



1024*1024


无压缩


Texture




单图占用量


4M






空间占用量


82.M





ipa



14.6M


10



1024*1024


压 缩为


PVRTVC4


格式




单张图占用量


0.5M



空间占用量



47.3M



ipa




11.6M





综上所述:






1.2



N


次方大小的图片会得到引擎更大的 支持,包括压缩比率,内存消耗



打包压缩大小,而且支持


的力度非常大。






2.


减小 图片的占用大小和内存方式有:图片大小变化(


Maxsize



,


色彩位数变化(


16


位色



32


位色),


压缩


PVRC


格式







3.U3D


对于图片的格式是自己生成的,而并不是你给它什么它用 什么格式。一张


1024*1024


图在无压

< br>缩的格式下,


他会被


U3D


无压 缩文件像是存放,


也就是说


U3D


里的


Texture Perview


里显示的占用大小


**M


不只是内存占用的大小,还是空间占用大小。




Unity


图片压缩格式介绍:






U3D


的内部机制为自动生成图片类型来替代我们的图片在图片的压缩方式需要进行谨慎的选择。



几种


比较主要的压缩格式:



RGBA32 BIT/AutomaticTurecolor



(256*256 256k)















格式为无压缩最保真格式,最消耗内存和空间的格式。



RGBA16 BIT/






格式为无压缩

16


位格式,比


32


位节省一半的 空间和内存,与


Automatic16


相同。



RGBA Compressed PVRTC 4bits


格式为


PVRTC


图片格式,







它相当 于把图片更改了压缩方式新生成了一个图片来替换原来的图片格式




贴图格式:




3D


游戏中贴图的的分类:





UI


贴图





ui


是按照



1280*853


比例出的图





3D


场景贴图



主要是因为多重采样的缘故。


3D


游戏一般来说都是受摄像机 远近大小改变而采取不同的采


样大小,如果不设置多重采样的话,在远处有非常多的白色 噪点。






2D


游戏






所有都不需要勾选多重采样,具有


3D


性质的贴图,我们都需要勾选上


G ENERATE MIP MAPS


,这样会


使贴图大小增加< /p>


25%


这样。





正方贴图与非正方贴图也要区分


:


非正方贴图只有


16


位的压缩(相当于 真彩色减半),所以最好游戏中都是正方的贴图。



正方贴图:



IOS






普通不透明:



RGB PVRTC 4 BITS




普通透明:



RGBA PVRTC 4 BITS



(256*256 32kb)


Androis:




普通不透明:



RGB ETC 4 BITS



(256*256 32kb)




普通透明:因为没有通用的兼容模 式,所以一般情况是用


RGBA 16 BITS


或是针对不 同的


GPU


选择



DXT5/ATC8 BITS/ETC2 8BITS



如果技术支持,


可以采用



RGB ETC 4 BITS


加一张


Alpha 8


的贴图来实现


透明效果。





非正方形:





一般采用


16


位压缩,


16


位色会带来颜色损失,如果本来美术就按


16


位色画的话,就不会带来损失。日


本的很 多


2D


游戏都是采用那个


16


位来画的。少渐变



和艳色。





不透明贴图:



RGB 16 BIT



256*256



128KB






透明贴图:



RGBA 16 BIT




256*256



128KB





高清不压缩贴图:




RGBA 32 BIT



(256*256 256kb)



对于不重要的贴图,模糊度低的贴图,建议不仅要采取像素压缩,还要直接压缩其大小。如光照贴图压到


512



256


。如背 景原本


1024


的图直接压到


256< /p>


。玩家不注意到就可以了。




注意:






U3D


所有图片的压缩格式都会以另 一种方式存储,不会以你给的方式存储,只有你指定了某种格式,他才会转换成


你要的格 式。而且在


Andriod


里的并不一定有效,因为


Andriod


的机型多,


GPU


的渲染方式也不一样,


RGBA16


适应


于所有机型





?



GameObject


数量




场景中


GameObject


的数量也是衡量性能的重要指标,频繁的创建



和销毁


GameObjec


是非常耗 时,场景


中存在的


GameObject


会占用内存,如果


GameObject


上挂有物体的话,每 个


GameOject


的脚本都需要实力


化。






?



整理图集




整理图集的主要目的是节省运行时内存(虽然有时也能起到合 并


DrawCall


的作用)。从这个角度讲,显


示一个界面时送进显存的图集尺寸之和是越小越好。一般有如下方法可以帮助我们做到这点:



1)



< p>
在界面设计上,尽量让美术控件设计成九宫格拉伸,即


UiSprite< /p>


的类型是


Sliced.


这样美术素材可 以


切出一张很小的图片在


unity


中 做拉伸。


当然一个九宫格也就意味着其定点数量会从


4


个增加到


16



(如果 九宫格的中心格子采用


Tiled


做平铺类型的话,

< p>
定点数会更多)



构建


D rawCall


的开销会更大。


但一般只要

DrawCall


安排合理就不会出问题



2)



同样在界面设计上



尽量设计成对称的 形式,这样在切图的时候美术切图的时候就可以只切一部分,


我们在

Untiy


中将完整的图案拼出来,比如一个圆形图案我们可以只切四分之一,不过 与上述第一点


类似这样会增加定点个数,


同时也会增加场景中< /p>


GameObject


的个数,


因为


GameObject


的数量增多时


会占用 跟多的内存,所以只对尺寸较大的图案采用这种方法。


-


-


-


-


-


-


-


-



本文更新与2021-02-01 21:59,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/595396.html

Unity之工作总结的相关文章

  • 爱心与尊严的高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊严高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊重的作文题库

    1.作文关爱与尊重议论文 如果说没有爱就没有教育的话,那么离开了尊重同样也谈不上教育。 因为每一位孩子都渴望得到他人的尊重,尤其是教师的尊重。可是在现实生活中,不时会有

    小学作文
  • 爱心责任100字作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任心的作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文