Unity技术面试
以下是在最新Unity技术面试中被问到的问题,作为Unity学习者,你对这些问题了解多少呢?认真阅读本文,或许会对你找工作有所帮助。
1. NGUI在不同屏幕分辨率下如何适配?
NGUI本身按照高度进行适配,它依据目标设备的高度(targetHeight)与设置好的高度(manualHeight)的比值来实现适配。若宽高比一致,就能实现完美适配;但如果宽高比不一致,可能会出现左右两边有黑边(设备宽高比更大)或左右两边被裁减(设备宽高比更小)的情况。为解决此问题,可以通过代码手动修改Camera.orthographicSize来调整与目标屏幕大小的比率。
对于UI元素的定位,可以使用UIAnchor。UIRoot的ScalingStyle选项包含PixelPerfect、FixedSize、FixedSizeOnMobile几个值,使用FixedSizeOnMobile可保证UI元素大小不变。
2. NGUI如何减少DrawCall?
应尽量将图素合并到一张贴图中,使用同一个材质创建一个atlas。并且,相同atlas的UI对象,其深度要相邻或相同,否则会产生额外的DrawCall。
3. 内存优化
- 资源池的使用:使用资源池来缓存需要反复使用的
GameObject,其数量可根据需求动态增长和缩减。 - MipMap的应用:对图片使用
MipMap。 - 资源的销毁:
Object销毁要调用Destroy,AssetBundle销毁要调用Unload(false),并且在适当时候调用Resources.UnloadUnusedAssets()方法释放游戏资源。 - 静态变量的使用:谨慎使用静态变量来引用
GameObject,因为这很可能会导致资源释放不干净。 - 场景资源的释放:切换场景时,在
OnDestroy方法中对场景资源进行释放。 - 数据类型的选择:尽量使用
struct,而非class。 - 字符串拼接:当字符串拼接操作较多时,使用
StringBuilder。
4. 性能优化
- 材质的使用:尽量使用相同的材质,方便进行
batch操作,并且在引用时使用sharedMaterial。 - 光照的处理:尽量不使用实时光照,使用光照贴图,并修改
Quality的PixelLightCount来降低光照计算开销。 - Shader的选择:尽量少用
AlphaTest的Shader,最好使用Mobile目录下的Shader。 - 静态物体的设置:不会动的物体勾选
static选项,若物体身上有碰撞体,最好不要改变它们的位置。 - 物理计算频率:降低物理计算的更新频率,修改
Time的Fixed Timestep。 - 模型优化:降低模型的面数,多用纹理来表现细节,可以考虑使用
LOD。
5. 减小包大小
- 资源压缩:对图片、
Mesh、动画分别启用压缩,对Mesh的Normals、Tangents选项勾选None,因为它们只有在使用实时照明、法线贴图时才会用到。 - 网格优化:优化网格。
- 类库的使用:少使用
System的类库,例如System.Xml,可以使用更加小巧的第三方插件。 - 构建方式:使用
Release Build而不是Debugging Build。 - 代码剥离:启用
Stripping Level。 - API兼容性设置:将
Api Compatibility Level设为.NET 2.0 Subset。 - 打包日志查看:在
Console面板点击Open Editor Log,查看打包时的日志。
6. NGUI如何屏蔽3D场景的事件响应?
可以使用UICamera.Raycast(mousePosition, out uiHitInfo)这个静态方法来检测是否点击到某个UI元素,在3D场景的事件响应时进行这一层拦截。
7. 向量点乘叉乘的几何意义
点乘可以得到一个数值,一般用于确定两向量的夹角;叉乘可以得到与两向量垂直的一个向量,通常用于计算法线或者确定平面。
8. 介绍一下图形渲染管线
这是CG教程里的编程渲染管线示意图,横线上面是在CPU中处理,下面是在GPU计算。顶点着色阶段进行坐标变换,具体顺序为:模型空间 -> 世界空间 -> 视角空间 -> 投影空间;图元装配段进行消隐处理。网上有很多相关教程,大家可以自行查阅。
9. Dictionary<K,V>与HashTable的区别
Dictionary<K,V>是泛型,K和V的类型预先已经确定;而HashTable内的K和V类型不定。如果顺序地调用Add方法,Dictionary<K,V>中的元素是有序的,而HashTable内部是无序的。当K是值类型时,Dictionary<K,V>的速度要比HashTable快,因为值类型在HashTable内会进行装/拆箱操作。
10. LinkedList与List的区别,插入删除、查询谁快?
LinkedList实际是一个双向链表,List是对数组的一层封装,数组的长度会动态增长,重新分配数组会有一定的性能开销。在插入和删除操作上,LinkedList通常更快;而在查询操作上,List的性能更好。
11. Dynamic Batch的条件
- 顶点数小于300,如果
shader使用了Vertex Position、Normal、UV0、UV1和Tangent,那么顶点数限制为180。 - 使用相同的材质。
- 使用相同的
transform scale。 - 如果
shader使用了多个pass,则不能进行batch。 - 接受实时阴影的模型,不能进行
batch。
12. 使用了什么插件
- PureMVC
- LitJson
- C# Lite
- A* Pathfinding Project
- NGUI
- RVO
- Thrift