Unity试题收集

来源:互联网 发布:网络选修课 编辑:程序博客网 时间:2024/06/08 03:45

Unity相关

动画相关

1.请描述游戏动画有哪几种,以及其原理。

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

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

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

骨骼动画,广泛应用的动画方式,集成了以上两个方式的优点,骨骼按角色特点组成一定的层次结构,由关节相连,可做相对运动,皮肤作为单一网格蒙在骨骼之外,决定角色的外观。皮肤网格每一个顶点都会受到骨骼的影响,从而实现完美的动画。(骨骼动画是由关节动画发展而来的,如今基本都使用骨骼动画来实现角色动画)

渲染相关

1.alpha blend 工作原理

实际显示颜色 = 前景颜色Alpha/255 + 背景颜色(255-Alpha)/255

2.写光照计算中的diffuse的计算公式

实际光照强度 I= 环境光(Iambient) + 漫反射光(Idiffuse) + 镜面高光(Ispecular);

环境光:Iambient= Aintensity* Acolor; (Aintensity表示环境光强度,Acolor表示环境光颜色)

漫反射光:Idiffuse = Dintensity*Dcolor*N.L;

(Dintensity表示漫反射强度,Dcolor表示漫反射光颜色,N为该点的法向量,L为光源向量)

镜面反射光:Ispecular = Sintensity*Scolor*(R.V)^n;

(Sintensity表示镜面光照强度,Scolor表示镜面光颜色,R为光的反射向量,V为观察者向量,n称为镜面光指数)

3.Vertex Shader是什么?怎么计算?

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

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

4.什么是渲染管道?

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

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

主要步骤有:

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

技术实现

1.lod是什么,优缺点是什么

LOD技术即Levels of Detail的简称,意为多细节层次。LOD技术指根据物体模型的节点在显示环境中所处的位置和重要度,决定物体渲染的资源分配,降低非重要物体的面数和细节度,从而获得高效率的渲染运算。

优点:可根据距离动态地选择渲染不同细节的模型

缺点:加重美工的负担,要准备不同细节的同一模型,同样的会稍微增加游戏的容量。

2.两种阴影判断的方法工作原理

阴影由两部分组成:本影与半影

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

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

求阴影区域的方法:做两次消隐过程

一次对每个光源进行消隐,求出对于光源而言不可见的区域L;

一次对视点的位置进行消隐,求出对于视点而言可见的面S;

shadow area= L ∩ S

阴影分为两种:自身阴影和投射阴影

自身阴影:因物体自身的遮挡而使光线照射不到它上面的某些可见面

工作原理:利用背面剔除的方法求出,即假设视点在点光源的位置。

投射阴影:因不透明物体遮挡光线使得场景中位于该物体后面的物体或区域受不到光照照射而形成的阴影

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

若是动态光源此方法就无效了。

6.MipMap是什么?作用?

在三维计算机图形的贴图渲染中有一个常用的技术被称为Mipmapping。为了加快渲染速度和减少图像锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为 MIP map 或者 mipmap。

7.用u3d实现2d游戏,有几种方式?

1.利用引擎自带的GUI

2.把摄像机设为Orthographic,用面片作为2d元素

3.利用第三方插件:NGUI、2dToolkit

组件相关

1.u3d中碰撞器和触发器的区别?

触发器只是碰撞器身上的一个属性,碰撞器是触发器的载体。
碰撞器有碰撞的效果,IsTrigger=false,可以调用OnCollisionEnter/Stay/Exit函数;

触发器没有碰撞效果,IsTrigger=true,可以调用OnTriggerEnter/Stay/Exit函数。

a.如果不想让碰撞检测影响物体移动但是又想检测到碰撞这时用到触发器(Trigger)
b.触发器用来检测一个物件是否经过空间中的某个区域

2.物体发生碰撞的必要条件

物体A必须带有(collider+rigidbody)或者CharacterController,另一个物体也必须至少带有collider

3.CharacterController和Rigidbody的区别

CharacterController自带胶囊碰撞器,里面包含有刚体的属性;
Rigidbody就是刚体,使物体带有刚体的特征。
[CharacterController:角色控制器]
Rigidbody具有完全真实物理的特性,而CharacterController可以说是受限的Rigidbody,具有一定的物理效果但不是完全真实的

4.物体发生碰撞时,有几个阶段,分别对应的函数

1.OnCollisionEnter(进入碰撞) 2.OnCollisionStay (逗留碰撞) 3.OnCollisionExit(当退出碰撞)

4.u3d中,几种施加力的方式,描述出来

rigidbody.AddForce/AddForceAtPosition,都是rigidbody的成员函数

5.什么叫做链条关节

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

6.物体自旋转使用的函数叫什么

transform.Rotate

7.物体绕某点旋转使用函数叫什么

transform.RotateAround

8.u3d提供了一个用于保存读取数据的类,(playerPrefs),请列出保存读取整形数据的函数

PlayerPrefs.SetInt 与 PlayerPrefs.GetInt

9.unity3d提供了几种光源,分别是什么

四种。
平行光:Directional Light 点光源:Point Light
聚光灯:Spot Light 区域光源:Area Light(只用于烘培)

10.unity3d从唤醒到销毁有一段生命周期,请列出系统自己调用的几个重要方法。

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

11.物理更新一般在哪个系统函数里?

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

12.移动相机动作在哪个函数里,为什么在这个函数里。

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

13.当游戏中需要频繁创建一个物体对象时,我们需要怎么做来节省内存。

做一个pool,游戏开始时预先实例化足够的数量,然后用的时候取不用的时候收回

14.一个场景放置多个camera并同时处于活动状态,会发生什么

实际看到的画面由多个camera的画面组成,由depth、Clear Flag、Culling Mask都会影响最终合成效果。

15.简述prefab的用处和环境

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

16.u3d下如何安全的在不同工程迁移asset数据

方法1,可以把assets目录和Library目录一起迁移,

方法2,导出包

方法3,用unity带的assets server功能

28.如何优化内存?

有很多种方式,例如

A、压缩自带类库;

B、将暂时不用的以后还需要使用的物体隐藏起来而不是直接Destroy掉;

C、释放AssetBundle占用的资源;AssetBundle资源包

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

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

29.动态加载资源的方式?(有时候也问区别,具体请百度)

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

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

3.通过AssetDatabase.loadasset :这种方式只在editor范围内有效,游戏运行时没有这个函数,它通常是在开发中调试用的【AssetDatabase 资源数据库】

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

动态资源的存放

有时我需要存放一些自己的文件在磁盘上,例如我想把几个bundle放在初始的安装里, unity有一个streaming asset的概念,用于提供存储接口的访问。我们需要在编辑器建立一个StreamingAssets名字的文件夹,把需要我们放在客户磁盘上的动态文件放在这个文件夹下面,这样安装后,这些文件会放在用户磁盘的指定位置,这个位置可以通过Application.streamingAssetsPath来得到。

30.什么是协同程序?

在主线程运行时同时开启另一段逻辑处理,来协助当前程序的执行。换句话说,开启协程就是开启一个线程。可以用来控制运动、序列以及对象的行为。

31.你用过哪些插件?

一 界面制作 推荐:NGUI

二 2D游戏制作 推荐:2D Toolkit //[?tu:lk?t] 工具包,工具箱

三 可视化编程 推荐:PlayMaker

四 插值插件 推荐:iTween,HOTween

五 路径搜寻 推荐:Simple Path

六 美术及动画制作 推荐:RageSpline,Smooth Moves

七 画面增强 推荐:Bitmap2Material,Strumpy Shader Editor

八 摄像机管理 推荐:Security Camera

九 资源包 推荐:Nature Pack

十、造路插件EasyRoads3D

32使用unity3d实现2d游戏,有几种方式?

1.使用本身的GUI;

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

//[??:θ?’ɡr?f?k] adj. 正字法的,拼字正确的;正射

3.使用2d插件,如:2DToolKit;

33.请说出4种面向对象的设计原则,并分别简述它们的含义。

1) 单一职责原则 (The Single Responsiblity Principle,简称SRP):一个类,最好只做一件事,只有一个引起它的变化.

2) 开放-封闭原则 (The Open-Close Principle,简称OCP):对于扩展是开放的,对于更改是封闭的

3) Liskov 替换原则(The Liskov Substitution Principle,简称LSP):子类必须能够替换其基类,子类可以扩展父类的功能,但不能改变父类原有的功能。

4) 依赖倒置原则(The Dependency Inversion Pricinple,简称DIP):依赖于抽象,高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。

5) 接口隔离原则 (The Interface Segregation Principle,简称ISP):使用多个小的专门的接口,而不要使用一个大的总接口。
6)迪米特法则:又叫最少知道原则,最早是在1987年由美国Northeastern University的Ian Holland提出。
通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。

34.请简述NGUI中Panel和Anchor的作用

  Anchor包含UIAnchor脚本。UIAnchor的功能是把对象锚定在屏幕的边缘(左上,左中,左下,上,中,下,右上,右中,右下),或缩放物体使其匹配屏幕的尺寸

  Panel对象有UIPanel脚本,UIPanel是一个容器,它将包含所有UI小部件,并负责将所包含的部件组合优化,以减少绘制命令的调用。

35.协同程序(Coroutine)

协同程序,即在主程序运行时同时开启另一段逻辑处理,来协同当前程序的执行。换句话说,开启协同程序就是开启一个线程。
原理:协同程序被开启后作为一个线程在运行,而MonoBehaviour也是一个线程,他们成为互不干扰的模块,除非代码中用调用,他们共同作用于同一个对象,只有当对象不可见才能同时终止这两个线程。
使用MonoBehaviour.StartCoroutine方法即可开启一个协同程序。
使用StopCoroutine(string methodName)来终止一个协同程序,使用StopAllCoroutines()来终止所有可以终止的协同程序,但这两个方法都只能终止该MonoBehaviour中的协同程序。
还有一种方法可以终止协同程序,即将协同程序所在GameObject的Active属性设置为false,当再次设置active为ture时,协同程序并不会再开启。
协同程序和多线程的区别?
在多处理器情况下,从概念上来讲多线程程序同时运行多个线程;而协同程序是通过协作来完成,在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只在必要时才会被挂起

36.简述prefab的用处

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

37..Net与Mono的关系?

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

38.请简述如何在不同分辨率下保持UI的一致性

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

39.什么是LightMap?

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

40.Unity和cocos2d的区别

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

cocos2d 开源 并且免费

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

41.C#和C++的区别?

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

42.结构体和类有何区别?

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

43.ref参数和out参数是什么?有什么区别?

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

44.C#的委托是什么?有何用处?

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

45.简述四元数的作用,四元数对欧拉角的优点?

四元数用于表示旋转

相对欧拉角的优点:

1.能进行增量旋转

2.避免万向锁

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

46.GPU的工作原理

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

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

C#相关

1.请简述值类型与引用类型的区别

1.值类型存储在内存栈中,引用类型数据存储在内存堆中,而内存单元中存放的是堆中存放的地址。
2.值类型存取快,引用类型存取慢。
3.值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针和引用。
4.栈的内存是自动释放的,堆内存是.NET中会由GC来自动释放。
5.值类型继承自System.ValueType,引用类型继承自System.Object。

2.C#中所有引用类型的基类是什么?

引用类型的基类是System.Object 值类型的基类是System.ValueType
同时,值类型也隐式继承自System.Object

3.请简述ArrayList和List的主要区别?

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

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

GC回收堆上的内存
避免:
1)减少new产生对象的次数
2)使用公用的对象(静态成员)
3)将String换为StringBuilder

5.请描述Interface与抽象类之间的不同?

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

6.请简述sealed关键字用在类声明时与函数声明时的作用

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

7.请简述private,public,protected,internal的区别

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

private:仅对该类公开

protected:对该类和其派生类公开

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

8.反射的实现原理?

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

导入using System.Reflection;

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

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

foreach (Type type in assembly.GetTypes()) { string t = type.Name; }
4. Type type = assembly.GetType(“程序集.类名”);获取当前类的类型

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

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

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

【原文】Unity3D面试题整合