1、委托是什么,事件是委托吗? 它们有什么区别?
C#中委托通常是指委托类型创建的对象,它用于保存和调用同类型的方法,基于它可以很方便地实现观察者模式。事件不是委托,是委托的更安全实现,也用于保存和调用同类型的方法,安全性体现在:事件对象不支持=操作符,以及只能在定义事件的类中,调用事件内所保存的方法。
2、运行string a = new string(”XYZ”);代码时,涉及几个String对象?
2个,一个是字符串字面量"xyz"所对应的、驻留在一个全局共享的字符串常量池中的实例对象,另一个是通过new String(String)创建并初始化的、内容与"xyz"相同的实例对象。a是string类型的引用变量,非实例对象。
3、值类型与引用类型的区别?
在C#中,基于值类型创建变量时,会创建相应类型的对象,并用变量名进行标识,可直接用于存储数据,其对象内存一般位于栈区。
而基于引用类型创建变量时,其变量为引用变量,并没有创建引用类型的对象。引用类型的变量,需要引向堆区的引用类型对象,通过它将数据存放到堆区对象。
4、脚本生命周期从开始到结束,写出几种系统调用的方法?
Awake、OnEnable、Reset、Start、FixedUpdate、Update、LateUpdate、OnGUI、OnApplicationPause、OnApplicationQuit、OnDisable、OnDestroy
[if !supportLists](1) [endif]Awake(用于在游戏开始之前初始化变量或游戏状态,用Awake来设置脚本间的引用,能用来执行协同程序)
[if !supportLists](2) [endif]Start(函数只在脚本实例被启用时才会执行,如果游戏对象开启了,对象上绑定的脚本实例被禁用了,那么Start函数不会执行。并且Start函数只会在脚本实例首次被开启时才会执行。如果是已经开启过的脚本实例被关闭后再次开启,那么Start函数不会再次执行)
[if !supportLists](3) [endif]Update(正常帧更新,用于更新逻辑。每一帧都执行,ixedUpdate比较适用于物理引擎的计算,因为是跟每帧渲染有关。Update就比较适合做控制。)
[if !supportLists](4) [endif]FixedUpdate(固定帧更新,其中“Fixed Timestep”选项用于设置FixedUpdate()的更新频率,更新频率默认为0.02)
[if !supportLists](5) [endif]LateUpdate:在所有Update函数调用后被调用,和fixedupdate一样都是每一帧都被调用执行,这可用于调整脚本执行顺序,LateUpdate,在每帧Update执行完毕调用,他是在所有update结束后才调用,比较适合用于命令脚本的执行。
[if !supportLists](6) [endif].OnGUI:在渲染和处理GUI事件时调用,每帧执行一次。
[if !supportLists](7) [endif]Reset:(在用户点击检视面板的Reset按钮或者首次添加该组件时被调用。此函数只在编辑模式下被调用。Reset最常用于在检视面板中给定一个默认值。)
[if !supportLists](8) [endif]OnDisable:(当物体被销毁时 OnDisable将被调用,并且可用于任意清理代码。脚本被卸载时,OnDisable将被调用,OnEnable在脚本被载入后调用。注意: OnDisable不能用于协同程序。)
[if !supportLists](9) [endif]OnDestroy:当MonoBehaviour将被销毁时,这个函数被调用。OnDestroy只会在预先已经被激活的游戏物体上被调用。注意:OnDestroy也不能用于协同程序。
[if !supportLists](10) [endif]OnEnable:脚本组件被激活的时候运行,且每次被重新激活,都会运行一次
GameObject的Activity为true,脚本的enable为true时,其先后顺序为:Awake、OnEnable、Start;
GameObject
的Activity为true,脚本的enable为false时,只运行Awake;
GameObject的Activity为false时,以上都不调用,OnDisable()被调用;
Awake --> OnEnable --> Start --> Update --> FixedUpdate -->
LateUpdate -->OnGUI --> OnDisable -->OnDestroy
5、资源动态加载的方式有哪几种?
(1)通过Resources模块的load方法,可以直接load并返回某个类型的Object,前提是要把这个资源放在Resource命名的文件夹下,Unity不关有没有场景引用,都会将其全部打入到安装包中。
(2)通过AssetBundle的形式:即将资源打成 asset bundle 放在服务器或本地磁盘,然后使用www模块get 下来,然后从这个bundle中load某个object。
(3)通过AssetDatabase.loadasset:这种方式只在editor范围内有效,游戏运行时没有这个函数,它通常是在开发中调试用的
6、ArrayList 与List<Int>的区别?
ArrayList是非泛型集合类,不是类型安全的。ArrayList在管控对象时,需要保证其为object类型的子类。在使用对象时,还需要将它们转化为对应的原类型来处理。期间,容易出现类型不匹配的情况。另外,在管控和使用对象时,还可能存在了装箱与拆箱的操作,会带来很大的性能损耗。
List<Int>是泛型集合,不存在装箱与拆箱和类型安全的问题,C#中推荐使用泛型集合。
7、LOD是什么,优缺点。LOD是什么,优缺点?
LOD全称是Level of Detail,也就是细节层级。LOD是一个用于性能优化的方案,它根据物体与摄像机的距离来展示这个物体不同的mesh,从而使得物体较远是使用面数比较少的mesh,而距离近的时候使用面数多的mesh。
缺点是:需要占用更多的内存,而且如果没有调整好距离的话,可能会造成模拟的突变。
8、哪些情况下,Unity3D 中会发生在组件上出现数据丢失的情况?
组件上引用的资源被删除,常出现在:工程间进行数据迁移;在资源视图误删资源。
9、MeshRenderer中有属性.material,以及.sharedMaterial。两者有什么区别?
sharedMaterial 是共用的 Material,称为共享材质。修改共享材质会改变所用使用该材质的物体,并且编辑器中的材质设置也会改变。
material 是独立的 Material,返回分配给渲染器的第一个材质。修改材质仅会改变该物体的材质。如果该材质被其他的渲染器使用,将克隆该材质并用于当前的渲染器。
10、当camera距离一个模型很近,靠近摄像机的mesh出现部分丢失,应该如何优化这种现象。
拉近摄像机的近裁剪面。
11、简述Unity的协同程序,并写出任意一个示例程序。
unity协程是一个能暂停执行,暂停后立即返回,直到中断指令完成后继续执行的函数。它类似一个子线程单独出来处理一些问题,性能开销较小,但是他在一个MonoBehaviour提供的主线程里只能有一个处于运行状态的协程。
12.如何理解消息机制,你用过哪些消息事件系机制?请简单描述一下消息机制的实现方法。(最好用代码或者伪代码设计出来一个简单的消息机制)。
消息机制的主要作用是解耦和。消息的发送者不需要了解接收者的具体情况,完全零耦合。可以基于事件来进行消息的监听,内部用Dictinary进行保存事件和消息一一对应,将委托添加到对应事件的监听中,发送消息时,对Dictinary对应的事件进行调用即可。
13、你觉得在FPS里哪些东西适合使用对象池,请简述一下对象池。
在FPS游戏中,经常被大量创建的同类型对象,包括子弹,敌人,粒子等,都适合使用对象池进行管理。
unity中一些需要频繁创建和销毁的对象,在销毁时会频繁的调用gc,非常占用cpu时,造成性能瓶颈。这时候就需要对象池技术。使用对象池在销毁时并不调用gc,而是仅仅将需要销毁的obj失活,当再次创建同类对象时,在对象池中查找可以使用的对象进行调用。仅仅在需要的时候调用gc进行一次销毁。这样做大大减少了cpu的压力,但是增大了内存的消耗,通常情况这种牺牲是值得的。
14、常见的Unity的优化主要有哪些,着重点是那些?
使用LOD、Mipmap提供渲染速度。注意:Mipmap类似于LOD,但LOD是针对于模型来处理,Mip是针对贴图纹理来处理。
对象池,提高游戏性能;数据缓存层设计,提高资源加载速度;
使用光照探头或 烘培静态光照贴图,提高光照渲染效率;
纹理图集合并,减少DC;
恰当使用Unity提供的静态合并和动态合并方式,减少DC。
在拼接或连接大量字符串时,需使用StringBuilder,减少GC。
15、在Unity中使用线程有什么要注意的?
unity中使用c#的多线程时不能使用修改unity相关函数、属性,使用时Unity会报错提示。当需要进行修改位置,旋转之类的操作时,可以创建一个单例Mono类对象,开启协程。操作需要在Unity主线程中的操作函数时,对该单例类添加一个委托,在单例类协程中持续判断委托。如果存在委托就执行并且清空。
仅能从主线程中访问Unity3D的组件,对象和Unity3D系统调用支持。如果同时你要处理很多事情或者且与Unity的对象互动少,可以用thread,否则使用coroutine。注意:C#中有lock这个关键字,用来确保只有一个线程可以在特定时间内访问特定的对象。
16、使用mipmap有什么好处和坏处?什么情况下使用?
Mipmap,称为多级渐进纹理。为了加快渲染速度和减少纹理锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为Mipmap。常用于:根据摄像机距离模型的远近而调整使用不同质量的贴图。
[if !vml]
[endif]
Mipmap宽高值不一定要相等,但需要为2的n次幂,最低精度为1x1;从原始高精度的Mipmap宽高减半,逐级生成低精度的Mipmap层级;所有低精度层级加起来,会增加1/3存储空间的占用:A、Mipmap贴图文件占用更多硬盘空间,解决方法:使用dds进行压缩存储。B、Mipmap纹理占用更多内存、显存空间。
17、手写除了冒泡外的,你已知的排序算法。
常见:快速排序,堆排序,插入排序等。
18、请简述GC(垃圾回收)产生的原因,并描述何如避免?
当我用new创建一个对象时,当可分配的内存不足GC就会去回收未使用的对象,但是GC的操作是非常复杂的,会占用很多CPU时间,对于移动设备来说频繁的垃圾回收会严重影响性能。
下面的建议可以避免GC频繁操作。
减少用new创建对象的次数,在创建对象时会产生内存碎片,这样会造成碎片内存不法使用
使用公用的对象(静态成员,常量),但是不能乱用,因为静态成员和常量的生命周期是整个应用程序。
在拼接大量字符串时StringBuilder。在使用注意,创建StringBuilder对象时要设置StringBuilder的初始大小如:StringBuilder sb1
=new StringBuilder (size);
使用object pool(对象池)
19、时间复杂度和空间复杂度,是什么?给出冒泡排序和快速排序的时间和空间复杂度
算法的时间复杂度(Time Complexity),用来 衡量算法执行时所需“时间”,它是对 【程序基本操作重复执行的次数与问题规模n的函数f(n)】进行【O()运算】的结果,常记为T(n)
算法的空间复杂度(Space Complexity),是对一个算法在运行过程中【临时额外】占用存储空间大小的量度,常记为 S(n) 。它是 对 【额外空间与问题规模n的函数f(n)】 进行【O()运算】的结果。
时间复杂度空间复杂度
冒泡排序O(n2)O(1)
快速排序O(n2)O(nlog2n)
直接插入O(n2)O(1)
20、有两段代码if(go.CompareTag(“Enemy”)) 和if(go.tag==”Enemy”)有什么区别?
go.CompareTag调用一次内部方法就完成了比较,但go.tag要先花时间调用一次getter来获得字符串,消耗的时间相比CompareTag会更多。建议,使用CompareTag替换所有的tag。
21、已知道List<int> list1=new
List<int>(new int[](1,2,3,4,5)),请问,如果用foreach操作lst1,有什么需要注意的?
使用foreach遍历容集合时,可以得到对象的标识符或引用。但是无法增加、删除,修改,该集合对象所管控的元素。
22、string tmp = "你好,我爱编程!!";,请C#编程实现截出“我爱编程”;
string ret1 = tmp.Substring(3, 4);
//C#中char型是2个字节,一个char变量可以存放一个汉字。
// string类的其他常见方法见 文字课件。
23、写出UGUI中监听事件的几种方式
在脚本代码中,使用代码,添加事件监听,比如:onClick.addListener等;
在脚本组件的检视视图中,手动添加事件监听的对象,并设置回调函数;
在脚本代码中,继承相关事件的接口,实现对事件的监听,比如:IBeginDrag等。
24、四元数的作用,四元数对欧拉角的优点?基于伪代码:给出基于四元数,缓慢旋转到指定朝向(使用Vector3表示)的实现
四元数和欧拉角,均用于表示物体的朝向,在unity中分别使用Quaternion类和Vector3类进行描述和实现。
欧拉角在表示物体朝向时,优点是:容易理解和形象直观,缺点是:在两个欧拉角之间,无法做插值运算;对于一个给定的朝向,表示方式不唯一;有万向节死锁(Gimbal Lock)的现象。
四元数,在表示物体朝向时,优点是:可以避免万向节锁现象,可以提供平滑插值;某些情况下,使用四元数实现旋转,更加高效。缺点是:理解困难,不直观;
实现代码:
Quaternion dstRotation =Quaternion.LookRotation(dstDirection, Vector3.up);
this.transform.rotation =Quaternion.Slerp(transform.rotation, dstRotation, Time.deltaTime * 2.0f);
25、什么是渲染管道 或 渲染管线?
渲染管线是指为了在显示器上,显示出图像而经过的一系列必要操作。渲染管道中的很多步骤,都要将几何物体从一个坐标系中变换到另一个坐标系中去。主要步骤有:本地坐标->视图坐标->背面裁剪->光照->裁剪->投影->视图变换->光栅化。
[if !vml]
[endif]
具体参见《Shader入门精要》。
26、谈谈shader的类型和各自在什么时候使用。通常Shader中是如何将图片变成灰度图。
Shader按管线分类一般分为固定渲染管线与可编程渲染管线。
1、固定渲染管线
这是标准的几何&光照(Transforming&Lighting)管线,功能是固定的,它控制着世界、视、投影变换及固定光照控制和纹理混合。T&L管线可以被渲染状态控制,矩阵,光照和采制参数。功能比较有限。基本所有的显卡都能正常运行。
2、可编程渲染管线
对渲染管线中的顶点运算和像素运算分别进行编程处理,而无须象固定渲染管线那样套用一些固定函数,取代设置参数来控制管线。
27、Unity3d的三种Shader:
1、固定功能着色器(Fixed Function Shader)
固定功能着色器为固定功能渲染管线的具体表现。功能较简单兼容比较老的机器
2、顶点和片段着色器(Vertex and Fragment Shader)
最强大的Shader类型,属于可编程渲染管线, 使用的是CG/HLSL语法。
3、表面着色器(Surface Shade)
Unity3d推崇的Shader类型,使用Unity预制的光照模型来进行光照运算。使用的也是CG/HLSL语法。
图片灰度化:
修改对应Shader中的灰色公式,设置为:Gray = R*0.299 + G*0.587 +
B*0.114,即可实现图片变灰的效果。比如:UGUI中彩色UI变灰色,找到UI-Default.shader,复制,重命名为UI-Gray.shader, 将frag函数修改为如上参数即可。
28、Unity3D Shader分为哪几种,有什么区别?
1、表面着色器,的抽象层次比较高,它可以轻松地以简洁方式实现复杂着色。表面着色器可同时在前向渲染及延迟渲染模式下正常工作。
2、顶点片段着色器,可以非常灵活地实现需要的效果,但是需要编写更多的代码,并且很难与Unity的渲染管线完美集成。
3、固定功能管线着色器,可以作为前两种着色器的备用选择,当硬件无法运行那些酷炫Shader的时,还可以通过固定功能管线着色器来绘制出一些基本的内容。
29、在VR游戏中,前向渲染和延迟渲染应该选择哪一个,为什么?
前向渲染 提供更快的基线和更快的渲染通道,可在 VR 平台拥有更好的性能。前向渲染不仅速度更快,相较于延迟渲染器它还拥有更多抗锯齿选项,带来更为清晰明快的显示效果。
//以下了解
[if !vml]
[endif]
Forward Rendering(正向渲染/前向渲染)是大多数渲染引擎使用的渲染技术。你给显卡提供几何对象,它将几何对象分解成顶点送入顶点着色器,然后把这些顶点数据插值后分别送入片元/像素着色器,然后在它们被送入屏幕前做最终的渲染处理(模板测试,混合等)。
[if !vml]
[endif]
Deferred Rendering(延迟渲染),从这个名字来看就意味着渲染是被延迟的,直到所有几何对象都已经通过渲染管线处理后,在最后才应用着色(通过光照来决定最终的像素颜色)并产生最终的图像。
[if !vml]
[endif]
30、什么是drawcall?叙述下Unity3d中的drawcall合并
在使用unity的时候经常会要求尽量降低Draw call和Batched 的数量。那么Draw call 和Batched 到底指的是什么呢?
Draw Call: Unity生成一帧的画面的处理过程大致过程是:
引擎经过可见性测试,确定摄像机可以看到的物体,然后把这些物体的顶点(包括顶点位置、法线、uv 等),索引(如何组成三角形),变换(物体的位置旋转 缩放 以及摄像机的位置)相关光源,纹理,渲染方式(由材质/Shader决定)等数据准备好,然后通知图形API(或者就简单地看作是通知GPU)开始绘制,GPU基于这些数据经过一些列的运算,在屏幕上画出组成图形的三角形,构成一幅画。
在unity 中每次引擎装备数据并通知GPU的过程为一次Draw Call。
为什么要优化DrawCall?
因为通知给GPU这个工作是由CPU来完成的,完成每一次DrawCall都需要CPU完成很多的内容,因此如果DrawCall很多的话CPU一定是不堪重负。但对于GPU而言,很多的工作都是一样的,也就是说很多的DrawCall是没有意义的,可以理解为很多次的DrawCall都可以合并为一次,这样减轻了CPU的负担,同样也可以通知GPU完成相应的工作。因此减少DrawCall成了优化CPU的第一要务。
Batched: Batched 其实是Draw Call的另外一种称呼。你可以想象成 每一次的Draw Call 是CPU把一个Batched里的数据(物体的顶点数据)传输给GPU,由GPU绘制到屏幕上。因此Batched越多需要传输的数据就越多,产生的Draw Call也会越多,也会消耗更多的性能。
Unity提供了Dynamic Batching和Static
Batching两种方式。
//具体见https://docs.unity3d.com/Manual/DrawCallBatching.html
31、如何优化内存
代码级别优化:
1、连接两个字符串的操作使用StringBuilder.Append来代替string。
2、使用gameObject.CompareTag("XXX")来代替gameObject.tag = xxx。
3、使用ObjectPool对象池来管理对象,避免频繁使用的Instance,Destroy。
//其他补充
//https://blog.csdn.net/wwanrong/article/details/78676275
//https://www.bbsmax.com/R/ke5jG4Xdrl/
//https://www.jianshu.com/p/14b978447135
32、写光照计算中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 称为镜面光指数)
引用类型的基类System.Object
值类型的基类System.ValueType
34.Interface 与抽象类之间的不同
答:抽象类表示该类中可能已经有一些方法的具体定义,但接口就是公公只能定义各个方法的界面,不能具体的实现代码在成员方法中。
类是子类用来继承的,当父类已经有实际功能的方法时该方法在子类中可以不必实现,直接引用父类的方法,子类也可以重写该父类的方法。
实现接口的时候必须要实现接口中所有的方法,不能遗漏任何一个。
35. 请简述 ArrayList 和 List 的主要区别
答: ArrayList存在不安全类型 ‘ ( ArrayList 会把所有插入其中的数据都当做 Object 来处理)
装箱拆箱的操作(费时)List 是接口, ArrayList 是一个实现了该接口的类,可以被实例化。
36.Unity3D 的协程和 C# 线程之间的区别是什么?
多线程程序同时运行多个线程 ,而在任一指定时刻只有一个协程在运行,并且这个正在运行的协同程序只在必要时才被挂起。除主线程之外的线程无法访问 Unity3D 的对象、组件、方法。 Unity3d 没有多线程的概念,不过 unity 也给我们提供了StartCoroutine (协同程序)和 LoadLevelAsync (异步加载关卡)后台加载场景的方法。StartCoroutine 为什么叫协同程序呢,所谓协同,就是当你在 StartCoroutine 的函数体里处理一段代码时,利用 yield 语句等待执行结果,这期间不影响主程序的继续执行,可以协同工作。而LoadLevelAsync 则允许你在后台加载新资源和场景,所以再利用协同,你就可以前台用 loading 条或动画提示玩家游戏未卡死,同时后台协同处理加载的事宜 asynchronous[e ɪˈ s ɪŋ kr ə n ə s] .synchronous 同步。
37. 简述四元数的作用,四元数对欧拉角的优点?
答:四元数用于表示旋转
相对欧拉角的优点: 1 )能进行增量旋转 2 )避免万向锁 3 )给定方位的表达方式有两种,互为负(欧拉角有无数种表达方式)
38. 矩阵相乘的意义及注意点
用于表示线性变换:旋转、缩放、投影、平移、仿射
注意矩阵的蠕变:误差的积累
39. 向量的点乘、叉乘以及归一化的意义?
1 )点乘描述了两个向量的相似程度,结果越大两向量越相似,还可表示投影 2 )叉乘得到的向量垂直于原来的两个向量 3 )标准化向量:用在只关系方向,不关心大小的时候
40.为什么 dynamic font 在 unicode 环境下优于static font
Unicode 是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。
使用动态字体时,Unity 将不会预先生成一个与所有字体的字符纹理。当需要支持亚洲语言或者较大的字体的时候,若使用正常纹理,则字体的纹理将非常大。
41. 为什么 Unity3D 中会发生在组件上出现数据丢失的情况?
答:组件上绑定的对象被删除了
42.如何安全的在不同工程间安全地迁移 asset 数据?三种方法
答:将 Assets 目录和 Library 目录一起迁移
导出包用 unity 自带的 assets Server 功能
43.请描述游戏动画有哪几种,以及其原理。
主要有关节动画、单一网格模型动画 ( 关键帧动画 ) 、骨骼动画。
关节动画把角色分成若干独立部分,一个部分对应一个网格模型,部分的动画连接成一个整体的动画,角色比较灵活 Quake2 中使用了这种动画。
单一网络模型动画由一个完整的网格模型构成,在动画序列的关键帧里记录各个顶点的原位置及其改变量,然后插值运算实现动画效果,角色动画较真实。
骨骼动画,广泛应用的动画方式,集成了以上两个方式的优点,骨骼按角色特点组成一定的层次结构,由关节相连,可做相对运动,皮肤作为单一网格蒙在骨骼之外,决定角色的外观。皮肤网格每一个顶点都会受到骨骼的影响,从而实现完美的动画。(骨骼动画是由关节动画发展而来的,如今基本都使用骨骼动画来实现角色动画)
44.两种阴影判断的方法工作原理
阴影由两部分组成:本影与半影
本影:景物表面上那些没有被光源直接照射的区域(全黑的轮廓分明的区域)
半影:景物表面上那些被某些特定光源直接照射但并非被所有特定光源直接照射的区域(半明半暗区域)
求阴影区域的方法:做两次消隐过程
一次对每个光源进行消隐,求出对于光源而言不可见的区域 L ;
一次对视点的位置进行消隐,求出对于视点而言可见的面S
shadow area= L ∩S
阴影分为两种:自身阴影和投射阴影
自身阴影:因物体自身的遮挡而使光线照射不到它上面的某些可见面
工作原理:利用背面剔除的方法求出,即假设视点在点光源的位置。
投射阴影:因不透明物体遮挡光线使得场景中位于该物体后面的物体或区域受不到光照照射而形成的阴影
工作原理:从光源处向物体的所有可见面投射光线,将这些面投影到场景中得到投影面,再将这些投影面与场景中的其他平面求交得出阴影多边形,保存这些阴影多边形信息,然后再按视点位置对场景进行相应处理得到所要求的视图(利用空间换时间,每次只需依据视点位置进行一次阴影计算即可,省去了一次消隐过程)
若是动态光源此方法就无效了。
45.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几个过程。
46.用u3d实现2d游戏,有几种方式?
1.利用引擎自带的GUI
2.把摄像机设为 Orthographic ,用面片作为 2d 元素
3.利用第三方插件: NGUI 、2dToolkit
47.CharacterController和Rigidbody的区别
Rigidbody 具有完全真实物理的特性,而 CharacterController 可以说是受限的Rigidbody ,具有一定的物理效果但不是完全真实的。
48.u3d中,几种施加力的方式,描述出来
rigidbody.AddForce/AddForceAtPosition,都是 rigidbody 的成员函数
49.unity3d提供了几种光源,分别是什么
平行光:Directional Light
聚光灯:SpotLight
点光源:PointLight
区域光源: Area
Light (只用于烘培)
50.u3d提供了一个用于保存读取数据的类,(playerPrefs),请列出保存读取整形数据的函数
PlayerPrefs.SetInt与PlayerPrefs.GetInt
51.移动相机动作在哪个函数里,为什么在这个函数里。
LateUpdate, ,是在所有 update 结束后才调,比较适合用于命令脚本的执行。官网上例子是摄像机的跟随,都是在所有 update 操作完才跟进摄像机,不然就有可能出现摄像机已经推进了,但是视角里还未有角色的空帧出现。
52.当游戏中需要频繁创建一个物体对象时,我们需要怎么做来节省内存。
做一个 pool ,游戏开始时预先实例化足够的数量,然后用的时候取不用的时候收回
53.一个场景放置多个camera并同时处于活动状态,会发生什么
实际看到的画面由多个camera 的画面组成,由 depth 、 Clear
Flag 、 Culling Mask都会影响最终合成效果。
54.什么叫做链条关节
Hinge Joint ,他可以模拟两个物体间用一根链条连接在一起的情况,能保持两个物体在一个固定距离内部相互移动而不产生作用力,但是达到固定距离后就会产生拉力。(简单说就是弹簧)
55.物体自旋转使用的函数叫什么transform.Rotate
56.物体绕某点旋转使用函数叫什么transform.RotateAround
57.什么是渲染管道?
是指在显示器上为了显示出图像而经过的一系列必要操作。 渲染管道中的很多步骤,都要将几何物体从一个坐标系中变换到另一个坐标系中去。
主要步骤有:
本地坐标 -> 视图坐标 -> 背面裁剪 -> 光照-> 裁剪 -> 投影 -> 视图变换 -> 光栅化。
58.如何优化内存?
1. 压缩自带类库;
2. 将暂时不用的以后还需要使用的物体隐藏起来而不是直接 Destroy 掉;
3. 释放 AssetBundle 占用的资源;
4. 降低模型的片面数,降低模型的骨骼数量,降低贴图的大小;
5. 使用光照贴图,使用多层次细节 (LOD) ,使用着色器 (Shader) ,使用预设(Prefab) 。
59、动态加载资源的方式?
1.Resources.Load();
2.AssetBundle
60.Animation.CrossFade命令作用是:(动画的淡入为其他动画)
61.Application.loadLevel命令为:(加载关卡)
62. 使用原生 GUI 创建一个可以拖动的窗口命令是什么?GUI.DragWindow();
63,在类的构造函数前加上static会报什么错?为什么?
构造函数格式为public+ 类名如果加上 static 会报错(静态构造函数不能有访问修饰符)
原因:静态构造函数不允许访问修饰符,也不接受任何参数;
无论创建多少类型的对象,静态构造函数只执行一次;
运行库创建类实例或者首次访问静态成员之前,运行库调用静态构造函数;
静态构造函数执行先于任何实例级别的构造函数;
显然也就无法使用this 和 base 来调用构造函数。