途趣科技Unity面试题

2021-06-02 09:02发布

数组和链表对比

通过一个变量存放多个相同类型的值,在存取数组中的值时直接根据数组中的下标即可完成。

在一个数组中存放的值都是同一数据类型的,并且可以通过循环以及数据操作的方法对数组的值进行运算或操作。

优点:可以利用空间局部性原理,借助 CPU cache进行预读,所以访问效率更高

缺点:大小固定,一经声明就要占用整块连续的内存空间。如果声明的数组过大,系统可能没有足够的连续内存空间用于分配,

就会导致“内存不足”。而如果声明的数组过小,当不够用时,又需要重新申请一块更大的内存,然后进行数据拷贝,非常费时。


链表

链表是数据结构之一,其中的数据呈线性排列。在链表中,数据的添加和删除都较为方便,就是访问比较耗费时间。

它是一种非固定长度的数据结构,是一种动态存储技术,

它能够根据数据的结构特点和数量使用内存,尤其适用于数据个数可变的数据存储。

使用链表存储数据的原理与数组不同,它不需要事先说明要存储的数据数量,系统也不会提前为它准备大的存储空间,

而是当需要存储数据时,通过动态内存分配函数malloc()或calloc()向系统获取一定数量的内存,

用于数据存储。需要多少,就申请多少,系统就分配多少。


插入删除:链表性能好

查询修改:数组性能好


内存优化

对象池:

对象池用于减少内存开销,其原理就是把可能用到到的对象,先存在一个地方(池),要用的时候就调出来,不用就放回去。

而不是要用的时候创建,不用的时候销毁。

图集打包:

lod:近的高模,远的地模

批处理:

静态批处理

为了更好地使用静态批处理,你需要明确指出哪些物体是静止的,并且在游戏中永远不会移动、旋转和缩放。想完成这一步,

你只需要在检测器(Inspector)中将Static复选框打勾即可。只要这些物体不移动,并且拥有相同的材质。因此,静态批处理比动态批处理更加有效,

你应该尽量低使用它,因为它需要更少的CPU开销。

使用静态批处理操作需要额外的内存开销来储存合并后的几何数据。在静态批处理之前,如果一些物体共用了同样的几何数据,

那么引擎会在编辑以及运行状态对每个物体创建一个几何数据的备份。因为有时候,将不得不牺牲一点渲染性能来

防止一些物体的静态批处理,从而保持较少的内存开销。比如,将浓密森里中树设为Static,会导致严重的内存开销。这就是空间和时间上的相爱相杀。

最后,如果场景自带静态物体,会合并批次;如果静态物体是场景加载后再读取预制体动态加载进去的,就不会自动合并批次,

需要你加载完后调一下手动合并批次的接口,StaticBatchingUtility.Combine 合并。

动态批处理:

如果动态物体共用着相同的材质,那么Unity会自动对这些物体进行批处理,动态批处理操作是自动完成的,并不需要你进行额外的操作。

Dynamic Batching启用时,Unity将尝试自动批量移动物体到一个Draw Call中。要使物体可以被动态批处理,它们应该共享相同的材质,

但是还有一些其他约束条件:

批处理动态物体需要在每个顶点上进行一定的开销,所以动态批处理仅支持小于900顶点的网格物体;如果你的着色器使用顶点位置,

法线和UV值三种属性,那么你只能批处理300顶点以下的物体;如果你的着色器需要使用顶点位置,法线,UV0,UV1和切向量,

那你只能批处理180顶点以下的物体。

尽量不要使用缩放尺度(scale)。统一缩放尺度的物体不会与非统一缩放尺度的物体进行批处理


A*寻路

1. 从起点 A 开始, 把它作为待处理的方格存入一个"开启列表", 开启列表就是一个等待检查方格的列表.


2. 寻找起点 A 周围可以到达的方格, 将它们放入"开启列表", 并设置它们的"父方格"为 A.


3. 从"开启列表"中删除起点 A, 并将起点 A 加入"关闭列表", "关闭列表"中存放的都是不需要再次检查的方格


4. 把它从 "开启列表" 中删除, 并放到 "关闭列表" 中.


5. 检查它所有相邻并且可以到达 (障碍物和 "关闭列表" 的方格都不考虑) 的方格. 如果这些方格


还不在 "开启列表" 里的话, 将它们加入 "开启列表", 计算这些方格的 G, H 和 F 值各是多少, 并设置它们的 "父方格" 为 C.


6. 如果某个相邻方格 D 已经在 "开启列表" 里了, 检查如果用新的路径 (就是经过 C 的路径) 到达它的话, G 值是否会更低一些, 如果新的 G 值更低, 那就把它的 "父方格" 改为目前选中的方格 C, 然后重新计算它的 F 值和 G 值 (H 值不需要重新计算, 因为对于每个方块, H 值是不变的). 如果新的 G 值比较高, 就说明经过 C 再到达 D 不是一个明智的选择, 因为它需要更远的路, 这时我们什么也不做.


人物血条制作

公告栏:3D血条 血条上  transform.localRotation = Quaternion.LookRotation(cameraMain.forward,cameraMain.up);