unity常见面试笔试题

1.基础

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

1.2.获取、增加、删除组件的命令分别是什么
获取:GetComponent
增加:AddComponent
删除:Destroy

1.3.U3D中用于记录节点空间几何信息的组件名称,及其父类名称
答:Transform 父类是 Component

1.4.OnEnable、Awake、Start运行时的发生顺序 哪些可能在同一个对象周期中反复的发生
Awake –>OnEnable->Start,OnEnable在同一周期中可以反复地发生。

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

1.6.unity的摄像机有几种投射方式,区别是什么
有透视和正交,
透视投影:与现实世界观察物体一样, 有近大远小的效果, 这种投影更加真实,所视范围是一个椎体
正交投影:正交投影属于平行投影, 投影的内容不会出现近大远小的效果,所视范围是一个长方体的

1.7.简述刚体的作用
刚体是激活物体物理属性的主要组件。绑定刚体的游戏对象,在unity中将受到物理作用

1.8.继承monoBehavior的脚本有哪几种更新函数,区别是什么
update(), 游戏运行每一帧都会调用的函数,用于游戏正常的更新逻辑
LateUpdate() 延迟更新函数,它是在所有Update结束后才调,比较适合用于命令脚本的执行
FixedUpdate() 固定更新函数,游戏运行的过程中,每一帧的处理时间是不固定的,当我们需要固定间隔时间执行某些代码时,就会用到FixedUpdate()函数

1.9.在场景中放置多个Camera并同时处于活动状态会发生什么
游戏界面可以看到很多摄像机的混合,各个摄像机的画面按照预先设定的层级和位置关系叠加起来

1.10.在物体发生碰撞的整个过程中,有几个阶段,分别列出对应的函数
三个阶段
1.OnCollisionEnter
2.OnCollisionStay
3.OnCollisionExit

1.11.请描述游戏动画有哪几种,以及其原理
主要有关节动画、骨骼动画、单一网格模型动画(关键帧动画)。
关节动画:把角色分成若干独立部分,一个部分对应一个网格模型,部分的动画连接成一个整体的动画,角色比较灵活;
单一网格模型动画由一个完整的网格模型构成,在动画序列的关键帧里记录各个顶点的原位置及其改变量,然后插值运算实现动画效果,角色动画较真实。
骨骼动画,广泛应用的动画方式,骨骼按角色特点组成一定的层次结构,有关节相连,可做相对运动,皮肤作为单一网格蒙在骨骼之外,决定角色的外观;

1.12.碰撞器有哪几种类型:
网格碰撞器,盒子碰撞器,胶囊碰撞器,球型碰撞器,地形碰撞器

1.13.请描述Interface与抽象类之间的不同
声明方法的存在而不去实现它的类被叫做抽像类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽像类,并让它指向具体子类的一个实例。不能有抽像构造函数或抽像静态方法。Abstract 类的子类为它们父类中的所有抽像方法提供实现,否则它们也是抽像类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
接 口(interface)是抽像类的变体。在接口中,所有方法都是抽像的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽像的,没有一个有 程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。 然后,它可以在实现了该接口的类的任何对像上调用接口的方法。由于有抽像类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到 接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。

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

1.15.Unity3d脚本从唤醒到销毁有着一套比较完整的生命周期,请列出系统自带的几个重要的方法。
Awake——>OnEnable–>Start——>Update——>FixedUpdate——>LateUpdate——>OnGUI——>OnDisable——>OnDestroy

1.16.如何销毁一个UnityEngine.Object及其子类
使用Destroy()方法;

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

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

1.19.客户端与服务器交互方式有几种
socket通常也称作”套接字”,实现服务器和客户端之间的物理连接,并进行数据传输,主要有UDP和TCP两个协议。Socket处于网络协议的传输层。
http协议传输的主要有http协议 和基于http协议的Soap协议(web service),常见的方式是 http 的post 和get 请求,web 服务。

1.20.StreamingAssets和Resources的功能异同。
答:相同点:都是Unity3d保留的目录。
不同点:
1、Resources里的内容在打包的时候会加密和压缩。而streamingassets里的资源会直接打包,不做处理。
2、Resource里的内容需要用Resources.Load来加载而Streamingassets则需要用www来加载。Assetbundle文件通常也是放在这个文件夹来进行加载。

1.21.abstract class和interface有什么区别

答: 相同点
1. 都不能被直接实例化,都可以通过继承实现其抽象方法。
2. 都是面向抽象编程的技术基础,实现了诸多的设计模式。
不同点
1. 接口支持多继承;抽象类不能实现多继承。
2. 接口只能定义抽象规则;抽象类既可以定义规则,还可能提供已实现的成员。
3. 接口是一组行为规范;抽象类是一个不完全的类,着重族的概念。
4. 接口只包含方法、属性、索引器、事件的签名,但不能定义字段和包含实现的方法;抽象类可以定义字段、属性、包含有实现的方法。
5. 接口可以作用于值类型和引用类型;抽象类只能作用于引用类型。

1.22.简述ScriptableObject的作用。
答:scriptableobject是Unity3d提供的一种可序列化脚本。通过ScriptableObject.CreateInstance()可以序列化出一个资源文件。多用来存储数据,方便快捷。

1.23.GameObject.Find()和Transform.Find的区别
答;GameObject.Find()是在场景中所有预设中查找。Transform.Find只在子节点中查找。

2.进阶

2.1.优化代码
void Update()
{
Vector3 pos = transform.position;
}

答案:
private Vector3 pos;
void Update()
{
pos=transform.position;
}

2.2.优化代码

for(int i=0;i< myArray.Length;i++)
{}
答案:
length=myArray.Length;
for(int i=0;i< length;i++)
{ }

2.3.优化代码
x/2.0f
答案x*0.5f

2.4.C# String类型比stringBuilder类型的优势是什么
如果是处理字符串的话,用string中的方法每次都需要创建一个新的字符串对象并且分配新的内存地址,而stringBuilder是在原来的内存里对字符串进行修改,所以在字符串处理方面还是建议用stringBuilder这样比较节约内存。但是string 类的方法和功能仍然还是比stringBuilder类要强。

2.5.简述一下对象池,你觉得在FPS游戏里哪些东西适合使用对象池
对象池就存放需要被反复调用资源的一个空间,比如游戏中要常被大量复制的对象,子弹,敌人,以及任何重复出现的对象。

2.6.你怎么样能迅速找到某一个UI控件
答案:分情况处理,这是一个优化策略的题目。首先如果这个控件我在awake的时候能知道,那么我会把它存成一个private变量,代码中使用的时候直接使用即可。如果不行,这个子物体是动态生成的(他可能有或者没有),那尽量使用FindChild,得到之后加以判断。如果不得不全局找一个东西(比如找到角色物体),才会用Find。

2.7.Unity3d与android交互的方式是什么
答:u3d调android 采用AndroidJavaClass 和AndroidJavaObject来实现。
Android调Unity3d 采用UnityPlayer.UnitySendMessage(“Main Camera”,”messgae”,edit.getText().toString());

2.8.Unity3d中如何在编辑器中增加一个自定义menu
答:
1、创建c#脚本,引入unityeditor命名空间
2、实现一个静态函数,在函数上加[menuitem]的属性。
3、脚本放在Editor文件夹下。

2.9.Unity3d中shader主要有几种类型
答:表面着色器,顶点片段着色器,固定管线着色器。

2.10.简述Unity3d动画中avator的用处并举例。
答:在动画中有选择性地启用或禁用特定身体部位。比如一个跑的动画和一个开枪动画。如果要实现跑动中设计就需要使用avator。实现上身播放开枪动画,下身播放跑步动画。

2.11.请简述GC(垃圾回收)产生的原因,并描述如何避免
GC回收堆上的内存
避免:1.减少new产生对象的次数
2.使用公用的对象(静态成员)
3.将String换为StringBuilder

2.12.你对屏幕适配有什么好办法
屏幕适配根本没有完美的解决方案这个可以根据回答判断!

2.13.你对资源加载有什么看法
答案:首先资源加载这个东西,就是老大难,用户一遍遍的吐槽加载的慢,但是谁也不愿意让加载的少导致后边必须加载而变得卡顿。对于比较耗费的加载,属于IO操作,在游戏刚登陆的时候,进行初始化加载。强制加载一些重要模块,比如登陆窗口(用户输入用户名密码的地方)等等。选择性加载一些必要的模块:如果这人需要新手引导,则加载新手引导模块,否则不加载,反之亦然。这些用户一定会用(或者一定不用)的模块,在登陆时候处理好。对于应用模块:比如我打开一个很庞大的UI,这个怎么加载,如果这个模块很吸金,用户用得概率很大,那么必须在登陆时加载,否则那只能用户打开的时候加载了,加载的时候要转圈提示用户。。关于场景加载更加的莫衷一是。既然大家被面到这一步了,相信也不需要我废话了,一个程序有一个程序的活法不是吗

2.14.如何优化内存
有很多种方式,例如
1.压缩自带类库;
2.将暂时不用的以后还需要使用的物体隐藏起来而不是直接Destroy掉;
3.释放AssetBundle占用的资源;
4.降低模型的片面数,降低模型的骨骼数量,降低贴图的大小;
5.使用光照贴图,使用多层次细节(LOD),使用着色器(Shader),使用预设(Prefab)。
6.代码中少产生临时变量
7:http://www.manew.com/thread-111469-1-1.html

2.15.列举减小包体的方法
1. 纹理格式的压缩(重要)
本次减小包体主要改变了纹理的格式:其实是纹理的压缩算法。
主要采用了以下方式减小包体:
a.采用RGB Crunched DXT1,RGBA Crunched DXT5的纹理格式,此压缩方式会比RGB Compressed DXT1和RGBA Crunched DXT5小一半还要多
官方未推荐在android平台上使用, 但是在Oppo机型上测试没有问题,其他机型暂时没有测试,采用 RGB Crunched DXT要求图片为2的n次幂
b.去掉纹理格式的mip选项,mipmap会生成多张小图来避免缩小图片时没必要的GPU采样消耗。但使用mipmap的图片会比不使用的图片多占用约三分之一的外存和内存。
2.模型文件的压缩,
模型文件(玩家模型除外)下仅选择了压缩类型为中度,原来工程关闭了模型压缩选项
压缩前mesh占用为 35.4M 压缩后为 中 25.8 M 高 24.7M
现在包体未压缩的模型: 仅玩家模型
4.声音文件的压缩
声音文件主要压缩要点有两个:
a.改变声音文件的比特率,原工程采用了声音的Persever选项,现在的声音选择了优化选项 更改前声音 18.5M 更改后 11.7M
b.改变声音文件的压缩格式,目前测试采用Vorbis压缩格式声音文件最小
c.暂时没有去查不同文件压缩格式对声音文件的影响(以后补上)

5.场景的压缩(重要,新知识)
场景中静态物体对包体大小的影响
经测试打包时关卡的大小跟场景内静态物体的数量有很大关系,因此当打包时 关卡占用过大时,
减小游戏内静态物体的数量可以减小包体的大小,但是游戏内对静态批处理和Culling等自动化处理都会都是依据static标记进行的,
因此此方法减小包体,会对游戏的帧率有所影响。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平