Unity面试汇总

C#编程

问题:什么是协同程序?

在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,开启协同程序就是开启一个线程。换句话说,开启协同程序就是开启一个可以与当前程序并行的逻辑。

问题:协同程序与线程的区别?

线程和协同程序的主要区别在于:在多处理器情况下,从概念上来讲多线程程序同时运行多个线程;而协同程序是通过协作来完成,在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只在必要时才会被挂起。

问题:请简述ArrayList和List的主要区别?

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

问题:请简述sealed关键字用在类声明时与方法声明时的作用。

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

问题:请简述public,private,protected,internal的区别?

1.public:对任何类和成员都公开,无限制访问;

2.private:仅对该类公开;

3.protected:仅对该类和其派生类公开;

4.internal:只能在包含该类的程序集中访问该类;

问题:请描述Interface与抽象类之间的不同点?

接口支持多继承,抽象类支持单继承;接口完全抽象,抽象类部分抽象;接口中的方法不能有具体的实现代码,必须由继承自该接口的类来实现,抽象类中的非抽象成员(属性、方法)可以有具体的实现代码,其非抽象的子类可以根据需求选择性的重写父类中的非抽象成员;接口不能实例化,抽象类可以间接实例化。

问题:.Net与Mono的关系?

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

问题:C#和C++的区别?

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

问题:结构体和类有何区别?

结构体是值类型,类是引用类型。值类型用于存储数据的值,引用类型用于存储对实际数据的引用。

问题:ref参数和out参数是什么?有什么区别?

相同点:ref参数和out参数的效果一样,都是通过关键字找到定义在主函数里面的变量的内存地址,并通过方法体内的语法改变它的大小。

不同点:ref是引用参数,out是输出参数。引用参数必须在方法体外对参数进行初始化,输出参数必须在方法体内对参数进行初始化。

问题:C#的委托是什么?有何用处?

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

问题:C#中的排序方式有哪些?

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

问题:请简述GC(垃圾回收)产生的原因,并描述如何避免?

GC回收堆上的内存

1. 减少new产生对象的次数;

2. 使用公用的对象(静态成员);

3. 将String换为StringBuilder;

问题:重载和重写的区别?

1.所处位置不同:重载在同类中,重写在父子类中;

2.定义方式不同:重载方法名相同参数列表不同,重写方法名和参数列表都相同;

3.调用方式不同:重载使用相同对象以不同参数调用,重写使用不同对象以相同参数调用;

4.多态时机不同:重载是编译时多态,重写是运行时多态;

问题:面向对象的三大特点?

1.继承:

提高代码重用度,增强软件可维护性的重要手段,符合开闭原则(软件中的对象扩展是开放的,修改是关闭的)。继承就是把子类的公共属性集合起来(变量,方法等)共同管理,这些公共属性设置为父类,C#的继承是单继承,但继承有传递性:A继承B,B继承C,A可以调用C#中的方法。

2.封装:

封装是将数据和行为相结合,通过行为约束代码修改数据的程度,增强数据的安全性,属性是C#封装实现的最好体现。

3.多态:

多态性是指同名的方法在不同环境下,自适应的反应出不同得表现,是方法动态展示的重要手段。例如叫声,在鸟这个类中是“鸣啼”在狗这个类中是“犬吠”。

问题:值类型和引用类型的区别?

1.值类型存储在内存栈中,引用类型存储在内存堆中,而内存单元中存放的是堆中存放的地址。

2.值类型存取快,引用类型存取慢。

3.值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针和引用。

4.栈内存是自动释放的,堆内存在.NET 中由 GC来自动释放。

5.值类型继承自System.ValueType,引用类型继承自System.Object。

6.值类型的变量直接存放实际的数据,而引用类型的变量存放的则是数据的地址,即对象的引用。

7.值类型变量直接把变量的值保存在堆栈中,引用类型的变量把实际数据的地址保存在堆栈中。

问题:反射的实现原理?

可以在加载程序运行时,动态获取和加载程序集,获取程序集的信息,在运行期间动态获取类、对象、方法、对象数据。

下面是实现步骤:

1.导入using System.Reflection;

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

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

foreach (Type type in assembly.GetTypes())

{

    string t = type.Name;

}

4.Type type = assembly.GetType(“程序集.类名”);//获取当前类的类型;

5. Activator.CreateInstance(type);//创建此类型实例;

6. MethodInfo info = type.GetMethod(“方法名”);//获取当前方法;

7. info.Invoke(null,方法参数);

问题:下列代码在运行中会产生几个临时对象?

string a = new string("abc");
a = (a.ToUpper() + "123").Substring(0, 2); 

 在C#中第一行是会报错的(Java中倒是可行)

应该这样初始化:

string a = new string(new char[]{'a','b','c'});

 可以产生5个临时变量

问题:下列代码在运行中会发生什么问题?如何避免?

List<int> list = new List<int>(new int[] { 1, 2, 3, 4, 5 });
foreach (int item in list)
{
    Console.WriteLine(item);
    list.Remove(item);
}  

产生运行时错误,在 list.Remove(item)这行,因为foreach是只读的,不能一边遍历一边修改。

Unity

问题:Unity3d中碰撞器和触发器的区别?

碰撞器是触发器的载体,触发器是碰撞器身上的一个属性。当Is Trigger=false时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果,可以调用OnCollisionEnter/Stay/Exit函数;当Is Trigger=true时,碰撞器被物理引擎所忽略,没有碰撞效果,可以调用OnTriggerEnter/Stay/Exit函数。

问题:物体发生碰撞的必要条件?

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

问题:在物体发生碰撞的整个过程中,有几个阶段,分别列出对应的函数。

3个阶段;

OnCollisionEnter(进入)

OnCollisionStay(逗留)

OnCollisionExit(退出)

问题:如何安全的在不同的工程间安全地迁移Asset数据?

1.将Assets目录和Library目录一起迁移;

2.导出包(Export Package);

3.使用Unity自带的Assets Server功能;

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

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

问题:MeshRender中material和sharedmaterial的区别?

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

问题:Unity提供了几种光源,分别是什么?

1.平行光(Directional Light);

2.点光源(Point Light);

3.聚光灯(Spot Light);

4.区域光源(Area Light);

问题:简述一下对象池,你觉得在FPS里哪些东西适合使用对象池。

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

问题:CharacterController和Rigidbody的区别?

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

问题:简述预制体(Prefab)的用处

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

问题:使用Unity3d实现2d游戏,有几种方式?

1. 使用本身的GUI,在Unity4.6以后出现的UGUI;

2. 摄像机的Projection(投影)值调为Orthographic(正交投影),不考虑z轴;

3. 使用2D插件,如:2DToolKit和NGUI;

问题:Unity3d的物理引擎中,有几种施加力的方式,分别描述出来。

rigidbody.AddForce/AddForceAtPosition,都在rigidbody系列函数中。

问题:什么叫做链条关节?

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

问题:物体围绕自身旋转和围绕目标旋转使用的函数分别是什么?

Transform.Rotate()和Transform.RotateAround()

问题:Unity3d提供了一个用于保存和读取数据的类(PlayerPrefs),请列出保存和读取整形数据的函数。

PlayerPrefs.SetInt()和PlayerPrefs.GetInt()

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

Awake>OnEnable>Start>FixedUpdate>

Update>LateUpdate>OnGUI>OnDisable>OnDestroy

问题:物理更新一般放在哪个系统函数里?

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

问题:在场景中放置多个Camera并同时处于活动状态会发生什么?

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

问题:如何销毁一个UnityEngine.Object及其子类?

使用Destroy()方法。

问题:请描述为什么Unity3d中会发生在组件上出现数据丢失的情况。

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

问题:LOD是什么,优缺点是什么?

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

问题:MipMap是什么,有什么作用?

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

问题:什么是LightMap?

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

问题:简述Unity3D支持的作为脚本的语言的名称。

C#、JavaScript(已经不再使用)

问题:U3D中用于记录节点空间几何信息的组件名称,及其父类名称。

Transform,父类是Component;

问题:向量的点乘、叉乘以及归一化的意义?

1.点乘描述了两个向量的相似程度,结果越大两向量越相似,还可表示投影;

2.叉乘得到的向量垂直于原来的两个向量所在的平面;

3.标准化向量:用在只关系方向,不关心大小的时候;

问题:为何大家都在移动设备上寻求U3D原生GUI的替代方案?

OnGUI不美观,不方便,耗费时间,效率不高。

问题:请简述如何在不同分辨率下保持UI的一致性。

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

问题:Unity和cocos2d的区别?

1.Unity3D支持C#、JavaScript(已经不再使用),cocos2d支持C++、HTML5、Lua等;

2.cocos2d开源并且免费;

3.Unity3D支持IOS、Android、Flash、Windows、Mac、Wii等平台的游戏开发,cocos2d支持IOS、Android、WP等;

问题:射线检测碰撞物的原理是?

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

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

剪裁平面 ,摄像机开始渲染到停止渲染之间的距离。

问题:如何让已经存在的GameObject在LoadLevel后不被卸载掉?

private void Awake()

{

    DontDestroyOnLoad(transform.gameObject);

}

问题:简述四元数的作用,四元数对欧拉角的优点?

四元数用于表示旋转。

相对欧拉角的优点:

1.能进行增量旋转;

2.避免万向锁;

3.给定方位的表达方式有两种,互为负(欧拉角有无数种表达方式);

问题:移动相机动作在哪个函数里,为什么在这个函数里?

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

问题:动态加载资源的方式?他们之间的有何区别?

1.Resources

2.AssetBundle

区别:

Resources是动态内部调用,Resources在编辑环境下是Project窗口的一个文件夹,调用里面的资源,可以用Resources类,比如Resources.Load,打包后这个文件夹是不存在的,会统一生成Assets资源。

AssetBundle是动态外部调用,要用AssetBundle首先要把资源打包成.assetbundle文件,再动态的去加载这个文件,本地或者网络服务器都可以。

简而言之,Resources资源的加载是动态加载内部的,AssetBundle是动态加载外部的。

问题:请描述游戏动画有哪几种,以及其原理?

主要有关节动画、单一网格模型动画(关键帧动画)、骨骼动画。

关节动画:把角色分成若干独立部分,一个部分对应一个网格模型,部分的动画连接成一个整体的动画,角色比较灵活,Quake2中使用这种动画;

单一网格模型动画(关键帧动画)由一个完整的网格模型构成,在动画序列的关键帧里记录各个顶点的原位置及其改变量,然后插值运算实现动画效果,角色动画较真实;

骨骼动画,广泛应用的动画方式,集成了以上两个方式的优点,骨骼按角色特点组成一定的层次结构,有关节相连,可做相对运动,皮肤作为单一网格蒙在骨骼之外,决定角色的外观;

问题:Unity3D是否支持写成多线程程序?如果支持的话需要注意什么?

支持:Unity3D没有多线程的概念,但是Unity3D为我们提供了StartCoroutine(协同程序)。

注意:C#中有lock这个关键字,以确保只有一个线程可以在特定时间内访问特定的对象。

问题:矩阵相乘的意义及注意点?

意义:用于表示线性变换(旋转、缩放、投影、平移、仿射)
注意点:矩阵的蠕变(误差的积累)

问题:为什么Dynamic Font在Unicode环境下优于Static Font ?

Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。
使用动态字体时,Unity不会预先生成一个包含所有字体的字符纹理。当需要支持亚洲语言或者较大的字体的时候,若使用正常纹理,则字体的纹理将非常大。

问题:获取、添加、删除组件的命令分别是什么?

获取:GetComponent()

添加:AddComponent()

删除:Destroy()

问题:层(Layers)添加和剔除?

使用LayerMask,通过位运算的方式去设置。

在代码中如何开启或关闭一个层(Layers)?

LayerMask mask = 1 << 2;//表示开启Layer2。

LayerMask mask = 0 << 5;//表示关闭Layer5。

LayerMask mask = 1<<2|1<<8;//表示开启Layer2和Layer8。

LayerMask mask = 0<<3|0<<7;//表示关闭Layer3和Layer7。

问题:画布的三种模式-缩放模式?

屏幕空间-覆盖模式(Screen Space - Overlay):Canvas创建出来后,默认就是该模式,该模式和摄像机无关,即使场景内没有摄像机,UI游戏物体照样渲染。

  • 屏幕空间:只有x轴和y轴
  • 覆盖模式:UI元素永远在3D元素的前面

屏幕空间-摄像机模式(Screen Space - Camera):设置成该模式后需要指定一个摄像机游戏物体,指定后UGUI就会自动出现在该摄像机的“投射范围”内,和NGUI的默认UI Root效果一致,如果隐藏掉摄像机,UGUI就不会渲染。

世界空间模式(WorldSpace):设置成该模式后,UGUI就相当于是3D场景内的一个普通的游戏对象,可以在3D场景内任意移动UGUI元素的位置,通常用于怪物血条显示和VR开发。

问题:使用过哪些Unity插件?

Shader Graph:特效插件

PlayerMaker:可视化编程插件

DoTween:动画插件

AVPro Video:视频播放插件

XLua:热更新插件

Addressables:资源管理插件

EasyTouch:手游触摸控制

渲染

问题:GPU的工作原理?

渲染流水线可分为应用阶段、几何阶段和光栅化阶段。应用阶段由CPU主导,而几何阶段和光栅化阶段由GPU主导(GPU流水线)。

几何阶段又可以细分为一下几个子流水线:

1.顶点着色器:用于实现顶点的空间变换、顶点着色等功能。其主要完成的是把顶点坐标从模型空间转换到齐次裁剪空间

2.曲面细分着色器:用于细分图元。

3.几何着色器:用于执行逐图元的着色操作或用于产生更多的图元。

4.裁剪:用于将那些不在摄像机视野内的顶点裁剪掉。

5.屏幕映射:负责把每个图元的坐标转换到屏幕坐标系中。

光栅化阶段又可以细分为一下几个子流水线:

1.三角形设置:计算光栅化一个三角网格所需要的信息。

2.三角形遍历:检查每个像素是否被一个三角网格所覆盖,如果有被覆盖的话,就会生成一个片元

3.片元着色器:根据上一步插值后的片元信息,片元着色器计算该片元的输出颜色。

4.逐片元操作:决定每个片元的可见性(深度测试、模板测试)。如果一个片元通过了所有测试,就需要把这个片元的颜色和已经存储在颜色缓冲区中的颜色进行合并(混合)。

经过以上流水线阶段后,在屏幕上输出图像。

问题:什么是渲染管道?

渲染管道是指在显示器上为了显示出图像而经过的一系列必要操作。渲染管道中的很多步骤,都要将几何物体从一个坐标系中变换到另一个坐标系中去。

主要步骤有:本地坐标->视图坐标->背面裁剪->光照->裁剪->投影->视图变换->光栅化

问题:Alpha Blend工作原理?

Alpha Blend实现透明效果,不过只能针对某块区域进行Alpha操作,透明度可设。

问题:写出光照计算中的diffuse的计算公式。

diffuse = Kd * LightColor * max(N*L,0); Kd漫反射系数、LightColor光源颜色、N单位法线向量、L 由点指向光源的单位向量、其中N与L点乘,如果结果小于等于0,则漫反射为0。

问题:两种阴影判断的方法和工作原理?

本影:景物表面上那些没有被光源直接照射的区域(全黑的轮廓分明的区域)。

半影:景物表面上那些被某些特定光源直接照射但并非被所有特定光源直接照射的区域(半明半暗区域)。

工作原理:从光源处向物体的所有可见面投射光线,将这些面投影到场景中得到投影面,再将这些投影面与场景中的其他平面求交得出阴影多边形,保存这些阴影多边形信息,然后再按视点位置对场景进行相应处理得到所要求的视图(利用空间换时间,每次只需依据视点位置进行一次阴影计算即可,省去了一次消隐过程)。

问题:Vertex Shader是什么,怎么计算?

顶点着色器是一段执行在GPU上的程序,用来取代固定管线中的变换和光照,Vertex Shader主要操作顶点。

Vertex Shader对输入顶点完成了模型空间到homogeneous space(齐次裁剪空间)的变换过程,homogeneous space即projection space的下一个space。在这其间共有world transformation(世界变换), view transformation(视图变换)和projection transformation(投影变换)及lighting几个过程。

热更新

内存优化

问题:如何优化内存?

1.压缩自带类库;

2.将暂时不用的以后还需要使用的物体隐藏起来而不是直接Destroy掉(对象池);

3.释放AssetBundle占用的资源;

4.降低模型的面数,降低模型的骨骼数量,降低贴图的大小;

5.使用光照贴图、多层次细节(LOD)、预制体(Prefab);

6.减少代码中产生的临时变量;

网络通信/网络编程

问题:TCP/IP协议各个层次及分别的功能?

应用层:用来处理特定的应用,针对不同的应用提供不同的协议。例如进行文件传输时用FTP协议、发送Email时用SMTP协议。

传输层:主要功能是提供应用程序之间的通信,这一层主要是TCP协议和UDP协议。

网络层:处理分组在网络中的活动,例如路由选择和转发等。这一层主要包含IP协议、ARP协议、ICMP协议等。

网络接口层:这是协议栈的最底层,对应OSI的物理层和数据链路层,主要完成数据帧的发送和接收。

游戏功能实现思路

问题:跳跃到最高点自动开枪,这个功能应该怎么做?

定义一个布尔变量jumping表示玩家是否正在跳跃。
在每帧中检测玩家是否按下了跳跃键,如果按下了,则将jumping设为true。
如果 jumping为true,则检测玩家是否已经到达最高点。可以通过判断玩家的竖直速度是否小于等于0来判断是否到达最高点。
如果到达了最高点,则自动开枪。可以调用开枪的函数或发送一个开枪的指令给服务器。

问题:角色可以穿脱装备,每个装备对角色的血量有不同的buff,该如何设计这个功能?

1.装备属性的实现:装备可以为角色提供一些属性加成(加血、加攻击力)。可以通过设计一个装备属性接口,让装备继承该接口,并实现对应的属性加成函数。在角色穿戴或卸下装备时,调用对应的属性加成函数即可。
2.装备buff的实现:当角色穿戴某个装备时,可以获得该装备的buff(加攻速)。可以在装备属性接口中添加一个获取buff的函数,在角色穿戴该装备时,调用该函数获取buff,并将buff应用到角色上。

  • 19
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kevin_Erics

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值