内容将会持续更新,有错误的地方欢迎指正,谢谢!
拥有更好的学习体验 —— 不断努力,不断进步,不断探索 |
助力快速掌握 面试题 为面试者节省宝贵的学习时间,避免困惑! |
文章目录
- 一、内存优化
- 1、资源内存占用
- 1.1、纹理
- 1.2、网格
- 2、引擎模块自身内存占用
- 3、托管堆内存占用
- 二、GPU渲染管线
- 三、u3d提供了一个用于保存读取数据的类是什么?
- 四、Coroutine的原理?
- 五、Image和RawImage的区别?
- 六、Material和Physic Material区别?
- 七、如何检测物体是否被其他对象遮挡?
- 八、获取、增加、删除组件的命令分别是什么?
- 九、什么是LightMap?
- 十、MeshCollider和其他Collider的不同?
一、内存优化
内存开销无外乎分为以下三大部分:1、资源内存占用;2、引擎模块自身内存占用;3、托管堆内存占用
1、资源内存占用
在一个较为复杂的大中型项目中,资源的内存占用往往占据总体的70%以上,一般来说,项目的资源主要可分为纹理、网格、动画、音频、材质、着色器、字体等等,其中纹理、网格、动画、音频是最容易造成大内存开销的资源。
1.1、纹理
纹理资源可以说是几乎所有游戏项目中占据最大内存开销的资源,一个2048x2048的纹理可能占用内存16M,因此项目中纹理资源的使用是否得当会极大的影响项目内存的占用。
-
纹理格式
纹理格式是研发团队最需要关注的纹理属性,因为它不仅影响纹理的内存占用,同时还决定了纹理的加载效率,一般来说建议开发团队尽可能根据硬件的种类选择硬件支持的纹理格式。 -
纹理尺寸
一般来说,纹理尺寸越大,则内存占用越大,所以尽可能降低纹理尺寸,如果512x512的纹理对于显示效果已经够用,那么就不要用1024x1024的纹理,因为后者的内存占用是前者的四倍。 -
MipMap
MipMap旨在有效降低渲染带宽的压力,提升游戏的渲染效率,但是,开启MipMap会将纹理内存提升1.33倍,对于具有较大纵深感的游戏来说,3D场景模型和角色建议开启MipMap,但是不要对UI也开启MipMap功能,开启MipMap并不会提升渲染效率,反倒会增加无谓的内存占用。 -
Read&Write
一般情况下,纹理资源的“Read&Write”功能在Unity引擎是默认关闭的,但是有的纹理资源仍会开启该选项,开启该选项会将纹理内存增加一倍。
1.2、网格
网格资源在较为复杂的游戏中,往往占据较高的内存
Mesh资源的数据中常常会包含大量的Color数据、Normal数据和Tangent数据,这些数据的存在将大幅度增加Mesh资源的文件体积和内存占用,其中Color数据和Normal数据主要为MAX和Maya模型导出时设置所生成,而Tangent一般为导入引擎时生成,一般这些数据主要为shader所用,来生成酷炫的效果。
2、引擎模块自身内存占用
3、托管堆内存占用
对于绝大数项目来说,其托管堆内存是由Mono分配和管理,托管的本意是Mono可以自动的改变堆的大小来适应你所需要的内存,并且适时的调用垃圾回收操作来释放已经不需要的内存,从而降低开发人员在代码内存管理方面的门槛。
但并不意味着可以肆无忌惮的开辟托管堆内存,因为目前Unity存在一个很严重的问题:Mono的堆内存一旦分配,就不会返还给系统,这意味着Mono的堆内存只升不降。
- 不要在Update、FixUpdate等较高调用频率的函数中开辟堆内存,会对项目内存和性能造成非常大的危害。
- Log输出,不要在项目中存在大量Log输出的情况,以避免不必要的内存分配
- 使用对象池,可以避免大量对象的创建。
- 使用StringBuilder替代string,String为不可变字符串,对于执行大量字符串操作的过程,会分配大量空间,显著降低性能,而StringBuilder是一个可变字符串,可以通过追加、移除、替换或插入字符来修改。
- 减少装箱操作,装箱和拆箱过程需要进行大量的计算,装箱时需要创建一个全新的对象,需要进行内存的分配。
二、GPU渲染管线
渲染管线是将三维场景模型转换到屏幕像素空间输出的过程,图形渲染管线主要包括两个功能:
- 一是将物体3D坐标转换为屏幕空间2D坐标
- 二是为屏幕每个像素点进行着色
- 应用阶段:
由CPU主要负责的阶段,且完全由开发人员掌控,CPU将决定递给GPU什么样的数据,有时候还会对这些数据进行处理,并告诉GPU这些数据的渲染状态,这一阶段最重要的输出是渲染所需的几何信息,即渲染元。- 准备好场景数据。如摄像机位置,视锥体,场景中包含的模型
- 粗粒度剔除。为了提高渲染性能
- 设置好每个模型的渲染状态
- 几何阶段:
负责大部分多边形操作和顶点操作,将三维空间的数据转换为二维空间的数据。- 顶点着色器:计算顶点光照
- 曲面细分着色器:需要根据现有的顶点来生产更多的顶点
- 几何着色器:通过现有图元来做一些几何方面的操作,生成更多的顶点和图元
- 顶点裁剪:裁剪掉屏幕外的顶点
- 屏幕映射:把顶点从3D坐标空间转换到2D坐标空间
- 光栅化阶段:
决定每个渲染图元中哪些像素应该被绘制在屏幕上,它需要对上一阶段得到的逐顶点数据进行插值 - 像素处理阶段:
给每一个像素正确配色,最后绘制出整幅图像
三、u3d提供了一个用于保存读取数据的类是什么?
PlayerPrefs类是一个本地持久化保存与读取数据的类,支持3种数据类型的保存和读取,整型、浮点型、字符串型。
- 整型 SetInt() GetInt()
- 浮点型 SetFloat() GetFloat()
- 字符串 SetString() GetString()
四、Coroutine的原理?
协程分为两部分,协程与协程调度器:协程仅仅是一个能够中间暂停返回的函数,而协程调度是在MonoBehaviour的生命周期中实现的。准确的说,Unity只实现了协程调度部分,而协程本身其实就是用了C#原生的迭代器方法。
-
协程本体:C#的迭代器函数
C#的迭代器方法其实就是一个协程,你可以使用yield来暂停,使用MoveNext()方法来继续执行,当一个方法的返回值协程了IEnumerator类型,他就会自动被解析成迭代器方法,你调用此方法的时候不会真的运行,而是会返回一个迭代器,需要用MoveNext()来真正的运行 -
协程调度:MonoBehaviour生命周期中实现
在MonoBehaviour生命周期的Update和LateUpdate之间,会检查这个MonoBehaviour下挂载的所有协程,并唤醒其中满足唤醒条件的协程
五、Image和RawImage的区别?
- RawImage不支持交互,可用于显示任何图片。一般用在背景和图标上。
- Image只能使用Sprite属性的图片,通常用于用户界面元素。适用于交互性强的元素。
- Image比RawImage更消耗性能。
六、Material和Physic Material区别?
- Material为普通的贴图材质
- Physic Material为物理材质,用于处理物理效果,比如滑动摩檫力,静态摩檫力,反弹等属性
七、如何检测物体是否被其他对象遮挡?
射线检测 EventSystem.IsPointerOverGameObject
八、获取、增加、删除组件的命令分别是什么?
- 获取组件 GetComponent()
- 增加组件:AddComponent()
- 删除组件:Destroy()
九、什么是LightMap?
就是指在三维软件里实时打光,然后渲染把场景各表面的光照输出到贴图上,最后又通过引擎贴到场景上,这样就使物体有了光照的感觉。
以下是关于Lightmap的一些关键信息:
- 用途: Lightmap用于渲染静态阴影,适用于不需要频繁变化的场景元素。
- 生成过程: Lightmap的生成通常是通过烘焙(baking)的方式进行的。在烘焙过程中,光照数据被预先计算并存储在纹理中。
- 性能优势: 使用Lightmap可以在几乎没有性能损耗的情况下提供高质量的阴影效果。
- 纹理尺寸: Lightmap通常存储在较低分辨率的纹理上,例如64x64或32x32,以节省内存和加速渲染。
十、MeshCollider和其他Collider的不同?
- MeshCollider是基于顶点数据,片面组成,消耗性能
- BoxCollider基于算法的,性能好
每一次跌倒都是一次成长 每一次努力都是一次进步 |
如果您喜欢本博客,请点赞和分享给更多的朋友,让更多人受益。同时,您也可以关注我的博客,以便及时获取最新的更新和文章。
在未来的写作中,我将继续努力,分享更多有趣、实用的内容。再次感谢大家的支持和鼓励,期待与您在下一篇博客再见!