Unity3D常见高频面试题整理(一)

整理了一些Unity3d高频面试题目,希望可以帮助到大家。

限于个人水平有限,只附上一些参考答案,如有错误还请指正。

一.什么是渲染管道?

是指在显示器上为了显示出图像而经过的一系列必要操作。

渲染管道中的很多步骤,都要将几何物体从一个坐标系中变换到另一个坐标系中去。

主要步骤有:

本地坐标->视图坐标->背面裁剪->光照->裁剪->投影->视图变换->光栅化。

二.如何优化内存?

有很多种方式,例如:
① 压缩自带类库;
② 将暂时不用的以后还需要使用的物体隐藏起来而不是直接Destroy掉;
③ 释放AssetBundle占用的资源;
④ 降低模型的片面数,降低模型的骨骼数量,降低贴图的大小;
⑤ 使用光照贴图,使用多层次细节(LOD),使用着色器(Shader),使用预设(Prefab)。

三、动态加载资源的方式?

(有时候也有区别,具体请自行搜索)
① Resources.Load();
② AssetBundle

四、什么是协同程序?

在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,协程很像多线程,但是不是多线程,Unity的协程实在每帧结束之后去检测yield的条件是否满足。

五、Unity3D中的碰撞器和触发器的区别?

碰撞器是触发器的载体,而触发器只是碰撞器身上的一个属性。当Is Trigger=false时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果,可以调用OnCollisionEnter/Stay/Exit函数;当Is Trigger=true时,碰撞器被物理引擎所忽略,没有碰撞效果,可以调用OnTriggerEnter/Stay/Exit函数。如果既要检测到物体的接触又不想让碰撞检测影响物体移动或要检测一个物件是否经过空间中的某个区域这时就可以用到触发器

六、物体发生碰撞的必要条件?

两个物体都必须带有碰撞器(Collider),其中一个物体还必须带有Rigidbody刚体,而且必须是运动的物体带有Rigidbody脚本才能检测到碰撞。

七、请简述ArrayList和List的主要区别?

####ArrayList存在不安全类型(ArrayList会把所有插入其中的数据都当做Object来处理) 装箱拆箱的操作(费时) List是接口,ArrayList是一个实现了该接口的类,可以被实例化

八、如何安全的在不同工程间安全地迁移asset数据?

三种方法:
① 将Assets目录和Library目录一起迁移
② 导出包,export Package
③ 用unity自带的assets Server功能

九、OnEnable、Awake、Start运行时的发生顺序?哪些可能在同一个对象周期中反复的发生

Awake –>OnEnable->Start,OnEnable在同一周期中可以反复地发生。

十、MeshRender中material和sharedmaterial的区别?

修改sharedMaterial将改变所有物体使用这个材质的外观,并且也改变储存在工程里的材质设置。不推荐修改由sharedMaterial返回的材质。如果你想修改渲染器的材质,使用material替代。

十一、Unity提供了几种光源,分别是什么?

① 平行光:Directional Light
② 点光源:Point Light
③ 聚光灯:Spot Light
④ 区域光源:Area Light

十二、简述一下对象池,你觉得在FPS里哪些东西适合使用对象池

对象池就存放需要被反复调用资源的一个空间,当一个对象回大量生成的时候如果每次都销毁创建会很费时间,通过对象池把暂时不用的对象放到一个池中(也就是一个集合),当下次要重新生成这个对象的时候先去池中查找一下是否有可用的对象,如果有的话就直接拿出来使用,不需要再创建,如果池中没有可用的对象,才需要重新创建,利用空间换时间来达到游戏的高速运行效果,在FPS游戏中要常被大量复制的对象包括子弹,敌人,粒子等

十三、CharacterController和Rigidbody的区别

Rigidbody具有完全真实物理的特性,Unity中物理系统最基本的一个组件,包含了常用的物理特性,而CharacterController可以说是受限的的Rigidbody,具有一定的物理效果但不是完全真实的,是Unity为了使开发者能方便的开发第一人称视角的游戏而封装的一个组件

十四、简述prefab的用处

在游戏运行时实例化,prefab相当于一个模板,对你已经有的素材、脚本、参数做一个默认的配置,以便于以后的修改,同时prefab打包的内容简化了导出的操作,便于团队的交流。

十五、请简述sealed关键字用在类声明时与函数声明时的作用

sealed修饰的类为密封类,类声明时可防止其他类继承此类,在方法中声明则可防止派生类重写此方法。

十六、请简述private,public,protected,internal的区别

public:对任何类和成员都公开,无限制访问
private:仅对该类公开
protected:对该类和其派生类公开
internal:只能在包含该类的程序集中访问该类

十七、使用Unity3d实现2d游戏,有几种方式?

① 使用本身的GUI,在Unity4.6以后出现的UGUI
② 把摄像机的Projection(投影)值调为Orthographic(正交投影),不考虑z轴;
③ 使用2d插件,如:2DToolKit,和NGUI

十八、在物体发生碰撞的整个过程中,有几个阶段,分别列出对应的函数

三个阶段
1.OnCollisionEnter
2.OnCollisionStay
3.OnCollisionExit

十九、Unity3d的物理引擎中,有几种施加力的方式,分别描述出来

rigidbody.AddForce/AddForceAtPosition,都在rigidbody系列函数中。大家可以自己去查看一下rigidbody的API

二十、什么叫做链条关节?

Hinge Joint,可以模拟两个物体间用一根链条连接在一起的情况,能保持两个物体在一个固定距离内部相互移动而不产生作用力,但是达到固定距离后就会产生拉力。

二十一、物体自身旋转使用的函数?

Transform.Rotate()

二十二、Unity3d提供了一个用于保存和读取数据的类(PlayerPrefs),请列出保存和读取整形数据的函数

PlayerPrefs.SetInt() PlayerPrefs.GetInt()

二十三、Unity3d脚本从唤醒到销毁有着一套比较完整的生命周期,请列出系统自带的几个重要的方法。

Awake——>OnEnable–>Start——>Update——>FixedUpdate——>LateUpdate——>OnGUI——>OnDisable——>OnDestroy

二十四、物理更新一般放在哪个系统函数里?

FixedUpdate,每固定帧绘制时执行一次,和Update不同的是FixedUpdate是渲染帧执行,如果你的渲染效率低下的时候FixedUpdate调用次数就会跟着下降。FixedUpdate比较适用于物理引擎的计算,因为是跟每帧渲染有关。Update就比较适合做控制。

二十五、在场景中放置多个Camera并同时处于活动状态会发生什么?

游戏界面可以看到很多摄像机的混合。

二十六、如何销毁一个UnityEngine.Object及其子类?

使用Destroy()方法;

二十七、请描述为什么Unity3d中会发生在组件上出现数据丢失的情况

一般是组件上绑定的物体对象被删除了

二十八、LOD是什么,优缺点是什么?

LOD(Level of detail)多层次细节,是最常用的游戏优化技术。它按照模型的位置和重要程度决定物体渲染的资源分配,降低非重要物体的面数和细节度,从而获得高效率的渲染运算。缺点是增加了内存。

二十九、MipMap是什么,作用?

MipMapping:在三维计算机图形的贴图渲染中有常用的技术,为加快渲染进度和减少图像锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为MipMap。

三十、请描述Interface与抽象类之间的不同

抽象类表示该类中可能已经有一些方法的具体定义,但接口就是公公只能定义各个方法的界面 ,不能具体的实现代码在成员方法中。类是子类用来继承的,当父类已经有实际功能的方法时该方法在子类中可以不必实现,直接引用父类的方法,子类也可以重写该父类的方法。实现接口的时候必须要实现接口中所有的方法,不能遗漏任何一个。

三十一、.Net与Mono的关系?

mono是.net的一个开源跨平台工具,就类似java虚拟机,java本身不是跨平台语言,但运行在虚拟机上就能够实现了跨平台。.net只能在windows下运行,mono可以实现跨平台跑,可以运行于linux,Unix,Mac OS等。

三十二、简述Unity3D支持的作为脚本的语言的名称

Unity的脚本语言基于Mono的.Net平台上运行,可以使用.NET库,这也为XML、数据库、正则表达式等问题提供了很好的解决方案。Unity里的脚本都会经过编译,他们的运行速度也很快。这三种语言实际上的功能和运行速度是一样的,区别主要体现在语言特性上。JavaScript、 C#、Boo

三十三、U3D中用于记录节点空间几何信息的组件名称,及其父类名称

Transform 父类是 Component

三十四、向量的点乘、叉乘以及归一化的意义?

1.点乘描述了两个向量的相似程度,结果越大两向量越相似,还可表示投影
2.叉乘得到的向量垂直于原来的两个向量
3.标准化向量:用在只关系方向,不关心大小的时候

三十五、为何大家都在移动设备上寻求U3D原生GUI的替代方案

不美观,OnGUI很耗费时间,效率不高,使用不方便

三十六、请简述如何在不同分辨率下保持UI的一致性

NGUI很好的解决了这一点,屏幕分辨率的自适应性,原理就是计算出屏幕的宽高比跟原来的预设的屏幕分辨率求出一个对比值,然后修改摄像机的size。UGUI通过锚点和中心点和分辨率也解决这个问题

三十七、什么是LightMap?

LightMap:就是指在三维软件里实现打好光,然后渲染把场景各表面的光照输出到贴图上,最后又通过引擎贴到场景上,这样就使物体有了光照的感觉。

使用光照贴图可以避免在游戏运行时进行实时的光照和阴影计算,提高游戏的运行性能

三十八、Unity和cocos2d的区别

Unity3D支持C#、javascript等,cocos2d-x 支持c++、Html5、Lua等。

cocos2d 开源 并且免费

Unity3D支持iOS、Android、Flash、Windows、Mac、Wii等平台的游戏开发,cocos2d-x支持iOS、Android、WP等。

三十九、C#和C++的区别?

简单的说:C# 与C++ 比较的话,最重要的特性就是C# 是一种完全面向对象的语言,而C++ 不是,另外C# 是基于IL 中间语言和.NET Framework CLR 的,在可移植性,可维护性和强壮性都比C++ 有很大的改进。C# 的设计目标是用来开发快速稳定可扩展的应用程序,当然也可以通过Interop 和Pinvoke 完成一些底层操作。

四十、结构体和类有何区别?

结构体是一种值类型,而类是引用类型。(值类型、引用类型是根据数据存储的角度来分的)就是值类型用于存储数据的值,引用类型用于存储对实际数据的引用。那么结构体就是当成值来使用的,类则通过引用来对实际数据操作

四十一、ref参数和out参数是什么?有什么区别?

ref和out参数的效果一样,都是通过关键字找到定义在主函数里面的变量的内存地址,并通过方法体内的语法改变它的大小。不同点就是输出参数必须对参数进行初始化。ref必须初始化,out 参数必须在函数里赋值。ref参数是引用,out参数为输出参数。

1、使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化。
2、使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。
3、out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。

ref和out区别:
① 使用ref的时候必须要先赋值,否则编译错误,而out并不需要。
② 对应的,在实现的方法中,out必须赋值,而ref不强求。

我觉得就作用来讲,ref 是用来修改传人参数的值的。OUT是用来返回多个返回值的。

四十二、C#的委托是什么?有何用处?

委托类似于一种安全的指针引用,在使用它时是当做类来看待而不是一个方法,相当于对一组方法的列表的引用。用处:使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。与C或C++中的函数指针不同,委托是面向对象,而且是类型安全的。

四十三、C#中的排序方式有哪些?

选择排序,冒泡排序,快速排序,插入排序,希尔排序,归并排序

四十四、射线检测碰撞物的原理是?

射线是3D世界中一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射 。

四十五、Unity中,照相机的Clipping Planes的作用是什么?调整Near、Fare两个值时,应该注意什么?

剪裁平面 。从相机到开始渲染和停止渲染之间的距离。

四十六、如何让已经存在的GameObject在LoadLevel后不被卸载掉?

void Awake()
{
DontDestroyOnLoad(transform.gameObject);
}

四十七、请简述GC(垃圾回收)产生的原因,并描述如何避免?

GC回收堆上的内存

避免:
① 减少new产生对象的次数
② 使用公用的对象(静态成员)
③ 将String换为StringBuilder
④ 使用对象池

四十八、反射的实现原理?

审查元数据并收集关于它的类型信息的能力。实现原理:在运行时根据程序集及其中的类型得到元数据。下面是实现步骤:

导入using System.Reflection;

Assembly.Load(“程序集”)加载程序集,返回类型是一个Assembly

得到程序集中所有类的名称

foreach (Type type in assembly.GetTypes())
{
string t = type.Name;
}

Type type = assembly.GetType(“程序集.类名”);获取当前类的类型
Activator.CreateInstance(type); 创建此类型实例
MethodInfo mInfo = type.GetMethod(“方法名”);获取当前方法
m.Info.Invoke(null,方法参数);

四十九、简述四元数的作用,四元数对欧拉角的优点?

四元数用于表示旋转,相对欧拉角的优点:
① 能进行增量旋转
② 避免万向锁
③ 给定方位的表达方式有两种,互为负(欧拉角有无数种表达方式)

五十、移动相机动作在哪个函数里,为什么在这个函数里?

LateUpdate,是在所有的update结束后才调用,比较适合用于命令脚本的执行。官网上例子是摄像机的跟随,都是所有的update操作完才进行摄像机的跟进,不然就有可能出现摄像机已经推进了,但是视角里还未有角色的空帧出现。

未完待续……

本文转自: Unity程序员samzhang

最新文章