精华内容
下载资源
问答
  • Unity面试题

    2020-05-19 19:04:39
    1、Unity面试题总结(2020年持续更新。。。) https://blog.csdn.net/ztysmile/article/details/105866253 ①总结: 2、史上最全的Unity面试题(持续更新总结。。。。。。) 包含答案的Unity面试题 ...

    一、目的

    1、

     

    二、参考

    1、Unity面试题总结(2020年持续更新。。。)

    https://blog.csdn.net/ztysmile/article/details/105866253

    ①总结:

     

    2、史上最全的Unity面试题(持续更新总结。。。。。。) 包含答案的Unity面试题

    https://www.cnblogs.com/android-blogs/p/6343336.html

    ①总结:

     

    三、操作

    1、

    展开全文
  • unity面试题

    2020-09-15 19:10:22
    unity面试题 最近在准备面试, 有自己整理的一些面试问到的基础问题, 有一部分是整理了另外一位博主的文章, 具体是谁的我有点忘记了, 文章看心情更新 -------------------------------------------C#------------...

    unity面试题

     

    最近在准备面试, 有自己整理的一些面试问到的基础问题, 有一部分是整理了另外一位博主的文章, 具体是谁的我有点忘记了, 文章看心情更新

    -------------------------------------------C#------------------------------------------------

    值类型与引用类型区别?

    1.值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址。

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

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

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

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

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

    7.值类型变量直接把变量的值保存在堆栈中,引用类型的变量把实际数据的地址保存在堆栈中,而实际数据则保存在堆中。注意,堆和堆栈是两个不同的概念,在内存中的存储位置也不相同,堆一般用于存储可变长度的数据,如字符串类型;而堆栈则用于存储固定长度的数据,如整型类型的数据int(每个int变量占用四个字节)。由数据存储的位置可以得知,当把一个值变量赋给另一个值变量时,会在堆栈中保存两个完全相同的值;而把一个引用变量赋给另一个引用变量,则会在堆栈中保存对同一个堆位置的两个引用,即在堆栈中保存的是同一个堆的地址。在进行数据操作时,对于值类型,由于每个变量都有自己的值,因此对一个变量的操作不会影响到其它变量;对于引用类型的变量,对一个变量的数据进行操作就是对这个变量在堆中的数据进行操作,如果两个引用类型的变量引用同一个对象,实际含义就是它们在堆栈中保存的堆的地址相同,因此对一个变量的操作就会影响到引用同一个对象的另一个变量。

     

    简述对继承的理解?

    一个类继承另一个类 可以使用基类的方法和属性 基类必须加virtual 子类加override

     

    List和ArrayList区别?

    arraylist 不带泛型,数据类型丢失,需要装箱拆箱, list 带泛型,数据类型保存,不需要装箱拆箱

     

    4种访问修饰符的区别?

    private 仅对本类公开

    public 对任何类公开,没有访问限制

    protected 对本类和它的子类公开

    internal 同一个程序集可以访问

    protected 和 internal 同一个程序集内部以及不同程序集但存在继承关系的可以引用

     

    面向对象三大特征?

    继承 提高代码重用性,增强软件可维护性,符合开闭原则

    封装 将数据和行为相结合,增强代码安全性

    多态 重载和重写

     

    Ref和out区别?

    都是通过引用传递参数,和 C 中的指针类似,使用 ref 传递参数,参数必须初始化,使用 out 必须在方法中对其完成初始化,out适合用在需要 return 多个返回值的地方,ref 用在需要被调用的方法修改调用者的引用的时候

     

    接口和抽象类区别?

    接口是对动作的抽象,抽象类是对根源的抽象。

    抽象类不能创建实例,只能作为父类被继承,抽象方法只作声明,不实现,抽象类有构造函数,可以包含普通成员变量,静态方法,只能单继承

    接口也不能创建实例,只能包含方法声明,不能包含常量,字段,构造,析构,静态成员,可以多继承

    一个类可以实现多个接口,但只能继承一个抽象类,

    相同点:派生类必须实现未实现的方法

     

    String和StringBuilder区别?

    string 具有不可变性,每次对 string 对象进行修改其实都是创建另一个 string 类的对象,所以当需要频繁 的对 string对象 修改时建议使用 stringBuilder,stringbuilder 的原理是先在内存中开辟一定大小的内存空间,如果内存不够则会对次内存空间进行扩充而不是重新创建一个对象,不会造成过多的内存浪费

    string 主要用于公用 API ,通用性好,用途广泛,读取性能高,占用内存小,stringbilder 主要用于拼接 string 修改性高,不过现在的编译器已经把 string 的 + 操作优化成 stringbuilder 了,所以一般用 string 就可以了

    string 是不可变的,所以天然线程同步,stringbuilder 可变,非线程同步

     

    简述常用设计原则?

    单一职责:一个对象应该只包含单一的职责,只干一件事,高内聚

    里氏代换原则:所有引用基类的地方能透明的使用子类

    依赖倒转原则:抽象不依赖于细节,细节依赖于抽象

    接口隔离原则:接口不应该太大或太小

    迪米特法则:最少知识原则,低耦合

    合成复用原则:优先使用对象组合,而不是继承来达到复用的目的

    开闭原则:对扩展开放,对修改关闭

     

    简述常用设计模式?

    单例模式:全局唯一,静态不销毁,可以直接访问不需要实例化

    简单工厂模式:由一个工厂对象决定创建哪一个对象

    观察者模式:当一个对象发生变化时会自动通知它的依赖对象 实现事件处理系统

    状态模式:类的行为基于状态改变,需要状态跳转(有限状态机)

    外观模式:隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口

    命令模式:请求以命令的形式包裹在对象中并传给调用对象

    代理模式:一个类代表另一个类的功能,为其他对象提供一种代理以控制对这个对象的访问

     

    List命名空间?

    system.collections.Generic

     

    二叉树的前序中序后续

    前序遍历:先访问根节点,在访问左节点,在访问右节点

    中序遍历:先访问左节点,在访问根节点,在访问右节点

    后序遍历:先访问左节点,在访问右节点,在访问根节点

     

    数组和链表区别?

    链表是链式的存储结构,数组是顺序的存储结构

    数组必须事先定义固定的长度(元素个数),不能适应数据动态的增减的情况,可以根据下标直接存取,在栈中分配空间,自由度小

    链表动态的进行存储分配,可以方便的插入删除数据项,必须根据 next 指针找到下一个元素,在堆中分配空间,自由度大但是申请管理比较麻烦

    如果需要快速访问数据,很少或不插入删除元素就应该用数组,如果需要经常插入和删除元素就需要用链表

     

    软件设计四大特性?

    可维护性 可复用性 可测试性 安全性

     

    什么是MVC?

    模型视图控制器,用一种业务逻辑、数据、界面显示分离的方法组织代码

     

    文件流的3种读写方式?

    BinaryReader  BinaryWriter

    StringReader  StringWriter

    StreamReader  StreamWriter

    TextReader    TextWriter

     

    观察者的设计原则?

    依赖倒转原则(定义对象间的一种一对多的依赖关系)

     

    常用容器类?

    Stack 栈,先进后出

    Queue 队列,先进先出

    List 列表,访问快,修改慢

    ArrayList 类似于List 使用object 会引起装箱拆箱,性能不足

    Dictionary/HashTable 字典/散列表,查询效率高,占内存大

     

    数组和list区别?

    数组在内存中连续存储,索引速度非常快,赋值和修改元素也很简单,但是在数组的两个数据间插入数据很麻烦,而且声明数组时必须指定数组的长度,过长会造成内存浪费,过短会造成数据溢出

    list 在声明时需要指定集合内数据的对象类型,对象的大小是按照其中存储的数据来动态扩充与收缩,声明是不需要指定长度

     

    IO的关键字分别有哪些?分别有什么用?

    Stream  流  File 文件  Path 路径 Directory 文件夹

     

    同步和异步的区别?

    两方同时在线 阻塞 等待回复  异步 相当于发消息 发完就可以执行其他程序

    同步时单线程,阻塞式

    异步时多线程,同时运行多个线程

     

    接口和委托区别?

    接口是约束类的应该具备的功能集合,使类从千变万化的具体逻辑中解脱出来,便于类的管理和扩展,同时又合理解决了类的单继承问题。

    约束方法集合的一个类,可以便捷的使用委托对这个方法集合进行操作。

    在以下情况中使用接口:无法使用继承的场合,完全抽象的场合,多人协作的场合

    在以下情况中使用委托:多用于事件处理中

     

    sealed在类声明和函数声明时的作用?

    sealed修饰累防止其他类被继承, 修饰方法, 防止派生类重写

     

    C#反射

    获取运行是类型信息的方式, 类, 类型,等成员或成员信息

    反射是指陈旭可以访问, 检测和修改他本身状态和行为的一种能力, 程序集包含模块, 而模块包含类型, 类型又包含成员, 反射则提供了封装程序集, 模块和类型的对象.

    可以使用反射动态创建类型的实例

     

    string是值类型还是引用类型?

    引用类型

     

    装箱和拆箱

    装箱是将值类型转化为引用类型(将值类型转化为object)

    拆箱是将引用类型转化为值类型(被装箱的对象才能进行拆箱)

     

     

    list,ArrayList,数组之间的区别,List和ArrayList底层

    List 大小不固定, 内存连续, 可通过下标进行访问, 只能存储一种类型

    ArrayList 大小不固定, 内存连续, 可通过下标进行访问, 可以存储多个类型

    数组 大小固定, 内存连续, 可以通过下标进行访问, 只能存储一种数据类型

    ArrayList底层是数据, ArrayList是实现该接口的类

    List底层是接口

     

    class和struct区别

    class是引用类型, struct是值类型

    class可以继承类和接口, struct只能继承接口

    class默认有无参构造函数, 析构函数, struct没有

    class表示行为, struct存储数值

     

    堆栈区别

    堆存储引用类型, 栈存储值类型

    堆存取慢, 栈存取快

    堆由程序员手动申请释放内存, 栈由系统自动分配

    堆是树状结构, 栈是先进后出结构

     

    虚函数和抽象函数

    虚函数(virtual)有具体实现, 可以选择是否被子类覆盖

    抽象函数(abstract)没有具体实现, 必须让子类实现

     

    override和重载

    override存在于父类和子类之间, 重载存在于父类, 子类, 同类之间

    重载不能重载之后返回值不同的方法名

    重载参数类型, 顺序, 个数至少有一个不同

    override方法名和参数完全相同

     

    工作中用到的队列和栈的功能

     

     

    单例模式的实现

    public class Single

    {

    private static Single _single = null;

    static Single()

    {

    _single = new Single();

    }

    public static Single CreateInstance()

    {

    return _single;

    }

    }

     

    线程和协成

    多线程程序可以运行多个线程, 除主线程外其他线程都无法访问unity对象, 组件, 方法, 多线程用于网络同步

    协成是有unity管理, 运行在主线程上, 就是当你在StartCoroutine的函数体力处理一段代码时, 利用yield语句等待执行结果, 这期间不影响主程序继续工作, 协成多用于处理动画相关, 资源加载相关等

     

    GC是什么,产生的原因,如何避免

    GC是为了避免内存溢出而产生的垃圾回收机制, 回收堆上的内存会产生GC

    减少new对象的次数, 尽量使用单例, 对象池

    unity减少GC的方式, 谨慎使用lambda表达式

     

     

    -----------------------------------------unity----------------------------------------------------------------

    Unity生命周期函数有哪些?

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

     

    Unity光源有几种?

    平行光、聚光灯、点光源、区域光源

     

    Unity动画有几种?

    关节动画

    单一网格模型动画

    骨骼动画

     

    矩阵相乘的意义?

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

     

    自身坐标系和世界坐标系区别?

    localposition 自身坐标系是自身的位置,相对于父级的变换的位置

    position 在世界坐标系 transform 的位置

     

    协程和线程区别?

    多线程程序同时运行多个线程,除主线程之外的线程无法访问 Unity3D 的对象,组件,方法, 线程多用于网络同步

    协程,就是当你在 StartCoroutine 的函数体里处理一段代码时,利用 yield 语句等待执行结果,这期间不影响主程序的继续执行,可以协同工作(迭代器实现的), 协成多用于动画相关以及资源加载相关

     

    异步加载场景的函数?

    using UnityEngine.SceneManagement;//命名空间

    SceneManager.LoadSceneAsync(1);//异步加载场景函数

    SceneManager.LoadScene(0);//加载场景

     

    unity增加删除和获取组件的方法?

    AddComponent 、 Destroy 、 GetComponent

     

    UGUI 、GUI 和 NGUI 区别?

    UGUI 是原生的,NGUI 是第三方插件

    UGUI 渲染层级靠 Hierarchy 位置,NGUI 靠 Depth 修改

    UGUI 不需要添加碰撞 NGUI是射线检测,需要添加碰撞

    UGUI 没有tween NGUI 自带tween 插件

    UGUI 的 Panel 是 Image NGUI 的 Panel 是容器与mask(遮罩)

    UGUI 可以用散图 NGUI 得自己手动打图集,只能用图集里的图片

    UGUI 靠 camera 和 world 做3D NGUI 靠 2DRoot 和 3DRoot 做3D

    NGUI 锚点可以有多个

    GUI 运行时显示,在unity脚本周期 OnGUI 里调用,UGUI 所见即所得,使用了画布和事件系统

     

    Unity 重要的文件夹

    Edior            放编辑器脚本

    Resources        动态加载资源的文件夹

    Plugins          放插件相关

    StreamingAssets  资源文件夹,放 AssetsBundle包

     

    unity两个场景之间互相传值的方法。

    PlayerPrefs 存档 、 DotDestroyOnLoad 不销毁

     

    material和SharedMaterial区别?

    material 修改渲染器材质,shardmaterial 修改工程中的所有使用这个材质的外观

     

    碰撞器和触发器区别?

    collider 碰撞器有碰撞效果,可以调用 OnCollisionStay/Enter/Exit函数

    trigger  触发器没有碰撞效果,可以调用OnTriggerStay/Enter/Exit函数

     

    什么是DrawCall?

    GPU把游戏场景内的的模型贴图光照等信息收集起来发送给GPU计算的过程称为一次drawcall

    1个模型带一个材质单通道shader渲染一次的过程是1个drawcall

     

    .Net和Mono?

    .Net是一个语言平台,Mono为 .Net 提供集成开发环境,集成并实现了 .Net 的编译器、CLR 和基础类库,使得 .Net 既可以运行在 windows 也可以运行于 Linux 、Unix 、 Mac 、 OS 等

     

    点乘和叉乘?

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

    叉乘得到的向量垂直于原来的两个向量

     

    Render,MeshRender和SkinnedMeshRender区别?

    Reader,r 是 MeshRender 和 SkinnedMeshRender 的 父类,负责渲染

    MeshReader,网格渲染器,

    SkinReader,蒙皮网格渲染器,每个模型的骨骼的骨关节,都有一个顶点,骨骼里有骨骼信息,骨骼可以牵引着蒙皮走

     

    Animator的Layer有什么用?

    动画层作为一个具有层级动画编辑概念的工具, 可以用来制作和处理任何类型的动画

     

    什么是跨平台?

    在一个平台上开发的软件或程序可以在其他平台上正常运行显示

     

    Pingpong和Repeat?

    Mathf.Pingpong 让数值 t 在 0 到 length 之间往返 t 值永远不会大于length的值,也永远不会小于0。

    Mathf.Repeat  循环数值 t,0到 length之间。t值永远不会大于length的值也永远不会小于0。

     

    Lerp,Slerp

    Mathf.Lerp  插值 数值 t 在0 到1之间

    Mathf.Slerp  平滑插值 t 在0 到1之间

     

    动态加载资源的3种方式?

    Resources

    WWW (AssetBundles)

    AssetDatabase.loadasset

     

    矩阵相乘?(必要条件)

    第一个矩阵的行数和第二个矩阵的列数必须相同

     

    获取input,横纵轴的方法?

    Horizontal 、 Vertical

     

    LOD和MippingMap?

    Lod: 多层次细节,根据模型所处的环境决定渲染资源分配,提高渲染效率

    优点:可以根据距离动态渲染不同细节模型,少渲染定点数和面片数

    缺点:需要不同模型,加重美工负担,加大游戏容量

    MippingMap:为了加快渲染速度和减少图像锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为 Mippingmap(增加33%内存优化GPU)

     

    序列化和反序列化?

    序列化是将对象的状态信息转换成可以存储或传输的形式的过程

    反序列化是将二进制的数据转化成对象的类或信息

     

    隐藏Inspector字段的方法?

    HideInInspector

    SerializeField

     

    AssetBundle和Resources区别?

    Resources 需要把所有资源全部打入安装包,对版本升级不利

    AssetBundle 把资源打成几个小包,用哪个就load那个

     

    旋转使用矩阵,四元数,欧拉角的优缺点

    旋转矩阵:能增量旋转,不能插值,但比四元数慢,可能发生矩阵蠕变

    欧拉角:不能增量旋转,插值可能遭遇万向锁或其他问题,对给定方位的表达方式有无数种

    四元数:能够增量旋转,能够平滑插值,对给定方位的表达方式有二种互为正负

     

    什么会导致unity内存泄漏

    程序未能释放已经不用的内存导致内存泄漏

     

    状态机和行为树的区别?

    状态机:状态之间需要特定的条件进行跳转,状态节点不需要复用,同一时刻只能有一个状态在执行,状态节点的增加会增加维护成本,做复杂的ai不好维护

    行为树:树形结构,将状态封装成高度模块化的行为,行为之间跳转由父节点决定,节点复用性增加,适合做大型复杂的ai

    状态机(FSM):

    数学连通图

    状态之间需要特定的条件跳转

    节点不容易复用,

    状态节点增加会增加维护成本

    同一时刻只有一个节点在执行

    行为树(BT)

    树形结构

    高度模块化行为,行为之间的跳转由父节点来决定,复用性好

    适合做大型的AI

     

    什么是光照贴图?有什么意义?

    把一片区域原有光照信息制作成静态贴图,减少实时光照,增大内存优化GPU

     

    光照探针?什么意义?

    光照贴图无法对动态物体产生光照效果,增加光照探针使玩家以为实时光照,增加游戏体验

     

    resources加载和AssetBundle加载有什么区别?

     

    --------------------优化------------------------

     

    优化FPS的方法?

    在Edit/Project Setting/Quality中关闭帧数锁定

    Application.targetFrameRate = TargetFrameRate;  设置帧率

     

    unity优化内存?

    模型顶点优化

    UI优化,小图放大显示,图片复用

     

    unity中优化CPU?

    视椎体剔除,遮挡剔除(需要烘焙,相机照不到的地方不烘焙)

    合理安排图片和材质,使用 unity 批处理,动态批处理顶点不超过900个

    合并模型,文理,打包图集

    脚本重构

     

    unity中优化GPU?

    使用光照贴图,动态光探针,反射探针

    Lod、MippingMap(牺牲内存优化GPU)

    减少顶点数量,简化计算复杂度

    压缩图片,适应显存带宽

     

    GC的产生原因和避免?

    GC是为了避免内存溢出而产生的垃圾回收机制

    避免:尽量少new对象,多使用单例对象池

     

    Unity减少GC的方式?

    少用 foreach ,谨慎使用 lambda 表达式

     

    unity中怎么手动GC?

    DestroyImmediate

    Resources.UnLoadUnusedAssets

    System.GC.Collect

     

    mipmap是什么,什么时候不适用

     

    AB打包

    第一种方式

    首先把需要打包的物体设为预设物,把AsststBundle标签名字改为XX.unitry3d

    在编辑器脚本下现找到StreamingAsstesPath路径,

    看是否存在该路径,如果存在,就把该文件夹Delete掉,在重新创建该SteamingAssets文件夹

    使用BuildPipeline.BuildAssetBundles(path,0,BuildTarget.StandaloneWindows64);打包资源

    第二种方式

    引入Luaframework框架,在Packager中添加打包路径,然后点击编辑器脚本生成Wrap文件

     

     

    -----------------Network---------------------

    网络数据的序列化方法有哪些?有什么区别?

    json:轻量级数据交换格式,具有良好的可读和便于快速编写的特性,对象表示为键值对

    protoBuf:google的一种数据交换的格式,独立于语言,平台,是一种二进制的格式

    XML:扩展标记语言,用来标记数据,定义数据类型,允许用户对自己的标记语言进行定义的源语言,格式统一,跨平台和语言

     

    .proto转.cs文件,流程?

    protogen.exe -i: 源文件 -o:输出文件名  .cs

     

    网络5层协议?

    应用层、传输层、网络层、数据链路层、实体层

     

    http,socket,tcp,udp 区别?

    TCP 是面向连接的,tcp 的三次握手最低限度上保证了连接的可靠性

    UDP 不是面向连接的,消息传输不进行收发确认,开销小传输速度快,实时性好

    http协议对应于应用层,是建立在TCP协议之上的一种应用。短连接,连接完自动断开

    Socket相当于调用接口(API),用来调取TCP/IP协议。

    Socket连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

     

    粘包产生原因,如何解决?

    发送方发送多个包到接收方后混做一个包

    原因:发送方收集多个分组一起发送,接收方 tcp 接受和应用层读取速度不一致

    解决:给没个包体添加包头,包头是包体的长度的字节数组

     

    粘包产生原因,如何解决?

    要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包。

    待发送数据大于MSS (最大报文长度),TCP在传输前将进行拆包。

    要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓存区的数据一次发送出去

    接收数据端的应用层没有及时读取接收缓存区中的数据,将发生粘包

    只有TCP才有粘包现象

    粘包是: TCP发送的时候是以流的形式发送的,所以发送的时候把多个包存储在一个连续的缓存中,而接收方不知道每个包的接收边缘,所以估算大小读取,所以会产生粘包和半包

    解决方法:

    先把收到的数据存储到内存流里

    可以先定义一个int类型的lengthCount=4的值,表示每次读取数据的长度

    在while循环中进行读取数据,

    先把读取数据的长度放在内存流的开头,如果数据的长度不足一个int的长度,

    就把剩下的字节全部一次读取,放到内存流的最后

    这样处理就可以通过先读取最前面的数据长度进行判断,避免粘包半包的产生

    首先声明MS内存流把收到的信息存到里面

    int count=4;

    while(MS剩余的字节>count)

    {

      声明一个ms内存流用于存储每次从MS中读取的字节流

      if并把指向当前位置的指针前移相应的字节

      else字符流长度不够,直接一次全部读完放到ms的最后,跳出循环,等待下次读取

    }

    MS的剩余字节判断是用MS的字节长度减MS的指针位置得到的

     

    网络连接方法

    一般使用Socket基于TcpClient进行连接,服务器开启监听,开启异步读取客户端连接

     

    断线重连

    客户端每隔一定时间间隔发送一次心跳包,如果客户端成功发送,但是长时间未接到服务器的

    回应,则认为连接已经中断,如果服务器没有接收到客户端的请求,则可以认为客户端已经离线

    如果服务器可以接收到客户端发来的心跳包,则可以重新连接

    有三种方式:

    1.静默重连:就是断线时用户不知道,可以应付短暂的网络中断

    2.显式重连:在静默重连一定次数,仍然无法连接成功,此时需要弹出提示框,中断游戏流程,告知用户当前网络环境较差,引导用户在网络较好时尝试连接

    3.服务器故障重连.

     

    Lua和C#是怎么进行交互的

    C#调用Lua是通过LuaInterface进行交互的

    Lua调用C#是通过LuaFunction绑定回调

     

    常用的数据结构

    设计模式 单例模式 对象池模式 外观模式 观察者模式 简单工厂模式 开发者模式 状态机模式

     

    简述你熟悉的数据结构

     

    ---------------网络连接底层是怎么实现的

     

    ---------------如何加载AB包

     

    ---------------什么是外观模式

     

    ---------------MVC

     

    ---------------Json和XML的区别

     

    ----------------------------------------------Lua------------------------------------------------

    lua基本数据类型有哪些?

    nil 、number 、string 、boolean 、function 、table 、userdata 、thread

     

    lua中什么是元表?

    lua 的重载机制,两个表不能直接进行函数运算,这时候定义其中一个表的元表,在元表里定义一个指定函数就可以了

     

    lua中.和:有什么区别?

    lua 中对于非面向对象的类,一般用 .  对于面向对象的类用 :

    lua 调用 c# 类调用静态函数或字段时用 .  调用成员函数 :

     

    lua中如何实现面向对象?

    利用元表机制  __index  __newindex 

     

    pairs和ipairs有什么区别?

    pairs 遍历表中的所有键值对,可以遍历所有元素

    ipairs 只会遍历数组,不能返回 nil 否则会跳出遍历

     

    dofile和require有什么区别?

    dofile 引入模块后,再引入一次会刷新,相当于重新引入

    require 引入模块后,再引入一次也不会有任何意义

     

    ulua热更新的原理?

    把控制游戏逻辑的代码写成 lua 脚本,在移动端编写 lua 的解析器,通过解析器运行最新 lua 脚本

    热更新的流程?

    修改 AppConst 的调试模式和更新模式

    生成 wrap 文件

    打资源包 Buil Bundle

    将 StreamAssets 上传资源服务器

    打包时修改 游戏名,公司名,修改屏幕分辨率,横竖屏

     

    cstolua的原理和优点?

    减少了跨语言调用,代码都用lua写

    优点:更好的控制 c# 函数可见性

    更快的回收内存

    可以支持数组参数

    处理二义性

    支持重载函数

    u3d类型位null检测,对于已经为空的 unity object 进行提示

    严格区分枚举类型和 int 值

    支持导出模板类

     

    pureMVC框架的结构?

    MVC(模型、视图、控制器)

     

    pbc的使用流程?

    protoc.exe -o 目标文件 源文件

     

    ulua中如何优化?

    尽量减少 c# 调用 lua 的次数

     

    简述热更新机制

     

    ---------------------------------------shader--------------------------------------------------------

    什么是渲染管线?

    也叫渲染流水线,是显示芯片内部处理图形信号相互独立的并行处理单元。

    应用阶段: cpu收集场景信息,将计算好的数据(顶点坐标,法向量,纹理坐标,纹理)发给gpu

    几何阶段:顶点坐标变换,光照,裁剪,投影以及屏幕映射 "变换三维顶点坐标和光照计算"

    光栅化阶段:将连续的数据转化成离散的数据,这里光栅阶段是指矢量图形转化成像素点的过程

    将数据3D场景转换成2D图像,并在屏幕上显示出来的总过程

     

    shader中的数值类型有哪些?

    float 32位浮点数

    half 16位浮点数

    int 32位整型数

    fixed 11比特 [-2,2]  精度1/256

    bool  布尔数据

    string  字符串

    sampler  纹理对象的句柄 

     

    Lambert和BlinnPong的计算公式?

    漫反射 Lambert :fixed diffuse = max(0 ,dot(normal,lightDir))

    漫反射遮蔽(半Lambert):fixed diffuse = max(0 ,dot(normal,lightDir))*0.5+0.5

    高光 phong :Half3 reflectDir = normalize(reflect(-lightDir,normal));                   

    Float spec = max(0,dot(reflectDir,viewDir));                               

    Float specValue = pow(spec,_Power);

    BlinnPhong 高光:Half3 halfDir = normalize(lightDir + viewDir));                           

    Float spec = max(0,dot(normal,halfDir)); 

    Float  specValue = pow(spec,_Power);

     

    shaderLab的种类?分别什么区别?

    固定管线(已弃用):

    为了兼容老式显卡,都是顶点光照,特征是里面出现了形如下面Material块、没有CGPROGRAM和ENDCG块。

    顶点和片元着色器 Vertex & Fragment Shader

    :功能最强大,最自由的形态,特征是在Pass里出现CGPROGRAM和ENDCG块,编译指令#pragma

    #pragma fragment name

    #pragma target name

    #pragma only_renderers name name ... 

    #pragma exclude_renderers name name...

    表皮着色器(SurfaceShader):可以认为是一个光照shader的语法糖,手游不建议使用

    特征是在SubShader里出现CGPROGRAM和ENDCG块。(而不是出现在Pass里。因为SurfaceShader自己会编译成多个Pass。)

     

    顶点函数中常用哪些语义?分别代表什么含义?

    POSITION        顶点坐标

    TANGENT        切线

    Normal          法线

    TEXCOORD0 ~ n  纹理坐标

    COLOR          顶点颜色

     

    AlphaBlend代表什么阶段?有哪些常见混合方式?

    用于两个透明物体的叠加显示效果,Blending 就是处理透明度的,处理光栅化的最后阶段显示在屏幕上的颜色

    常见混合方式:

    Blend zero one :仅显示目标的RGB 无透明通道处理(alpha为1)

    Blend one zero :仅显示源的RGB 无透明通道处理(alpha为1)

    Blend one one :目标和源的RGB值相加,无透明通道处理(alpha为1)

    Blend ScrAlpha zero :仅显示源的颜色(处理透明通道)

    Blend ScrAlpha OneMinusDstAlpha :源RGB * alpha + 目标RGB * (1 - alpha)

     

    ShaderForge中Fresnel节点代表什么含义?

    边缘亮显的效果

     

    RenderType的Opaque和Transparent有什么区别?

    渲染标签类型 Opaque 是不透明的 , Transparent 是透明的

     

    RenderQueue中有哪些参数?

     

    shader中Fallback什么意思?

    在运行平台硬件不支持该shader的情况下,选择替代shader。

     

     

     

     

     

    展开全文
  • Unity面试题(包含答案)

    万次阅读 多人点赞 2018-09-13 09:48:19
    这个是我刚刚整理出的Unity面试题,为了帮助大家面试,同时帮助大家更好地复习Unity知识点,如果大家发现有什么错误,(包括错别字和知识点),或者发现哪里描述的不清晰,请在下面留言,我会重新更新,希望大家共同...

    这个是我刚刚整理出的Unity面试题,为了帮助大家面试,同时帮助大家更好地复习Unity知识点,如果大家发现有什么错误,(包括错别字和知识点),或者发现哪里描述的不清晰,请在下面留言,我会重新更新,希望大家共同来帮助开发者

    一:什么是协同程序?

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

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

    碰撞器是触发器的载体,而触发器只是碰撞器身上的一个属性。当Is Trigger=false时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果,可以调用OnCollisionEnter/Stay/Exit函数;当Is Trigger=true时,碰撞器被物理引擎所忽略,没有碰撞效果,可以调用OnTriggerEnter/Stay/Exit函数。如果既要检测到物体的接触又不想让碰撞检测影响物体移动或要检测一个物件是否经过空间中的某个区域这时就可以用到触发器

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

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

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

    ArrayList存在不安全类型(ArrayList会把所有插入其中的数据都当做Object来处理),装箱拆箱的操作(费时),List是泛型类,功能跟ArrayList相似,但不存在ArrayList所说的问题。
    五:如何安全的在不同工程间安全地迁移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提供了几种光源,分别是什么

    四种。

    平行光:Directional Light

    点光源:Point Light

    聚光灯:Spot Light

    区域光源:Area Light

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

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

    十:CharacterController和Rigidbody的区别

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

    十一:简述prefab的用处

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

    十二:请简述sealed关键字用在类声明时与函数声明时的作用

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

    十三:请简述private,public,protected,internal的区别

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

    private:仅对该类公开

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

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

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

    使用本身的GUI,在Unity4.6以后出现的UGUI
    2.把摄像机的Projection(投影)值调为Orthographic(正交投影),不考虑z轴;

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

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

    三个阶段,1.OnCollisionEnter 2.OnCollisionStay 3.OnCollisionExit

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

    rigidbody.AddForce/AddForceAtPosition,都在rigidbody系列函数中。大家可以自己去查看一下rigidbody的API

    十七:什么叫做链条关节?

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

    十八:物体自身旋转使用的函数?

    Transform.Rotate()

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

    PlayerPrefs.SetInt() PlayerPrefs.GetInt()

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

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

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

    FixedUpdate,固定时间间隔执行 可以在edit->project setting->time设置 update 是在渲染帧执行,和Update不同的是FixedUpdate是渲染帧执行,如果你的渲染效率低下的时候FixedUpdate调用次数就会跟着下降。FixedUpdate比较适用于物理引擎的计算,因为是跟每帧渲染有关。Update就比较适合做控制。

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

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

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

    使用Destroy()方法;

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

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

    二十五:LOD是什么,优缺点是什么?

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

    二十六:MipMap是什么,作用?

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

    二十七:请描述Interface与抽象类之间的不同

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

    二十八:.Net与Mono的关系?

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

    二十九:简述Unity3D支持的作为脚本的语言的名称

    Unity的脚本语言基于Mono的.Net平台上运行,可以使用.NET库,这也为XML、数据库、正则表达式等问题提供了很好的解决方案。Unity里的脚本都会经过编译,他们的运行速度也很快。这三种语言实际上的功能和运行速度是一样的,区别主要体现在语言特性上。JavaScript、 C#、Boo

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

    Transform 父类是 Component

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

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

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

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

    三十二:为何大家都在移动设备上寻求U3D原生GUI的替代方案

    不美观,OnGUI很耗费时间,效率不高,使用不方便

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

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

    三十四:什么是LightMap?

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

    三十五:Unity和cocos2d的区别

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

    cocos2d 开源 并且免费

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

    三十六:C#和C++的区别?

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

    三十七:结构体和类有何区别?

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

    三十八:ref参数和out参数是什么?有什么区别?

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

    三十九:C#的委托是什么?有何用处?

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

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

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

    四十一:射线检测碰撞物的原理是?

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

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

    剪裁平面 。从相机到开始渲染和停止渲染之间的距离。

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

    void Awake() { DontDestroyOnLoad(transform.gameObject); }
    四十四:请简述GC(垃圾回收)产生的原因,并描述如何避免?

    GC回收堆上的内存

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

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

    3.将String换为StringBuilder

    四十五:反射的实现原理?

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

    导入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,方法参数);

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

    四元数用于表示旋转

    相对欧拉角的优点:

    1.能进行增量旋转

    2.避免万向锁

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

    四十七:移动相机动作在哪个函数里,为什么在这个函数里?

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

    四十八: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图形的生成,将图形映射到相应的像素点上,对每个像素进行计算确定最终颜色并完成输出。

    四十九:什么是渲染管道?

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

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

    五十:如何优化内存?

    有很多种方式,例如

    1.压缩自带类库;

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

    3.释放AssetBundle占用的资源;

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

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

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

    五十一:动态加载资源的方式?他们之间的区别

    1.Resources.Load();

    2.AssetBundle

    区别参考

    五十二:请描述游戏动画有哪几种,以及其原理?

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

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

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

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

    五十三:alpha blend工作原理

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

    五十四:写出光照计算中的diffuse的计算公式

    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 space到homogeneous space(齐次空间)的变换过程,homogeneous space即projection space的下一个space。在这其间共有world transformation, view transformation和projection transformation及lighting几个过程。

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

    string a = new string(“abc”); a = (a.ToUpper() + “123”).Substring(0, 2);
    在C#中第一行是会报错的(Java中倒是可行)。

    应该这样初始化:

    string b = new string(new char[]{‘a’,’b’,’c’});
    答案为:5个临时对象

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

    List ls = new List(new int[] { 1, 2, 3, 4, 5 }); foreach (int item in ls) { Console.WriteLine(item * item); ls.Remove(item); }
    产生运行时错误,在 ls.Remove(item)这行,因为foreach是只读的。不能一边遍历一边修改。

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

    仅能从主线程中访问Unity3D的组件,对象和Unity3D系统调用

    支持:如果同时你要处理很多事情或者与Unity的对象互动小可以用thread,否则使用coroutine。

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

    六十:Unity3D的协程和C#线程之间的区别是什么?

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

    Unity3d没有多线程的概念,不过unity也给我们提供了StartCoroutine(协同程序)和LoadLevelAsync(异步加载关卡)后台加载场景的方法。 StartCoroutine为什么叫协同程序呢,所谓协同,就是当你在StartCoroutine的函数体里处理一段代码时,利用yield语句等待执行结果,这期间不影响主程序的继续执行,可以协同工作。

    六十一:矩阵相乘的意义及注意点

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

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

    六十二:为什么dynamic font在unicode环境下优于static font

    Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。

    使用动态字体时,Unity将不会预先生成一个与所有字体的字符纹理。当需要支持亚洲语言或者较大的字体的时候,若使用正常纹理,则字体的纹理将非常大。

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

    穿透(碰撞检测失败)

    六十四:请简述OnBecameVisible及OnBecameInvisible的发生时机,以及这一对回调函数的意义?

    当物体是否可见切换之时。可以用于只需要在物体可见时才进行的计算。

    六十五:什么叫动态合批?跟静态合批有什么区别?

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

    区别:动态批处理一切都是自动的,不需要做任何操作,而且物体是可以移动的,但是限制很多。静态批处理:自由度很高,限制很少,缺点可能会占用更多的内存,而且经过静态批处理后的所有物体都不可以再移动了。

    参考

    六十六:简述StringBuilder和String的区别?

    String是字符串常量。

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

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

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

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

    六十七:Unity3D Shader分哪几种,有什么区别?

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

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

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

    六十八:已知strcpy函数的原型是:char * strcpy(char * strDest,const char * strSrc); 1.不调用库函数,实现strcpy函数。2.解释为什么要返回char *

    char * strcpy(char * strDest,const char * strSrc)
    {
    if ((strDestNULL)||(strSrcNULL))
    throw “Invalid argument(s)”;
    char * strDestCopy=strDest;
    while ((*strDest++=*strSrc++)!=’\0’);
    return strDestCopy;
    }
    六十九:C#中四种访问修饰符是哪些?各有什么区别?

    1.属性修饰符 2.存取修饰符 3.类修饰符 4.成员修饰符。

    属性修饰符:

    Serializable:按值将对象封送到远程服务器。

    STATread:是单线程套间的意思,是一种线程模型。

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

    存取修饰符:

    public:存取不受限制。

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

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

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

    类修饰符:

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

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

    成员修饰符:

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

    sealed:密封方法。可以防止在派生类中对该方法的override(重载)。不是类的每个成员方法都可以作为密封方法密封方法,必须对基类的虚方法进行重载,提供具体的实现方法。所以,在方法的声明中,sealed修饰符总是和override修饰符同时使用。

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

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

    event:声明一个事件。

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

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

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

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

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

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

    七十:Heap与Stack有何区别?

    1.heap是堆,stack是栈。

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

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

    七十一:值类型和引用类型有何区别?

    1.值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址。

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

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

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

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

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

    七十二:请写出求斐波那契数列任意一位的值得算法

    递归实现:

    int Fib1(int index)
    {
    if(index<1)
    {
    return -1;
    }
    if(index1|| index2)
    {
    return 1;
    }
    return Fib1(index-1)+Fib1(index-2);
    }
    迭代实现:

    int Fib5(int index)
    {
    if(index<1)
    {
    return -1;
    }
    int a1 - 1, a2 = 1, a3 = 1;
    for(int i = 0; i < index - 2; i++)
    {
    a3=a1+a2;
    a1=a2;
    a2=a3;
    }
    return a3;
    }
    参看更多实现方法

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

    function Start() {
    // 协同程序WaitAndPrint在Start函数内执行,可以视同于它与Start函数同步执行.
    StartCoroutine(WaitAndPrint(2.0));
    print (“Before WaitAndPrint Finishes ” + Time.time );
    }
    function WaitAndPrint (waitTime : float) {
    // 暂停执行waitTime秒
    yield WaitForSeconds (waitTime);
    print (“WaitAndPrint “+ Time.time );
    }

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

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

    七十四:什么是里氏代换元则?

    里氏替换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。通俗点:就是子类对象可以赋值给基类对象,基类对象不能赋值给子类对象

    参考

    七十五:Mock和Stub有何区别?

    Mock与Stub的区别:Mock:关注行为验证。细粒度的测试,即代码的逻辑,多数情况下用于单元测试。Stub:关注状态验证。粗粒度的测试,在某个依赖系统不存在或者还没实现或者难以测试的情况下使用,例如访问文件系统,数据库连接,远程协议等。

    七十六:概述序列化:

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

    七十七:堆和栈的区别?

    栈通常保存着我们代码执行的步骤,如在代码段1中 AddFive()方法,int pValue变量,int result变量等等。而堆上存放的则多是对象,数据等。我们可以把栈想象成一个接着一个叠放在一起的盒子。当我们使用的时候,每次从最顶部取走一个盒子。栈也是如此,当一个方法(或类型)被调用完成的时候,就从栈顶取走,接着下一个。堆则不然,像是一个仓库,储存着我们使用的各种对象等信息,跟栈不同的是他们被调用完毕不会立即被清理掉。

    七十八:概述c#中代理和事件?

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

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

    七十九:客户端与服务器交互方式有几种?

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

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

    八十:Unity和Android与iOS如何交互?

    Unity可以到处Android和iOS的工程,然后通过安卓或者iOS的类去给Unity发消息,调用Unity中的方法

    八十一:如何在Unity3D中查看场景的面试,顶点数和Draw Call数?如何降低Draw Call数?

    在Game视图右上角点击Stats。降低Draw Call 的技术是Draw Call Batching

    这个在5.0以后在window-》Profiler下面,快捷键是cmd + 7(ctl + 7

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

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

    八十三:UNITY3d在移动设备上的一些优化资源的方法

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

    2.顶点数对渲染无论是cpu还是gpu都是压力最大的贡献者,降低顶点数到8万以下,fps稳定到了30帧左右

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

    粒子系统是cpu上的大头

    4.剪裁粒子系统

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

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

    animator也是一个效率奇差的地方

    7.把不需要跟骨骼动画和动作过渡的地方全部使用animation,控制骨骼数量在30根以下

    8.animator出视野不更新

    9.删除无意义的animator

    10.animator的初始化很耗时(粒子上能不能尽量不用animator)

    11.除主角外都不要跟骨骼运动apply root motion

    12.绝对禁止掉那些不带刚体带包围盒的物体(static collider )运动

    NUGI的代码效率很差,基本上runtime的时候对cpu的贡献和render不相上下

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

    14去掉法线计算

    15不要每帧计算viewsize 和windowsize

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

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

    18.尽量减少smooth group

    19.给美术定一个严格的经过科学验证的美术标准,并在U3D里面配以相应的检查工具

    八十四:四元数有什么作用?

    对旋转角度进行计算时用到四元数

    八十五:将Camera组件的ClearFlags选项选成Depth only是什么意思?有何用处?

    如果把摄像机的ClearFlags勾选为Deapth Only,那么摄像机就会只渲染看得见的对象,把背景会完全透明,这种情况一般用在两个摄像机以上的场景中

    八十六:在编辑场景时将GameObject设置为Static有何作用?

    设置游戏对象为Static时,这些部分被静态物体挡住而不可见时,将会剔除(或禁用)网格对象。因此,在你的场景中的所有不会动的物体都应该标记为Static。

    八十七:有A和B两组物体,有什么办法能够保证A组物体永远比B组物体先渲染?

    把A组物体的渲染对列大于B物体的渲染队列,通过shader里面的渲染队列来渲染

    八十八:将图片的TextureType选项分别选为““Texture”和“Sprite”有什么区别

    Sprite作为UI精灵使用,Texture作用模型贴图使用。Sprite需要2的整次幂,打包图片省资源

    八十九:问一个Terrain,分别贴3张,4张,5张地表贴图,渲染速度有什么区别?为什么?

    没有区别,因为不管几张贴图只渲染一次。

    九十:什么是DrawCall?DrawCall高了又什么影响?如何降低DrawCall?

    Unity中,每次引擎准备数据并通知GPU的过程称为一次Draw Call。DrawCall越高对显卡的消耗就越大。降低DrawCall的方法:

    Dynamic Batching

    Static Batching

    高级特性Shader降级为统一的低级特性的Shader。

    九十一:实时点光源的优缺点是什么?

    可以有cookies – 带有 alpha通道的立方图(Cubemap )纹理。点光源是最耗费资源的。

    九十二:Unity的Shader中,Blend SrcAlpha OneMinusSrcAlpha这句话是什么意思?

    作用就是Alpha混合。公式:最终颜色 = 源颜色 x 源透明值 + 目标颜色 x(1 - 源透明值)

    九十三:简述水面倒影的渲染原理

    原理就是对水面的贴图纹理进行扰动,以产生波光玲玲的效果。用shader可以通过GPU在像素级别作扰动,效果细腻,需要的顶点少,速度快

    九十四:简述NGUI中Grid和Table的作用?

    对Grid和Table下的子物体进行排序和定位

    九十五:请简述NGUI中Panel和Anchor的作用

    只要提供一个half-pixel偏移量,它可以让一个控件的位置在Windows系统上精确的显示出来(只有这个Anchor的子控件会受到影响)

    如果挂载到一个对象上,那么他可以将这个对象依附到屏幕的角落或者边缘

    3.UIPanel用来收集和管理它下面所有widget的组件。通过widget的geometry创建实际的draw call。没有panel所有东西都不能够被渲染出来,你可以把UIPanel当做Renderer

    九十六:能用foreach遍历访问的对象需要实现接口或声明___方法的类型

    IEnumerable;GetEnumerator

    展开全文
  • Unity 面试题

    2017-07-28 17:49:52
    在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,协程很像多线程,但是不是多线程,Unity的协程实在每帧结束之后去检测yield的条件是否满足。 二:Unity3d中的碰撞器和触发器的区别? 碰撞器...

    一:什么是协同程序?

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

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

    碰撞器是触发器的载体,而触发器只是碰撞器身上的一个属性。当Is Trigger=false时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果,可以调用OnCollisionEnter\/Stay\/Exit函数;当Is Trigger=true时,碰撞器被物理引擎所忽略,没有碰撞效果,可以调用OnTriggerEnter\/Stay\/Exit函数。如果既要检测到物体的接触又不想让碰撞检测影响物体移动或要检测一个物件是否经过空间中的某个区域这时就可以用到触发器

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

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

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

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

    五:如何安全的在不同工程间安全地迁移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提供了几种光源,分别是什么

    四种。

    平行光:Directional Light

    点光源:Point Light

    聚光灯:Spot Light

    区域光源:Area Light

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

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

    十:CharacterController和Rigidbody的区别

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

    十一:简述prefab的用处

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

    十二:请简述sealed关键字用在类声明时与函数声明时的作用

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

    十三:请简述private,public,protected,internal的区别

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

    private:仅对该类公开

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

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

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

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

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

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

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

    三个阶段,1.OnCollisionEnter 2.OnCollisionStay 3.OnCollisionExit

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

    rigidbody.AddForce\/AddForceAtPosition,都在rigidbody系列函数中。大家可以自己去查看一下rigidbody的API

    十七:什么叫做链条关节?

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

    十八:物体自身旋转使用的函数?

    Transform.Rotate()

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

    PlayerPrefs.SetInt() PlayerPrefs.GetInt()

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

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

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

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

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

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

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

    使用Destroy()方法;

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

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

    二十五:LOD是什么,优缺点是什么?

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

    二十六:MipMap是什么,作用?

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

    二十七:请描述Interface与抽象类之间的不同

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

    二十八:.Net与Mono的关系?

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

    二十九:简述Unity3D支持的作为脚本的语言的名称

    Unity的脚本语言基于Mono的.Net平台上运行,可以使用.NET库,这也为XML、数据库、正则表达式等问题提供了很好的解决方案。Unity里的脚本都会经过编译,他们的运行速度也很快。这三种语言实际上的功能和运行速度是一样的,区别主要体现在语言特性上。JavaScript、 C#、Boo

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

    Transform 父类是 Component

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

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

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

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

    三十二:为何大家都在移动设备上寻求U3D原生GUI的替代方案

    不美观,OnGUI很耗费时间,效率不高,使用不方便

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

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

    三十四:什么是LightMap?

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

    三十五:Unity和cocos2d的区别

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

    cocos2d 开源 并且免费

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

    三十六:C#和C++的区别?

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

    三十七:结构体和类有何区别?

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

    三十八:ref参数和out参数是什么?有什么区别?

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

    三十九:C#的委托是什么?有何用处?

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

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

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

    四十一:射线检测碰撞物的原理是?

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

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

    剪裁平面 。从相机到开始渲染和停止渲染之间的距离。

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

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

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

    GC回收堆上的内存

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

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

    3.将String换为StringBuilder

    四十五:反射的实现原理?

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

    下面是实现步骤:

    导入using System.Reflection;

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

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

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

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

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

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

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

    四元数用于表示旋转

    相对欧拉角的优点:

    1.能进行增量旋转

    2.避免万向锁

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

    四十七:移动相机动作在哪个函数里,为什么在这个函数里?

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

    四十八: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图形的生成,将图形映射到相应的像素点上,对每个像素进行计算确定最终颜色并完成输出。

    四十九:什么是渲染管道?

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

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

    五十:如何优化内存?

    有很多种方式,例如

    1.压缩自带类库;

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

    3.释放AssetBundle占用的资源;

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

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

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

    五十一:动态加载资源的方式?他们之间的区别

    1.Resources.Load();

    2.AssetBundle

    区别参考

    五十二:请描述游戏动画有哪几种,以及其原理?

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

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

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

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

    五十三:alpha blend工作原理

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

    五十四:写出光照计算中的diffuse的计算公式

    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 space到homogeneous space(齐次空间)的变换过程,homogeneous space即projection space的下一个space。在这其间共有world transformation, view transformation和projection transformation及lighting几个过程。

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

    string a = new string(“abc”); a = (a.ToUpper() + “123”).Substring(0, 2); 在C#中第一行是会报错的(Java中倒是可行)。

    应该这样初始化:

    string b = new string(new char[]{‘a’,’b’,’c’}); 答案为:5个临时对象

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

    List ls = new List(new int[] { 1, 2, 3, 4, 5 }); foreach (int item in ls) { Console.WriteLine(item * item); ls.Remove(item); } 产生运行时错误,在 ls.Remove(item)这行,因为foreach是只读的。不能一边遍历一边修改。

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

    仅能从主线程中访问Unity3D的组件,对象和Unity3D系统调用

    支持:如果同时你要处理很多事情或者与Unity的对象互动小可以用thread,否则使用coroutine。

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

    六十:Unity3D的协程和C#线程之间的区别是什么?

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

    Unity3d没有多线程的概念,不过unity也给我们提供了StartCoroutine(协同程序)和LoadLevelAsync(异步加载关卡)后台加载场景的方法。 StartCoroutine为什么叫协同程序呢,所谓协同,就是当你在StartCoroutine的函数体里处理一段代码时,利用yield语句等待执行结果,这期间不影响主程序的继续执行,可以协同工作。

    六十一:矩阵相乘的意义及注意点

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

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

    六十二:为什么dynamic font在unicode环境下优于static font

    Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。

    使用动态字体时,Unity将不会预先生成一个与所有字体的字符纹理。当需要支持亚洲语言或者较大的字体的时候,若使用正常纹理,则字体的纹理将非常大。

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

    穿透(碰撞检测失败)

    六十四:请简述OnBecameVisible及OnBecameInvisible的发生时机,以及这一对回调函数的意义?

    当物体是否可见切换之时。可以用于只需要在物体可见时才进行的计算。

    六十五:什么叫动态合批?跟静态合批有什么区别?

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

    区别:动态批处理一切都是自动的,不需要做任何操作,而且物体是可以移动的,但是限制很多。静态批处理:自由度很高,限制很少,缺点可能会占用更多的内存,而且经过静态批处理后的所有物体都不可以再移动了。

    参考

    六十六:简述StringBuilder和String的区别?

    String是字符串常量。

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

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

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

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

    六十七:Unity3D Shader分哪几种,有什么区别?

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

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

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

    六十八:已知strcpy函数的原型是:char * strcpy(char * strDest,const char * strSrc);

    1.不调用库函数,实现strcpy函数。

    2.解释为什么要返回char *

    char * strcpy(char * strDest,const char * strSrc)
    {
    if ((strDest==NULL)||(strSrc==NULL))
    throw “Invalid argument(s)”;
    char * strDestCopy=strDest;
    while ((*strDest++=*strSrc++)!=’\0’);
    return strDestCopy;
    }
    

    六十九:C#中四种访问修饰符是哪些?各有什么区别?

    1.属性修饰符 2.存取修饰符 3.类修饰符 4.成员修饰符。

    属性修饰符:

    Serializable:按值将对象封送到远程服务器。

    STATread:是单线程套间的意思,是一种线程模型。

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

    存取修饰符:

    public:存取不受限制。

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

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

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

    类修饰符:

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

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

    成员修饰符:

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

    sealed:密封方法。可以防止在派生类中对该方法的override(重载)。不是类的每个成员方法都可以作为密封方法密封方法,必须对基类的虚方法进行重载,提供具体的实现方法。所以,在方法的声明中,sealed修饰符总是和override修饰符同时使用。

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

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

    event:声明一个事件。

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

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

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

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

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

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

    七十:Heap与Stack有何区别?

    1.heap是堆,stack是栈。

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

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

    七十一:值类型和引用类型有何区别?

    1.值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址。

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

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

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

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

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

    七十二:请写出求斐波那契数列任意一位的值得算法

    递归实现:

    int Fib1(int index)
    {
    if(index<1)
    {
    return -1;
    }
    if(index==1|| index==2)
    {
    return 1;
    }
    return Fib1(index-1)+Fib1(index-2);
    }
    迭代实现:
    
    int Fib5(int index)
    {
    if(index<1)
    {
    return -1;
    }
    int a1 - 1, a2 = 1, a3 = 1;
    for(int i = 0; i < index - 2; i++)
    {
    a3=a1+a2;
    a1=a2;
    a2=a3;
    }
    return a3;
    }
    //参看更多实现方法
    

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

    function Start() {
    // 协同程序WaitAndPrint在Start函数内执行,可以视同于它与Start函数同步执行.
    StartCoroutine(WaitAndPrint(2.0));
    print (“Before WaitAndPrint Finishes ” + Time.time );
    }
    function WaitAndPrint (waitTime : float) {
    // 暂停执行waitTime秒
    yield WaitForSeconds (waitTime);
    print (“WaitAndPrint “+ Time.time );
    }
    

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

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

    七十四:什么是里氏代换元则?

    里氏替换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。通俗点:就是子类对象可以赋值给基类对象,基类对象不能赋值给子类对象

    参考

    七十五:Mock和Stub有何区别?

    Mock与Stub的区别:Mock:关注行为验证。细粒度的测试,即代码的逻辑,多数情况下用于单元测试。Stub:关注状态验证。粗粒度的测试,在某个依赖系统不存在或者还没实现或者难以测试的情况下使用,例如访问文件系统,数据库连接,远程协议等。

    七十六:概述序列化:

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

    七十七:堆和栈的区别?

    栈通常保存着我们代码执行的步骤,如在代码段1中 AddFive()方法,int pValue变量,int result变量等等。而堆上存放的则多是对象,数据等。我们可以把栈想象成一个接着一个叠放在一起的盒子。当我们使用的时候,每次从最顶部取走一个盒子。栈也是如此,当一个方法(或类型)被调用完成的时候,就从栈顶取走,接着下一个。堆则不然,像是一个仓库,储存着我们使用的各种对象等信息,跟栈不同的是他们被调用完毕不会立即被清理掉。

    七十八:概述c#中代理和事件?

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

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

    七十九:客户端与服务器交互方式有几种?

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

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

    八十:Unity和Android与iOS如何交互?

    Unity可以到处Android和iOS的工程,然后通过安卓或者iOS的类去给Unity发消息,调用Unity中的方法

    八十一:如何在Unity3D中查看场景的面试,顶点数和Draw Call数?如何降低Draw Call数?

    在Game视图右上角点击Stats。降低Draw Call 的技术是Draw Call Batching

    这个在5.0以后在window-》Profiler下面,快捷键是cmd + 7(ctl + 7

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

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

    八十三:UNITY3d在移动设备上的一些优化资源的方法

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

    2.顶点数对渲染无论是cpu还是gpu都是压力最大的贡献者,降低顶点数到8万以下,fps稳定到了30帧左右

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

    粒子系统是cpu上的大头

    4.剪裁粒子系统

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

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

    animator也是一个效率奇差的地方

    7.把不需要跟骨骼动画和动作过渡的地方全部使用animation,控制骨骼数量在30根以下

    8.animator出视野不更新

    9.删除无意义的animator

    10.animator的初始化很耗时(粒子上能不能尽量不用animator)

    11.除主角外都不要跟骨骼运动apply root motion

    12.绝对禁止掉那些不带刚体带包围盒的物体(static collider )运动

    NUGI的代码效率很差,基本上runtime的时候对cpu的贡献和render不相上下

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

    14去掉法线计算

    15不要每帧计算viewsize 和windowsize

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

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

    18.尽量减少smooth group

    19.给美术定一个严格的经过科学验证的美术标准,并在U3D里面配以相应的检查工具

    八十四:四元数有什么作用?

    对旋转角度进行计算时用到四元数

    八十五:将Camera组件的ClearFlags选项选成Depth only是什么意思?有何用处?

    如果把摄像机的ClearFlags勾选为Deapth Only,那么摄像机就会只渲染看得见的对象,把背景会完全透明,这种情况一般用在两个摄像机以上的场景中

    八十六:在编辑场景时将GameObject设置为Static有何作用?

    设置游戏对象为Static时,这些部分被静态物体挡住而不可见时,将会剔除(或禁用)网格对象。因此,在你的场景中的所有不会动的物体都应该标记为Static。

    八十七:有A和B两组物体,有什么办法能够保证A组物体永远比B组物体先渲染?

    把A组物体的渲染对列大于B物体的渲染队列,通过shader里面的渲染队列来渲染

    八十八:将图片的TextureType选项分别选为““Texture”和“Sprite”有什么区别

    Sprite作为UI精灵使用,Texture作用模型贴图使用。Sprite需要2的整次幂,打包图片省资源

    八十九:问一个Terrain,分别贴3张,4张,5张地表贴图,渲染速度有什么区别?为什么?

    没有区别,因为不管几张贴图只渲染一次。

    九十:什么是DrawCall?DrawCall高了又什么影响?如何降低DrawCall?

    Unity中,每次引擎准备数据并通知GPU的过程称为一次Draw Call。DrawCall越高对显卡的消耗就越大。降低DrawCall的方法:

    Dynamic Batching Static Batching 高级特性Shader降级为统一的低级特性的Shader。

    九十一:实时点光源的优缺点是什么?

    可以有cookies – 带有 alpha通道的立方图(Cubemap )纹理。点光源是最耗费资源的。

    九十二:Unity的Shader中,Blend SrcAlpha OneMinusSrcAlpha这句话是什么意思?

    作用就是Alpha混合。公式:最终颜色 = 源颜色 x 源透明值 + 目标颜色 x(1 - 源透明值)

    九十三:简述水面倒影的渲染原理

    原理就是对水面的贴图纹理进行扰动,以产生波光玲玲的效果。用shader可以通过GPU在像素级别作扰动,效果细腻,需要的顶点少,速度快

    九十四:简述NGUI中Grid和Table的作用?

    对Grid和Table下的子物体进行排序和定位

    九十五:请简述NGUI中Panel和Anchor的作用

    只要提供一个half-pixel偏移量,它可以让一个控件的位置在Windows系统上精确的显示出来(只有这个Anchor的子控件会受到影响)

    如果挂载到一个对象上,那么他可以将这个对象依附到屏幕的角落或者边缘

    3.UIPanel用来收集和管理它下面所有widget的组件。通过widget的geometry创建实际的draw call。没有panel所有东西都不能够被渲染出来,你可以把UIPanel当做Renderer

    九十六:能用foreach遍历访问的对象需要实现接口或声明___方法的类型

    转载自http://www.cnblogs.com/android-blogs/p/6343361.html?utm_source=itdadao&utm_medium=referral

    展开全文
  • unity 面试题

    2016-03-30 19:49:00
    随后是二对一的技术面试,但涉及的技术细节相对较少,很多其它的是对曾经工作、项目经历的询问。 然后说今天先到这里。让我等通知。 我还特意问了一下,通知大概要多久,他们说这个得看hr,他们仅仅是给hr传达...
  • Unity面试题汇总》由会员分享,可在线阅读,更多相关《Unity面试题汇总(52页珍藏版)》请在人人文库网上搜索。1、一、 C#语言1. 重载和重写的区别1) 所处位置不同 重载在同类中 重写在父子类中2) 定义方式不同 重载...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 613
精华内容 245
关键字:

unity面试题