Unity3D最新面试高频问答题目
一、Unity3D脚本执行顺序
最先执行的方法依次为:
- Awake:激活时的初始化代码。
- Start
- Update:包含
FixUpdate和LateUpdate。 - OnGUI:渲染模块。
- 卸载模块(TearDown):主要有
OnDisable与OnDestroy两个方法。
二、高频问答问题
1. 什么是渲染管道?
渲染管道是指在显示器上为了显示出图像而经过的一系列必要操作。在渲染管道中,很多步骤都要将几何物体从一个坐标系中变换到另一个坐标系中去。其主要步骤如下: 本地坐标 -> 视图坐标 -> 背面裁剪 -> 光照 -> 裁剪 -> 投影 -> 视图变换 -> 光栅化。
2. 如何优化内存?
有多种内存优化方式,具体如下:
- 压缩自带类库。
- 隐藏暂不使用但后续需要的物体:将暂时不用的以后还需要使用的物体隐藏起来,而非直接使用
Destroy销毁。 - 释放 AssetBundle 占用的资源:
AssetBundle是资源包。 - 降低模型复杂度:降低模型的面数、骨骼数量以及贴图的大小。
- 使用优化技术:使用光照贴图、多层次细节(LOD)、着色器(Shader)和预设(Prefab)。
3. 动态加载资源的方式及区别
加载方式
- 通过 Resources 模块:调用其
load函数,可直接加载并返回某个类型的Object。前提是要把资源放在名为Resource的文件夹下,Unity 不管有无场景引用,都会将其全部打入到安装包中,例如Resources.Load()。 - 通过 bundle 的形式:将资源打成
asset bundle放在服务器或本地磁盘,然后使用WWW模块下载,再从这个bundle中加载某个object。 - 通过 AssetDatabase.loadasset:这种方式只在编辑器范围内有效,游戏运行时没有该函数,通常在开发中调试使用。
区别
Resources 方式需把所有资源全部打入安装包,不利于游戏的分包发布(微端)和版本升级(patch),所以 Unity 推荐使用 bundle 方式,将资源打成几个小的 bundle,按需加载。但在开发过程中,不可能每次更新资源都打一次 bundle,因此在编辑器环境下可使用 AssetDatabase 模拟,这通常需要封装一个 dynamic resource 的加载器模块,在不同环境下做不同实现。
动态资源的存放
若需存放一些自己的文件在磁盘上,例如将几个 bundle 放在初始安装中,Unity 有 streaming asset 的概念,用于提供存储接口的访问。需在编辑器建立一个名为 StreamingAssets 的文件夹,把需要放在客户磁盘上的动态文件放在该文件夹下,安装后,这些文件会放在用户磁盘的指定位置,可通过 Application.streamingAssetsPath 获取该位置。
4. 什么是协同程序?
协同程序是在主线程运行时同时开启另一段逻辑处理,以协助当前程序的执行。但需要注意的是,开启协程并非开启一个线程,它可用来控制运动、序列以及对象的行为。
5. 你用过哪些插件?
- 界面制作:推荐 NGUI。
- 2D 游戏制作:推荐 2D Toolkit。
- 可视化编程:推荐 PlayMaker。
- 插值插件:推荐 iTween、HOTween。
- 路径搜寻:推荐 Simple Path。
- 美术及动画制作:推荐 RageSpline、Smooth Moves。
- 画面增强:推荐 Bitmap2Material、Strumpy Shader Editor。
- 摄像机管理:推荐 Security Camera。
- 资源包:推荐 Nature Pack。
- 造路插件:推荐 EasyRoads3D。
6. 使用 Unity3D 实现 2D 游戏的方式
- 使用本身的 GUI。
- 调整摄像机投影模式:把摄像机的
Projection(投影)值调为Orthographic(正交投影),不考虑z轴。 - 使用 2D 插件:如 2DToolKit。
7. Unity3D 中的碰撞器和触发器的区别
触发器是碰撞器身上的一个属性,碰撞器是触发器的载体。
- 碰撞器:
IsTrigger为false时,有碰撞效果,可调用OnCollisionEnter、OnCollisionStay、OnCollisionExit函数。 - 触发器:
IsTrigger为true时,没有碰撞效果,可调用OnTriggerEnter、OnTriggerStay、OnTriggerExit函数。 - 若不想让碰撞检测影响物体移动但又想检测到碰撞,可使用触发器。
- 触发器可用于检测一个物件是否经过空间中的某个区域。
8. 物体发生碰撞的必要条件
两个物体都必须带有碰撞器(Collider),其中一个物体还必须带有刚体(Rigidbody)。
8.1 CharacterController 和 Rigidbody 的区别
- CharacterController:自带胶囊碰撞器,包含有刚体的属性,可说是受限的
Rigidbody,具有一定的物理效果但并非完全真实。 - Rigidbody:使物体带有刚体的特征,具有完全真实物理的特性。
9. 在物体发生碰撞的整个过程中的阶段及对应函数
物体碰撞过程分为三个阶段,对应函数如下:
- OnCollisionEnter:进入碰撞。
- OnCollisionStay:逗留碰撞。
- OnCollisionExit:退出碰撞。
10. Unity3D 的物理引擎中施加力的方式
在 rigidbody 系列函数中有 AddForce 和 AddForceAtPosition 两种施加力的方式。
11. 什么叫做链条关节?
Hinge Joint 可模拟两个物体间用一根链条连接在一起的情况,能保持两个物体在一个固定距离内不相互移动且不产生作用力,但达到固定距离后会产生拉力。
12. 物体自身旋转使用的函数
可使用 Transform.Rotate() 函数。
13. 物体围绕某点旋转使用的函数
使用 Transform.RotateAround() 函数。
14. Unity3D 保存和读取整形数据的函数
使用 PlayerPrefs.SetInt() 保存整形数据,使用 PlayerPrefs.GetInt() 读取整形数据。
15. Unity3D 提供的光源类型
Unity3D 提供四种光源类型,分别是平行光(Directional Light)、点光源(Point Light)、聚光灯(Spot Light)和区域光源(Area Light)。
16. Unity3D 脚本的生命周期中系统自带的重要方法
Awake -> Start -> Update -> FixedUpdate -> LateUpdate -> OnGUI -> Reset -> OnDisable -> OnDestroy
17. 物理更新一般放在哪个系统函数里?
物理更新一般放在 FixedUpdate 函数中,该函数每固定帧绘制时执行一次。与 Update 不同,FixedUpdate 与渲染帧执行相关,若渲染效率低下,其调用次数会下降。FixedUpdate 适用于物理引擎的计算,而 Update 更适合做控制。
18. 移动摄像机的动作放在哪个系统函数中,为什么?
移动摄像机的动作一般放在 LateUpdate 函数中。该函数在每帧执行完毕后调用,在所有 Update 结束后才执行,适合用于命令脚本的执行。例如摄像机跟随,若不在所有 Update 操作完成后跟进摄像机,可能会出现摄像机已推进,但视角里还未有角色的空帧情况。
19. 当游戏中需要频繁创建一个物体时,如何节省内存?
可使用预制物体对象 Prefab,然后复制创建。
20. 在场景中放置多个 Camera 并同时处于活动状态会发生什么?
游戏界面可以看到多个摄像机画面的混合。
21. 请描述 Prefab 的作用,并描述如何在移动设备的环境下恰当的使用它?
Prefab 在实例化时使用,主要用于经常会用到的物体,方便修改属性。销毁 UnityEngine.Object 及其子类可使用 Destroy() 方法。
22. 请简述 Unity3D 下如何安全的在不同工程间迁移 asset 数据,请列举出三种方法?
- 迁移目录:把
assets目录和Library目录一起迁移。 - 导出包:将资源导出为包进行迁移。
- 使用 Unity 自带功能:利用 Unity 带的
assets Server功能。
23. 请描述游戏动画有哪几种,以及其原理?
主要有关节动画、骨骼动画、单一网格模型动画(关键帧动画)。
- 关节动画:把角色分成若干独立部分,每个部分对应一个网格模型,各部分的动画连接成一个整体的动画,角色较为灵活,如在
Quake2中使用这种动画。 - 骨骼动画:广泛应用的动画方式,集成了关节动画和关键帧动画的优点。骨骼按角色特点组成一定的层次结构,有关节相连,可做相对运动,皮肤作为单一网格蒙在骨骼之外,决定角色的外观。
- 单一网格模型动画:由一个完整的网格模型构成,在动画序列的关键帧里记录各个顶点的原位置及其改变量,然后通过插值运算实现动画效果,角色动画较真实。
24. 请描述为什么 Unity3D 中会发生在组件上出现数据丢失的情况
一般是组件上绑定的物体对象被删除了。
25. alpha blend 工作原理
Alpha Blend 用于实现透明效果,不过只能针对某块区域进行 alpha 操作,透明度可设置。
26. 写出光照计算中的 diffuse 的计算公式
计算公式为:Idiffuse = Dintensity * Dcolor * N.L,其中 Dintensity 表示漫反射强度,Dcolor 表示漫反射光颜色,N 为该点的法向量,L 为光源向量。若 N 与 L 点乘结果小于等于 0,则漫反射为 0。
27. Lod 是什么,优缺点是什么?
LOD(Level of detail)即多层次细节,是常用的游戏优化技术。它根据模型的位置和重要程度决定物体渲染的资源分配,降低非重要物体的面数和细节度,从而提高渲染运算效率。
28. 两种阴影判断的方法、工作原理
方法一
阴影由本影与半影两部分组成:
- 本影:景物表面上那些没有被光源直接照射的区域(全黑且轮廓分明的区域)。
- 半影:景物表面上那些被某些特定光源直接照射但并非被所有特定光源直接照射的区域(半明半暗区域)。
求阴影区域需做两次消隐过程:一次对每个光源进行消隐,求出对于光源而言不可见的区域
L;一次对视点的位置进行消隐,求出对于视点而言可见的面S,阴影区域为L ∩ S。
方法二
阴影分为自身阴影和投射阴影:
- 自身阴影:因物体自身的遮挡而使光线照射不到它上面的某些可见面。工作原理是利用背面剔除的方法,假设视点在点光源的位置。
- 投射阴影:因不透明物体遮挡光线使得场景中位于该物体后面的物体或区域受不到光照照射而形成的阴影。工作原理是从光源处向物体的所有可见面投射光线,将这些面投影到场景中得到投影面,再将这些投影面与场景中的其他平面求交得出阴影多边形,保存这些阴影多边形信息,然后按视点位置对场景进行相应处理得到所要求的视图。但该方法在动态光源下无效。
29. Vertex Shader 是什么,怎么计算?
Vertex Shader 即顶点着色器,是一段在 GPU 上执行的程序,用于取代固定管线中的变换和光照。它主要操作顶点,对输入顶点完成从局部空间到齐次空间(homogeneous space)的变换过程,齐次空间是投影空间的下一个空间,其间包含世界变换、视图变换、投影变换及光照等过程。
30. MipMap 是什么,作用?
MipMapping 是三维计算机图形的贴图渲染中常用的技术。为加快渲染进度和减少图像锯齿,贴图被处理成由一系列预先计算和优化过的图片组成的文件,这样的贴图称为 MipMap。
31. 机试:二选一
- 用代码实现第三角色控制器。
- 实现吊机吊物体的功能,此功能需要节点挂接和坐标系转换。
32. 反向旋转动画的方法是什么?
将动画的速度调为 -1,碰撞时,被碰撞物体与碰撞物体需有 collider 组件,碰撞物体有刚体组件,或角色碰撞需包含角色组件,也可改变 animation.speed。
33. 碰撞检测需要物体具备什么属性?
能检测碰撞发生的方式有两种,一种是利用碰撞器,另一种是利用触发器。例如 Physics.OverlapSphere 可用于相交球检测碰撞,碰撞检测需要包围盒。
34. 获取、增加、删除组件的命令分别是什么?
获取组件使用 GetComponent,增加组件使用 AddComponent,删除组件使用 Destroy。
35. Animation.CrossFade 命令作用是?
该命令的作用是使动画淡入为其他动画,答案选 C。
36. Application.loadLevel 命令为?
该命令用于加载关卡,答案选 A。
37. 调试记录到控制台的命令是什么?
使用 Debug.Log() 命令。
39. 编辑器类存放路径是什么?
存放在工程目录下的 Assets/Editor 文件夹下。
40. 使用原生 GUI 创建一个可以拖动的窗口命令是什么?
使用 GUI.DragWindow() 命令。
41. localPosition 与 Position 的使用区别?
localPosition 是自身位置,相对于父级的变换的位置;Position 是在世界坐标 transform 的位置。
意义连线
Mathf.Round:四舍五入Mathf.Clamp:限制Mathf.Lerp:插值
42. 写一个计时器工具,从整点开始计时,格式为:00:00:00
(此处未给出具体代码实现,可根据需求进一步补充)
43. 写出 Animation 的五个方法
AddClip(添加剪辑)、Blend(混合)、Play(播放)、Stop(停止)、Sample(采样)。
44. 怎么拿到一个对象上脚本的方法
使用 GameObject.GetComponent<>() 方法。
上机题:用鼠标实现在场景中拖动物体,用鼠标滚轮实现缩放(用一个 Cube 即可)。
(此处未给出具体代码实现,可根据需求进一步补充)
45. 请简述向量的点乘,向量的叉乘以及向量归一化的几何意义?
- 点乘:计算两个向量之间的夹角,以及在某一方向上的投影。
- 叉乘:创建垂直于平面、三角形或者多边形的向量。
46. Unity3D 是否支持写成多线程?如果支持的话要注意什么?
Unity3D 支持多线程。若同时要处理很多事情或者与 Unity 的对象互动较少,可以使用 thread,否则建议使用协程。在 C# 中,可使用 lock 关键字确保只有一个线程可以在特定时间内访问特定的对象。
47. Unity3D 中的协程(Coroutine)和 C# 线程之间的区别是什么?
Unity3D 本身没有严格意义上的多线程概念,但提供了 StartCoroutine(协同程序)和 LoadLevelAsync(异步加载关卡)等后台加载场景的方法。StartCoroutine 之所以称为协同程序,是因为在其函数体里处理代码时,利用 yield 语句等待执行结果,期间不影响主程序的继续执行,可协同工作。而 LoadLevelAsync 允许在后台加载新资源和场景,利用协同可在前台用加载条或动画提示玩家游戏未卡死,同时后台协同处理加载事宜。
48. 请简述四元数的作用以及四元数相对于欧拉角的优点
四元数定义
四元数一般定义为 q = w + xi + yj + zk,其中 w、x、y、z 是实数,且 i * i = -1,j * j = -1,k * k = -1,也可表示为 q = [w, v]。
优点
- 四元数不会有欧拉角存在的万向节死锁(
gimbal lock)问题。 - 四元数由 4 个数组成,而旋转矩阵需要 9 个数。
- 两个四元数之间更容易插值。
- 四元数和矩阵在多次运算后会积攒误差,需分别进行规范化(
normalize)和正交化(orthogonalize),对四元数规范化更容易。 - 与旋转矩阵类似,两个四元组相乘可表示两次旋转。
49. 请简述 OnBecameVisible 及 OnBecameInvisible 的发生时机,以及他们执行的意义?
当渲染器(renderer)在任何相机上都不可见时,调用 OnBecameInvisible;当渲染器在任何相机上可见时,调用 OnBecameVisible。
50. 动画层(Animation Layers)的作用是什么?
动画层作为一个具有层级动画编辑概念的工具,可用于制作和处理任何类型的动画。
52. 请说出 4 种面向对象的设计原则,并分别简述它们的含义。
- 单一职责原则(The Single Responsiblity Principle,简称 SRP):一个类最好只做一件事,只有一个引起它变化的原因。
- 开放-封闭原则(The Open-Close Principle,简称 OCP):对于扩展是开放的,对于更改是封闭的。
- Liskov 替换原则(The Liskov Substitution Principle,简称 LSP):子类必须能够替换其基类。
- 依赖倒置原则(The Dependency Inversion Pricinple,简称 DIP):依赖于抽象。
- 接口隔离原则(The Interface Segregation Principle,简称 ISP):使用多个小的专门的接口,而不要使用一个大的总接口。
53. Material 和 Physic Material 区别?
PhysicMaterial 是物理材质,用于描述物体碰撞时的处理方式(如摩擦、弹性);Material 是材质类,为了获得一个对象使用的材质,可使用 Renderer.material 属性。
54. 法线贴图 、CG 动画
- 法线贴图:在原物体的凹凸表面的每个点上均作法线,通过 RGB 颜色通道来标记法线的方向,可理解为与原凹凸表面平行的另一个不同表面,但实际上它是一个光滑的平面。
- CG 动画:原为
Computer Graphics的英文缩写。随着以计算机为主要工具进行视觉设计和生产的一系列相关产业的形成,国际上习惯将利用计算机技术进行视觉设计和生产的领域通称为CG,既包括技术也包括艺术,几乎囊括了当今电脑时代中所有的视觉艺术创作活动,如平面印刷品设计、网页设计、三维动画、影视特效、多媒体技术、以计算机辅助设计为主的建筑设计及工业造型设计等。
55、NGUI Button 怎样接受用户点击并调用函数,具体方法名称是什么
可直接监听事件,将脚本直接绑定在按钮上,当按钮点击时即可监听到,但这种方法不够灵活。
56、请描述游戏动画有哪几种,以及其原理。
主要有关节动画、单一网格模型动画(关键帧动画)、骨骼动画。
- 关节动画:把角色分成若干独立部分,每个部分对应一个网格模型,各部分的动画连接成一个整体的动画,角色较为灵活,如在
Quake2中使用这种动画。 - 单一网格模型动画:由一个完整的网格模型构成,在动画序列的关键帧里记录各个顶点的原位置及其改变量,然后通过插值运算实现动画效果,角色动画较真实。
- 骨骼动画:广泛应用的动画方式,集成了关节动画和关键帧动画的优点。骨骼按角色特点组成一定的层次结构,由关节相连,可做相对运动,皮肤作为单一网格蒙在骨骼之外,决定角色的外观,皮肤网格的每个顶点都会受到骨骼的影响,从而实现完美的动画。
57、下面哪种做法可以打开 Unity 的 Asset Store
通过 Windows -> Asset Store 操作可打开。
58、Mecanim 系统中,Body Mask 的作用是?
指定身体的某一部分是否参与渲染。
59、以下哪种操作步骤可以打开 Unity 编辑器的 Lightmapping 视图?
通过 Windows --> Lightmapping 操作可打开。
60、关于光照贴图
使用光照贴图比使用实时光源渲染要快,可降低游戏内存消耗,多个物体可以使用同一张光照贴图。
61、关于 Vector3 的 API,以下说法正确的是?
Vector3.forward 与 Vector3(0, 0, 1) 意思相同。
62、 以下哪个函数在游戏进入新场景后会被马上调用?
MonoBehaviour.OnLevelWasLoaded 函数会在游戏进入新场景后马上调用。
63、 什么是导航网格( NavMesh)?
导航网格是一种用于实现自动寻路的网格。
64、什么是局部坐标,什么是世界坐标?
世界坐标以世界坐标轴的 XYZ 为标准,不会改变;局部坐标即自身的坐标,会随着物体的旋转而变化。
65、itween 插件的作用是什么,itween 作用于世界坐标还是局部坐标,请列举出 3 个其常用方法?
iTween 是一个动画库,目的是用最小的投入实现最大的产出,可轻松实现各种动画,如晃动、旋转、移动、褪色、上色、控制音频等。它可作用于世界坐标或局部坐标,常用方法如下:
- MoveTo:物体移动。
- ColorTo:随着时间改变对象的颜色组。
- LookTo:随时间旋转物体让其脸部朝向所提供的
Vector3或Transform位置。
66、请简述 NGUI 中 Panel 和 Anchor 的作用
- Anchor:包含
UIAnchor脚本,其功能是把对象锚定在屏幕的边缘(左上、左中、左下、上、中、下、右上、右中、右下),或缩放物体使其匹配屏幕的尺寸。 - Panel:对象有
UIPanel脚本,是一个容器,将包含所有 UI 小部件,并负责将所包含的部件组合优化,以减少绘制命令的调用。
67、Unity 摄像机有几种工作方式,分别是什么?
(原文未提及,可进一步补充相关内容)
68、LayerMask.NameToLayer() 这个方法有什么作用?
LayerMask 的使用是按位操作的,LayerMask.NameToLayer("Players") 返回该层的编号。
69、请描述 MeshRender 中 material 和 shader 的区别?
Shader(着色器)是一小段程序,负责将输入的 Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出。绘图单元依据该输出将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的 Shader,以及对 Shader 的特定参数设置,打包存储在一起,得到的就是 Material(材质)。Shader 大体上可分为表面着色器(Surface Shader)和片段着色器(Fragment Shader)两类。
70、什么是矢量图
计算机中显示的图形一般分为矢量图和位图。矢量图使用直线和曲线来描述图形,其元素包括点、线、矩形、多边形、圆和弧线等,通过数学公式计算获得。例如一幅花的矢量图形由线段形成外框轮廓,由外框颜色以及外框所封闭的颜色决定花的显示颜色。由于矢量图形可通过公式计算,所以文件体积一般较小,且无论放大、缩小或旋转等都不会失真,但难以表现色彩层次丰富的逼真图像效果。
71、Unity 连接数据库
需要获取 Mono.Data.Sqlite.dll 文件与 System.Data.dll 文件。
72、四元组是什么?
四元数是把 4 个实数组合起来的东西,其中一个是实部,其余 3 个是虚部。