一.什么是渲染管道?


是指在显示器上为了显示出图像而经过的一系列必要操作。 渲染管道中的很多步骤,都要将几何物体从一个坐标系中变换到另一个坐标系中去。 主要步骤有: 本地坐标->视图坐标->背面裁剪->光照->裁剪->投影->视图变换->光栅化。


二.如何优化内存?


有很多种方式,例如 1.压缩自带类库; 2.将暂时不用的以后还需要使用的物体隐藏起来而不是直接Destroy掉; 3.释放AssetBundle占用的资源; 4.降低模型的片面数,降低模型的骨骼数量,降低贴图的大小;

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


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


1.Resources.Load();

2.AssetBundle


四、什么是协同程序?


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


五、你用过哪些插件?


(最好多熟悉几个插件,问的时候好回答)



1.使用Unity3d实现2d游戏,有几种方式?


1.使用本身的GUI; 2.把摄像机的Projection(投影)值调为Orthographic(正交投影),不考虑z轴; 3.使用2d插件,如:2DToolKit;


2.Unity3d中的碰撞器和触发器的区别?


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


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


两个物体都必须带有碰撞器(Collider),其中一个物体还必须带有Rigidbody刚体。


4.CharacterController和Rigidbody的区别?


CharacterController自带胶囊碰撞器,里面包含有刚体的属性; Rigidbody就是刚体,使物体带有刚体的特征。


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


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


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


rigidbody.AddForce\/AddForceAtPosition,都在rigidbody系列函数中。


7.什么叫做链条关节?


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


8.物体自身旋转使用的函数?


Transform.Rotate()


9.物体围绕某点旋转使用的函数?


Transform.RotateAround()


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


PlayerPrefs.SetInt() PlayerPrefs.GetInt()


11.Unity3d提供了几种光源类型,分别是哪几种?


四种。 平行光:Directional Light

点光源:Point Light

聚光灯:Spot Light

区域光源:Area Light


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


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


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


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


14.移动摄像机的动作放在哪个系统函数中,为什么放在这个函数中?


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


15.当游戏中需要频繁创建一个物体时,我们需要怎样做能够节省内存?


使用预制物体对象Prefab,然后复制创建。


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


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


17.请描述Prefab的作用,并描述如何在移动设备的环境下恰当的使用它?


Prefab在实例化的时候用到,主要用于经常会用到的物体,属性方便修改。


18.如何销毁一个UnityEngine.Object及其子类?


使用Destroy()方法;


19.请简述Unity3d下如何安全的在不同工程间迁移asset数据,请列举出三种方法?


1.可以把assets目录和Library目录一起迁移 2.导出包 3.用Unity带的assets Server功能


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


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


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


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


22.alpha blend工作原理


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


23.写出光照计算中的diffuse的计算公式


diffuse = Kd x colorLight x max(N*L,0);Kd 漫反射系数、colorLight 光的颜色、N 单位法线向量、L 由点指向光源的单位向量、其中N与L点乘,如果结果小于等于0,则漫反射为0。


24.Lod是什么,优缺点是什么?


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


25.两种阴影判断的方法、工作原理。


A.阴影由两部分组成:本影与半影 a.本影:景物表面上那些没有被光源直接照射的区域(全黑的轮廓分明的区域) b.半影:景物表面上那些被某些特定光源直接照射但并非被所有特定光源直接照射的区域(半明半暗区域) 求阴影区域的方法:做两次消隐过程 .一次对每个光源进行消隐,求出对于光源而言不可见的区域L;

一次对视点的位置进行消隐,求出对于视点而言可见的面S; 32.shadow area= L ∩ S

阴影分为两种:自身阴影和投射阴影 自身阴影:因物体自身的遮挡而使光线照射不到它上面的某些可见面 35.工作原理:利用背面剔除的方法求出,即假设视点在点光源的位置。 投射阴影:因不透明物体遮挡光线使得场景中位于该物体后面的物体或区域受不到光照照射而形成的阴影 工作原理:从光源处向物体的所有可见面投射光线,将这些面投影到场景中得到投影面,再将这些投影面与场景中的其他平面求交得出阴影多边形,保存这些阴影多边形信息,然后再按视点位置对场景进行相应处理得到所要求的视图(利用空间换时间,每次只需依据视点位置进行一次阴影计算即可,省去了一次消隐过程) 若是动态光源此方法就无效了。


26.Vertex Shader是什么,怎么计算?


顶点着色器


27.MipMap是什么,作用?


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


28.机试:二选一 1.用代码实现第三角色控制器 2.实现吊机吊物体的功能

29.反向旋转动画的方法是什么?


【反转动画,讲动画的速度调到-1,碰撞时,被碰撞物体与碰撞物体有collider组件,碰撞物体有刚体组件,或角色碰撞得包含角色组件 OR 改变animation.speed】


30.碰撞检测需要物体具备什么属性?

31.获取、增加、删除组件的命令分别是什么?


获取:GetComponent 增加:AddComponent 删除:Destroy


32.Animation.CrossFade命令作用是:(C) A.动画放大 B.动画转换 C.动画的淡入为其他动画

33.Application.loadLevel命令为:(A)

A.加载关卡

B.异步加载关卡

C.加载动作

34.调试记录到控制台的命令是什么?


Debug.Log();


35.编辑器类存放路径是什么?


工程目录下的Assets\/Editor文件夹下。


36.使用原生GUI创建一个可以拖动的窗口命令是什么?


GUI.DragWindow();


37.localPosition与Position的使用区别?


localPosition:自身位置,相对于父级的变换的位置。 Position:在世界坐标transform的位置


38.意义连线


Mathf.Round 插值 Mathf.Clamp 四舍五入 Mathf.Lerp 限制


39.写一个计时器工具,从整点开始计时,格式为:00:00:00

40.写出Animation的五个方法

41.怎么拿到一个对象上脚本的方法


GameObject.GetComponent<>();


42.上机题:用鼠标实现在场景中拖动物体,用鼠标滚轮实现缩放(用一个Cube即可)。

43.请简述向量的点乘,向量的叉乘以及向量归一化的几何意义?


点乘的几何意义是:计算两个向量之间的夹角,以及在某一方向上的投影; 叉乘的几何意义是:创建垂直于平面,三角形,或者多边形的向量;



1、Animation.CrossFade命令作用是(C) A 动画消失 B动画转换 C东环的淡入为其他动画

2、Application.loadedLevel命令为(A) A加载关卡 B异步加载关卡 C加载动作

3、反向播放动画的方法为?


Animation.Rewind


4、碰撞检测需要物体具备什么属性?


两个物体都必须带有碰撞器(Collider),其中一个物体还必须带有Rigidbody刚体。


5、获取、增加、删除组件的命令分别是什么?


获取:GetComponent 增加:AddComponent 删除:Destroy


6、调试记录到控制台的命令式什么?


Debug.Log();


7、编辑器类存放的路径是什么?


工程目录下的Assets\/Editor文件夹下。


8、使用原声的GUI创建一个可以拖动的窗口的命令是什么?


GUI.DragWindow();


9、localPosition与position的使用区别


localPosition:自身位置,相对于父级的变换的位置。 Position:在世界坐标transform的位置


10、连线题(汉英对照)


Mathf.Round(四舍五入) 插值 Mathf.Clamp(限制) 四舍五入 Mathf.Lerp(插值) 限制


11、写一个计时器工具,从游戏开始计时,格式为00:00:00

using UnityEngine;
using System.Collections;

public class Cube : MonoBehaviour {

private float timer = 0f;

private int h = 0;

private int m = 0;

private int s = 0;

private string timeStr = string.Empty;

// Update is called once per frame
void Update () {
timer += Time.deltaTime;
if (timer >= 1f) {
s++;
timer = 0;
}
if (s >= 60) {
m++;
s = 0;
}
if (m >= 60) {
h++;
m = 0;
}
if (h >= 99) {
h = 0;
}
}

void OnGUI(){
timeStr = string.Format ("{0:D2}:{1:D2}:{2:D2}", h, m, s);
GUI.Label (new Rect (10, 10, 100, 200), timeStr);
}

}

12、上机题:用鼠标实现在场景中拖动物体,用鼠标滚轮实现缩放(用一个Cube即可)


在场景中添加一个Plan,Camera,Directional Light,Cube。添加两个脚本scrollerScirpt(挂在Camera),CubeDragScript(挂在Cube上)。

1.鼠标滚轮实现缩放:将摄像机的镜头拉近或者拉远,调整摄像机的视角就可以实现,主要实现代码如下:

​void Update () { //鼠标滚轮的效果 //Camera.main.fieldOfView 摄像机的视野 //Camera.main.orthographicSize 摄像机的正交投影 //Zoom out if (Input.GetAxis("Mouse ScrollWheel") < 0) { if (Camera.main.fieldOfView <= 100) Camera.main.fieldOfView += 2; if (Camera.main.orthographicSize <= 20) Camera.main.orthographicSize += 0.5F; } //Zoom in if (Input.GetAxis("Mouse ScrollWheel") > 0) { if (Camera.main.fieldOfView > 2) Camera.main.fieldOfView -= 2; if (Camera.main.orthographicSize >= 1) Camera.main.orthographicSize -= 0.5F; } } ​

2.鼠标实现在场景中拖动物体:

解决思路就是将世界坐标转换成屏幕坐标,然后计算物体与鼠标之间移动量,循环鼠标被按下操作,得到鼠标的当前位置,加上计算好的移动量,将新的坐标赋值给物理就行了。主要是开启一个协同程序(Corountine)来处理

主要代码如下:

​// Use this for initialization void Start () { StartCoroutine(OnMouseDown()); } IEnumerator OnMouseDown() { //将物体由世界坐标系转换为屏幕坐标系 Vector3 screenSpace = Camera.main.WorldToScreenPoint(transform.position);//三维物体坐标转屏幕坐标 //完成两个步骤 1.由于鼠标的坐标系是2维,需要转换成3维的世界坐标系 // // 2.只有3维坐标情况下才能来计算鼠标位置与物理的距离,offset即是距离 //将鼠标屏幕坐标转为三维坐标,再算出物体位置与鼠标之间的距离 Vector3 offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z)); while (Input.GetMouseButton(0)) { //得到现在鼠标的2维坐标系位置 Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z); //将当前鼠标的2维位置转换成3维位置,再加上鼠标的移动量 Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + offset; //curPosition就是物体应该的移动向量赋给transform的position属性 transform.position = curPosition; yield return new WaitForFixedUpdate(); //这个很重要,循环执行 } } ​