Unity面试题汇总(第一部分)

一、什么是渲染管道?

    答:就是告诉GPU一些数据,经过一系列的操作,得到最终要显示的数据。渲染管道中的很多步骤,总的来说是将几何物体从一个坐标系变换到另一个坐标系中去。

      主要步骤如下:

        本地坐标系 -- 经过世界变换矩阵 --> 世界坐标系 -- 经过视图变换矩阵 --> 视图坐标系 -- 经过投影变换矩阵 -->  投影坐标系 -- 经过视口变换矩阵 --> 视口坐标系

 

二、如何优化内存?

    答:优化内存的方式有很多种

      比如:

        1.压缩自带类库;

        2.将暂时不用的,以后还需要使用的物体隐藏起来,而不是Destroy掉;

        3.释放AssetBundle占用的资源;

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

        5.使用光照贴图,使用多层次细节(LOD),使用着色器(Shader),使用预设(Prefab)。

 

三、动态加载资源的方式,以及区别。

    答:

      1.通过Resources.Load()模块:调用它的load函数,可以直接load并返回某个类型的Object,前提是需要把这个资源放在Resource命名的文件夹下,Unity不管有没有场景引用,都会将其全部打包到安装包中。

      2.通过bundle的形式:即将资源打包成 asset bundle 放在服务器或本地磁盘,然后使用www模块get下来,之后从这个bundle中load某个Object。

      3.通过AssetDatabase.loadasset:这种方式只在editor范围内有效,游戏运行时没有这个函数,他通常是在开发中调用。

      区别:

      Resoueces的方式需要把所有资源全部打入安装包,这对游戏的发布和版本升级(patch)是不利的,所以Unity不太推荐使用它,而都用bundle的方式代替,把资源打成几个小的bundle,用哪个就load哪个,这样有利于分包发布和版本升级。但是在开发过程中,不可能每更新一个资源就打一次bundle,所以在editor环境下可以使用AssetDatabase来模拟,这通常需要我们封装一个dynamic resource的loader模块,在不同的环境下做不同的实现。

 

四、什么是协同程序?

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

 

五、Unity中的碰撞器和触发器的区别。

    答:

      1.碰撞器是触发器的载体,而触发器只是碰撞器身上的一个属性。

      2.当 Is Trigger = fasle 时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果。可以调用OnCollisionEnter、OnCollisionExit 函数;

      3.当 Is Trigger = true 时,碰撞器被物理引擎所忽略,没有碰撞效果,可以调用OnTriggerEnter、OnTriggerExit 函数。

      4.如果既要检测到物体的接触,又不想让碰撞检测影响物体移动,或者要检测一个物体是否经过空间中的你某个区域,这时就可以用到触发器。

 

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

    答:

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

 

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

    答:

      ArrayList存在类型不安全(ArrayList会把插入其中的数据都当作Object来处理),装箱和拆箱的操作(费时)。

      List类是ArrayList类的泛型等效类。它的大部分用法都与ArrayList相似,因为List类也继承了IList接口。最关键的区别在于,在声明List集合时,我们同时需要为其声明List集合内数据的对象类型

 

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

    答:

      1.将Asset目录和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,具有一定的物理效果但不是完全真实的,是Unity为了使开发者能方便、快速的开发游戏而封装的一个组件。

 

十四、简述prefab的用处。

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

 

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

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

 

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

    答:1.private:仅对该类公开。

      2.protected:对该类和其派生类公开。

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

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

      知识扩展:什么事程序集?

          经由编译器编译得到的,供CLR进一步编译执行的那个中间产物,在WINDOWS系统中,它一般表现为·dll或者是·exe的格式,但是要注意,它们跟普通意义上的WIN32可执行程序是完全不同的东西,程序集必须依靠CLR才能顺利执行。

 

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

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

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

      3.使用2d插件,如:2DToolKit 和 NGUI。

 

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

    答:OnCollisionEnter --> OnCollisionStay --> OnCollisionExit。

 

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

    答:Rigidbody.AddForce 和 Rigidbody.AddForceAtPosition。

 

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

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

 

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

    答:Transform.Rotate();

 

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

    答:1.保存整型数据函数:PlayerPrefs.SetInt()

      2.读取整型数据函数:PlayerPrefs.GetInt()。

 

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

    答:Awake ---> OnEnable ---> Start ---> FixedUpdate ---> Update ---> LateUpdate ---> OnGUI ---> OnDisable ---> OnDestroy

 

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

    答:一般放在FixedUpdate里。

      FixedUpdate函数:每固定帧绘制时执行一次,和Update不同,它是渲染帧执行。FixedUpdate比较适合用于物理引擎计算,Update比较适合做控制。

 

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

    答:1.若是Depth值相等,则会使用最后创建(激活)出来的摄像机进行渲染。

      2.若是Depth值不相等,则会使用Depth值最高的摄像机进行渲染。

 

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

    答:使用Destroy()方法。

 

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

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

 

二十八、请描述什么是LOD,它的优缺点分别是什么?

    答:LOD(Level of detail)多层次细节,是最常用的游戏优化技术。

      优点:它按照模型的位置和重要程度决定其渲染的资源分配,降低物体的面数和细节度,从而获得高效率的渲染运算。

      缺点:增加了内存。

 

二十九、MipMap是什么?它的作用是什么?

    答:MipMap是常用的游戏优化技术,贴图会根据与摄像机的距离,选择不同精度的贴图。

      作用:为了加快渲染进度和减少图像锯齿,贴图被处理成一系列被预先计算和优化过的图片组成的文件。其技术特点优点类似于LOD技术,但是不用的是,LOD是针对模型资源,而MipMap是针对的纹理贴图资源。

      优点:优化显存宽带,用以减少渲染。

      缺点:增加了内存。

 

三十、请描述接口与抽象类之间的不同。

    答:1.接口和抽象类的概念不一样。接口是对动作的的抽象,而抽象类是对根源的抽象。

      2.接口表示的是:这个对象能做什么。抽象类表示的是:这个对象是什么。

      3.在高级语言上,一个类只能继承自另一个类,但是可以实现多个接口。

      4.接口中的所有方法都是抽象的,不用去实现。而抽象类是声明方法的存在而不一定去实现。

      总结:当我们关注一个事物的本质的时候,用抽象类。当我们关注的是一个操作的时候,用接口。

         抽象类的功能远超过接口,但是定义抽线类的代价更高。因为对于高级语言来说,每个类只能继承自另一个类,在这个类中,你必须继承或编写出其所有子类的所有共性。虽然接口在功能上会弱化很多,但是它只是针对一个动作的描述,而且你可以在一个类中同时实现多个接口,这在设计阶段会降低难度。

 

三十一、请简述.Net与Mono的关系。

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

 

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

    答:JavaScript C#Boo。

 

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

    答:用于记录节点空间几何信息的组件:Transform。

      其父类名称是:Component。

 

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

    答:1.向量的点乘:两个向量的相似度,结果越大两个向量越相似。还可以表示投影。

      2.向量的叉乘:得到新向量垂直于原来的两个向量。

      3.归一化:用在只关心向量的方向,而不关心大小的时候。

 

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

    答:1.不美观。

      2.OnGUI很耗费时间,效率不高,使用不方便。

 

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

    答:1.NGUI插件很好的解决了这一点,屏幕分辨率的自适应性。原理就是计算出当前屏幕的宽高比跟原来预设的屏幕的分辨率求出一个对比值,然后修改摄像机的Size。

      2.UGUI通过锚点、中心点和分辨率也解决了这个问题。

 

三十七、什么是LightMap?

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

 

三十八、请简述Unity3d和Cocos2d的区别。

    答:1.Unity支出C#、JavaScript等语言。Cocos2d支持c++、Html5等语言。

      2.Cocos2d开源并且免费。

      3.Unity3d支持ios、android、flash、windows、mac、wii等平台的游戏开发。Cocos2d支持ios、android、wp等平台的游戏开发。

 

三十九、请简述C#与C++的区别。

    答:1.C 是完全面向过程的语言,用于开发规模较小的程序效率很高,但是如果开发规模较大的程序,就会显得代码量陡增,编写效率下降。

      2.C++是半面向对象的语言,引入了类的封装性、继承性、多态性。大大简化了代码的编写,提高了代码的重用率。

      3.C#是完全面向对象的语言,简单易学,开发效率非常高。

 

四十、请简述结构体和类的区别。

    答:1.结构体不能被继承,而类可以。

      2.结构体是值类型。而类是引用类型。

      3.结构体在数据参数方面效率更高,简单数组的应用中成本很低。

      4.类在运算方面更有优势,在抽象多级别时是最佳选择。

 

四十一、请简述ref参数和out参数是什么,有什么区别。

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

      2.ref关键字修饰的参数必须初始化,out关键字修饰的参数必须在函数里赋值。

      3.ref关键字修饰的参数是引用,out关键字修饰的参数为输出参数。

 

四十二、请简述C#中的委托是什么,有什么用处。

    答:委托是一个类。

      它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种做法可以避免在程序中大量的使用if-else(Switch)语句,同时使得程序具有更好的可扩展性。

 

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

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

 

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

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

 

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

    答:Clipping Planes:裁剪平面,摄像机开始渲染和停止渲染之间的距离。

 

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

    答:

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

 

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

    答:GC回收堆上的内存。

      避免:1.减少new产生对象的次数。

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

         3.将String换为StringBuilder。

 

四十八、请简述反射的实现原理。

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

      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.GetMeethod("方法名");获取当前方法

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

 

四十九、简述四元数的作用,四元数相对于欧拉角有哪些有点。(重点知识,需要学习和了解:矩阵旋转、欧拉角、四元数)

    答:四元数用于表示旋转。

      其相对于欧拉角的有点:

      1.避免万向锁。

      2.只需要一个4维的四元数就可以执行绕任意过原点的向量的旋转,方便快捷,在某些实现下比旋转矩阵效率更高。

      3.可以提供平滑插值。

 

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

    答:在LateUpdate里面执行。

      因为需要在所有的Update结束之后才调用。在官网的例子中,都是所有的Update操作完成才进行摄像机的跟进,不然的话可能会造成摄像机已经跟进,但是视角里还未有角色的空帧出现。

 

五十一、简述GPU的工作原理。

    答:简而言之,GPU的图形(处理)流水线完成如下的工作:(并不一定是按照如下顺序) 顶点处理:这阶段GPU读取描述3D图形 外观的顶点数据并根据顶点数据确定3D图形的形状及位置关系,建立起3D图形的骨架。在支持DX8DX9规格的GPU中,这工作由硬件实现的Vertex Shader(定点着色器)完成。 光栅化计算:显示器实际显示的图像是由像素组成的,我们需要将上面 生成的图形上的点和线通过一定的算法转换到相应的像素点。把一个矢量图形转换为一系列像素点的过程就称为光栅化。例如,一 条数学表示的斜线段,最终被转化成阶梯状的连续像素点。 纹理帖图:顶点单元生成的多边形只构成了3D物体的轮廓,而纹理映 射(texture mapping)工作完成对多变形表面的帖图,通俗的说,就是将多边形的表面贴上相应的图片,从而生成真实的图形。 TMUTexture mapping unit)即是用来完成此项工作。 像素处理:这阶段(在对每个像素进行光栅化处理期间)GPU完成对像素 的计算和处理,从而确定每个像素的最终属性。在支持DX8DX9规格的GPU中,这些工作由硬件实现的Pixel Shader(像素着 色器)完成。 最终输出:由ROP(光栅化引擎)最终完成像素的输出,1帧渲染完毕后,被送到显存帧缓冲区。

    总结:GPU的工作通俗的来说就是完成3D图形的生成,将图形映射到相应的像素点上,对每个像素进行计算确定最终颜色并完成 输出。

 

五十二、请简述游戏动画有哪几种,以及其原理。

    答:1.关节动画。原理:把角色分成若干独立部分,一个部分对应一个网格模型,部分的动画连接成一个整体的动画,角色动画比较灵活。

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

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

 

五十三、请简述alpha blend的工作原理。

    答:Alpha Blend实现透明效果,不过只能针对某块区域进行alpha操作,透明度可以设置。(这道题需要去复习计算机图形学才能回答)

 

五十四、写出光照运算中的diffuse的计算公式。(这道题需要去学习Shader的实现原理,目前还没能力去掌握)

    答:diffuse = kd x colorLight x max(N*L, 0);其中:

      kd:漫反射系数。

      colorLight:光的颜色。

      N:单位法线向量。

      L:由点只想光源的单位向量。其中N与L点乘,如果结果小于等于0,则漫反射为0。

 

五十五、Vertex Shader是什么,怎么计算的?

    答:顶点着色器是一段执行在GPU上的程序,用来取代 fixed pipeline 中的transformation 和 lighting,Vertex Shader 主要操作顶点。

      Vertex Shader对输入顶点完成了从local spacehomogeneous space(齐次空间)的变换过程,homogeneous space projection space的下一个space。在这其间共有world transformation, view transformationprojection transformationlighting 几个过程。

 

五十六、下列代码在运行中会产生几个临时对象?

 

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

 

    答:在C#中第一行是会报错的。

      正确初始化方式:string b = 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 * item);
     list.Remove(item);        
}

    答:发生的问题:产生运行时错误,在list.Remove(item)这行,因为foreach是只读的,在遍历过程中,是将遍历的值赋值给临时创建的item,所以不能一边遍历一遍删除。

      如何避免:可以用for循环遍历,并删除数据。

 

五十八、Unity3d是否支持多线程?如果支持的话需要注意什么?

    答:不支持。仅能从主线程中访问Unity3d的对象、组件和方法。如果需要同时处理很多事情,并且与Unity3d的对象互动小的话,可以用thread,否则使用coroutine。

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

 

五十九、Unity3d的协程和C#的线程之间的区别是什么?

    答:C#多线程程序同时运行多个线程。

      unity3d的协程在任意指定时刻只有一个协程在运行,并且这个正在运行的协同程序只在必要时才被挂起。除主线程之外的线程无法访问u3d的对象、组件、方法。

      unity3d没有多线程概念,不过unity3d也给我们提供了StartCoroutine(协同程序)和LoadLevelAsync(异步加载关卡)后台加载场景的方法。

 

六十、请简述矩阵相乘的意义以及注意点。

    答:用于表示线性变换:平移、缩放、旋转、投影、仿射。

      注意矩阵的蠕变:误差的积累。

 

六十一、为什么dynamic font 在 unicode 环境下优于static font?

    答:当你在导入设置的字符(Characters )下拉菜单设置为动态(Dynamic),Unity将不会预先生成一个与所有字体的字符纹理。相反,它会使用操作系统内置的字体渲染实时来创建的纹理。这样做的好处,它可以保存下载的大小和纹理内存,尤其是当你使用通常在用户系统中的字体,所以你不必包括字体的数据,或当你需要支持亚洲语言或较大的字体大小(使用正常字体纹理,使字体的纹理非常大)。它的缺点,字体渲染未必所有的用户机器上看起来完全是相同的(尤其是Mac和Windows计算机之间,或当一个字体未安装和使用一个备用的字体),并且,在生成屏幕上所需要的字符字体纹理,有时可能会导致速度变慢。

 

六十二、当一个细小的高速物体撞向另一个较大的物体时,会出现什么情况?如何避免?

    答:可能会出现穿透现象(碰撞检测失败)。

      如何避免:将在明天的程序中去实现下功能。

 

六十三、请简述OnBecameVisible和OnBecameInvisible的发生时机,以及这对回调函数的意思。

    答:OnBecameVisible:当物体处于摄像机渲染的范围时,调用。

      OnBecameInvisible:当原本处于摄像机渲染的范围的物体,不在摄像机渲染范围的时候,调用。

 

六十四、什么叫动态合批?跟静态合批有什么区别?

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

      区别:动态批处理:一切都是自动的,不需要做任何操作,并且物体是可以移动的,但是限制很多。

         静态批处理:自由度很高,限制很少,缺点是可能会占用更多的内存,而且经过静态批处理之后的物体就不可以再移动了。

 

六十五、请简述StringBuilder 和 String的区别?

    答:String是字符串常量。

      StringBuffer是字符串变量 ,线程安全。

      StringBuilder是字符串变量,线程不安全。

      String类型是个不可变的对象,当每次对String进行改变时都需要生成一个新的String对象,然后将指针指向这个新的对象,如果在一个循环里面,不断的改变一个String对象,就要不断的生成新的对象,所以效率很低,建议在不断更改String对象的地方不要使用 String类型。

      StringBuilder对象在做字符串连接操作时是在原来的字符串上进行修改,改善了性能。这一点我们平时使用中也许都知道,连接操作频繁的时候,使用StringBuilder对象。

 

六十六、Unity3d Shader分哪几种?有什么区别?

    答:表面着色器:抽象层次比较高,可以轻松地以简洁的方式实现复杂着色。表面着色器可同时在前向渲染及延迟渲染模式下正常的工作。

      顶点片段着色器:可以非常灵活地实现需要的效果,但是需要编写更多的代码,并且很难与Unity的渲染管线完美集成。

      固定功能管线着色器:可以作为前两种着色器的备用选择,当硬件无法运行那些酷炫的Shader时,还可以通过固定功能管线着色器来绘制一些基本的内容。

 

六十七、C#中的四种访问修饰符是什么?各有什么区别?

    答:1.属性修饰符。

      2.存取修饰符。

      3.类型修饰符。

      4.成员修饰符。

 

      1.属性修饰符:

        a.Seriallizable:按值将对象封送到远程服务器。

        b.STAThread:是单线程套间的意思,是一种线程模式。

        c.MATAThread:是多线程套间的意思,也是一种线程模式。

      2.存取修饰符:

        a.public:存取不受限制。

        b.protected:只有包含该成员的类以及派生类可以存取。

        c.private:只有包含该成员的类可以存取。

        d.internal:只有当前工程可以存取。

      3.类修饰符:

        a.abstract:抽象类。指示一个类只能作为其它类的基类。

        b.sealed:密封类。指示一个类不能被继承。所有密封类不能同时又是抽象类,因为抽象类总是希望被继承的。

      4.成员修饰符:

        a.abstract:指示该方法或属性没有实现。

        b.sealed:密封方法。可以防止在派生类中对该方法的override(重载)。

        c.delegate:委托。用来定义一个函数指针。C#中的事件驱动是基于 delegate + event的。

        d.const:指定该成员的值只读,不允许修改。

        e.event:声明一个事件。

        f.extern:指示方法在外部实现。

        g.override.重写。对由基类继承成员的新实现。

        h.readOnly:指示一个域只能在声明时以及相同类的内部被赋值。

        i.static:指示一个成员属于类型本身,而不是属于特定的对象。即在定义后可不经实例化,就可使用。

        j.virtual:指示一个方法或存取器的实现可以在继承类中被覆盖。

        k.new:在派生类中隐藏指定的基类成员,从而实现重写的功能。若要隐藏继承类的成员,请使用相同名称在派生类中声明该成员,并用new修饰符修饰它。

 

六十八、Heap与Stack有何区别?

    答:1.heap是堆,stack是栈。

      2.heap的空间是手动申请和释放的,heap常用new关键字了来分配。stack空间由操作系统自动分配和释放。

      3.heap的空间是很大的自由区。stack的空间有限。

 

六十九、值类型和引用类型有哪些区别?

    答:1.值类型的数据存储在栈中;引用类型的数据存储在堆中。

      2.值类型存取速度快;引用类型存取速度慢。

      3.值类型表示实际数据;引用类型表示指向存储在堆上的数据的指针或引用。

      4.值类型继承自System.ValueType;引用类型继承自System.Object。

      5.栈的内存分配是自动释放的;而堆在.NET中会有GC来释放。

 

七十、协同程序的执行代码是什么?有何用处?有何缺点?

    答:

function Start()
{
     StartCoroutine(WaitAndPrint(2.0f));
     print("Before WaitAndPrint Finishes " + Time.time);     
}

function WaitAndPrint(waitTime: float)
{
     yield WaitForSeconds(waitTime);
     print("WaitAndPrint" + Time.time)  
}

    作用:一个协同程序在执行过程中,可以在任意位置使用yield语句。yield的返回值控制合适恢复协同程序向下执行。协同程序在对象自有帧执行过程中堪称优秀。协同程序在性能上没有更多的开销。

    缺点:协同程序并非真线程,可能会发生堵塞。

 

七十一、请简述序列化。

    答:序列化简单理解成把对象转换为容易传输的格式的过程。比如,可以序列化一个对象,然后使用HTTP通过Internet在客户端和服务器之间传输该对象。

 

七十二、概述C#中代理和事件?

    答:代理就是用来定义指向方法的引用。

      C#事件本质就是对消息的封装,用作对象之间的通信;发送方叫事件发送器,接收方叫事件接收器。

 

七十三、客户端和服务器交互方式有几种?

    答:1.Socket通常也称作“套接字”,实现服务器和客户端之间的物理连接,并进行数据传输,主要有UDP和TCP两个协议。Socket处于网络协议的传输层。

      2.Http协议传输的主要有http协议和基于http协议的Soap协议(web service),常见的方式是http的post和get请求,web服务。

 

七十四、Unity和Android与ios如何交互?

    答:Unity可以导出Android和ios的工程,然后通过Android或者ios的类去给Unity发消息,调用Unity中的方法。

 

七十五、如何在Unity中查看场景的面数,顶点数和Draw Call数?如何降低Draw Call数?

    答:在Game视图右上角点击Stats。

      降低Draw Call的技术是Draw Call Baching。

 

七十六:请问alpha test在何时使用?能达到什么效果?

    答:Alpha Test ,中文就是透明度测试。简而言之就是V&F shader中最后fragment函数输出的该点颜色值(即上一讲frag的输出half4)的alpha值与固定值进行比较。AlphaTest语句通常于Pass{}中的起始位置。Alpha Test产生的效果也很极端,要么完全透明,即看不到,要么完全不透明。

 

七十七、Unity在移动设备上的一些优化资源的方法?

    答:1.使用assetbundle,实现资源分离和共享,将内存控制在200m之内,同时也可以实现资源的在线更新。

      2.顶点数对渲染无论是CPU还是GPU都是压力最大的贡献者,降低顶点数到8万以下,fps30帧以上。

      3.只用一盏动态光,不使用阴影,不使用光照探头。

      4.剪裁粒子系统。

      5.合并同时出现的粒子系统。

      6.自己实现轻量级的粒子系统。

      7.animator也是一个效率奇差的地方,把不需要骨骼动画和动作过渡的地方全部使用Animation,控制骨骼数量在30根以下。

      8.删除无意义的animator。

      9.animator的初始化很耗时,粒子上尽量不要使用animator。

      10.除主角外尽量都不要跟骨骼运动(apply root motion)。

      11.绝对禁止哪些不带刚体,带包围盒的物体(static collider)运动。

      12.每帧递归的计算 finalalpha 改为只有初始化和变动时计算。

      13.去掉法线计算。

      14.不要每帧计算 veiwsize 和 windowsize。

      15.filldrawcall时构建顶点缓存使用array.copy。

      16.代码裁剪:使用strip level,使用.net2.0 subset。

      17.尽量减少 smooth group。

      18.给美术定一个严格的经过科学验证的美术标准,并且最喜爱Unity3d里面配以相应的检查工具。

  

        

 

 

      

 

      

      

 

 

 

 

 

 

 

 

 

      

 

 

 

 

 

               

posted @ 2018-03-02 11:50  Dean二十七  阅读(11828)  评论(0编辑  收藏  举报