unity3d面试2

来源:互联网 发布:淘宝日系女生店铺推荐 编辑:程序博客网 时间:2024/06/05 20:00

1.        Unity实现昼夜交替的方法或思路?

在场景中设置一个主灯光,同时旋转能实现昼夜交替;

动态控制环境光照或者调整摄像机;

2      写出Unity脚本至少5个生命周期,并写出顺序。

 

AwakeStart FixedUpdate  Update LateUpdate 

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


3.  如何进行场景灯光的烘焙,说出具体的过程。

将场景中需要设置为静态的物体设置为  Lightmap static

将需要的灯光设置为baked

取消precomputedrealtime GI 勾选baked GI

开始烘培 

4           FixedUpdate(),Update(),LateUpdate()的用法与区别。


FixedUpdate固定更新

Update时时更新

LateUpdate最后更新


5    向量的点积,叉积,在游戏中的应用(分别举一个例子说明)

点积在游戏中是求物体旋转的夹角

叉积是两个向量的乘积产生一个新的向量。

叉积:求法线


6         LOD是什么,为什么要使用。

 

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

缺点是增加了内存。


7      两个对象发生碰撞的必要条件是什么?

 

 

两个对象必须要有collider组件,且其中一个必须要有 rigidbody组件。


 

8    Lightmapping是什么?为什么要使用?

 

是灯光的绘图,可以减少cpu的消耗,提高游戏的效率。

9  GI是什么,Light Probs是什么,Reflection Probs是什么,各有什么作用。

 

 

GI全局光照,是一个用来模拟光的互动和反弹等复杂行为的算法。


LightProbs是灯光探照组
Light Probe不产生阴影,只是提供灯光效果阴影只能靠实时灯光了.LightProbe的用法就是在LightMapping的基础上加上了一些探头的点来记录光源的信息。探头越多,效果就越明显
创建好Light Probes后,在烘焙的过程中,light probes会记录各个probe探针点记录的光照强度信息。然后运动的物体,通常是其mesh的中心点为物体的探测点(the centre of the mesh's bounding box)会参与运算。如果该点位于Light Probes的体积内的话,则取包裹该点的最小空间,取形成该空间的light probe(通常是4个点),根据距离进行插值,最终取得物体对应点的光照强度,并和烘焙时的光颜色共同作用于renderer。物体点所在的位置反应了插值时各点比例。
 
Light Probes的优点:(1)性能佳,对比实时阴影性能高很多,适合移动平台。(2)配合烘焙,配合烘焙效果很好。(3)可视化,可以可视化编辑Light Probes的分布,不需要代码。Light Probes的缺点:(1)烘焙后才能有效果,不能实时改变.(2)只能整体进行明暗变化。

ReflectionProbs

反射探头

天空盒的信息不可能包含所有的场景对象,在许多情况下,对象从天空搜集反射信息时可能会被遮蔽,像是室内对象或是在类似桥或是隧道等建筑物里的对象,为了要准确反射这些对象,我们必须用反射探头针对这些对象取样,这种探头从他们的位置对周围取样并把结果写到方体贴图,可以让周围经过的物体得到环境的反射影像

 

反射探头的位置会决定方体贴图取样的内容,以及反射所看起来的样子,一般来说,基于效能考虑反射探头越少越好请记住,反射探头并非用来让物理得到精确结果,而是让游戏世界有更好的反射,大多数情况下几个安排妥当的反射探头就很足够了。

 

10.        请简单叙述下Gizmos是什么,如何向场景中绘制。

 

Gizmos是Unity的一个接口Gizmos是场景视图里的一个可视化调试工具。

使用Gizmos.line 方法可以在场景中绘制

 

// 绘制最后一条线段
              Gizmos.DrawLine(firstPoint, beginPoint);
 
              // 恢复默认颜色
              Gizmos.color = defaultColor;
 
              // 恢复默认矩阵
              Gizmos.matrix = defaultMatrix;


11 

      在塔防游戏中,如何让塔指向进入攻击范围的敌人并射击?请写出对应的流程和代码。

1,首先对我防守单位建立攻击范围;

2,判断距离防守单位最近的敌人并且跑在最前方的敌人为防守单位最先攻击的敌人。

       3,确定敌人是一个动态数组,死去,从数组中删除,新生敌人添加在数组末尾。跑在最前方的敌人若处在防守单位的攻击范围内,则最先攻击其。

//创建防守单位using UnitEngine;using System.Collections;piblic class Defender : MonoBehaviour{public float m_attackArea;// 攻击范围GameObject m_targetEnemy;// 最先攻击敌人void Start(){m_attackArea= 2.0f;}void Update(){FindEnemy();Attack();// 进行攻击}// 查找最近敌人void FindEnemy(){if(m_targetEnemy != null)return;float mindist = -1;foreach(Enemy enemy in GameManager.Instance.m_EnemyList){Vector3 pos1 = this.transform.position;pos1.y = 0;vector3 pos2 = enemy.transform.position; pos2.y = 0;////目标敌人距离防守单位的距离float dist = Vector3.Distance(pos1, pos2);if(dist > m_attackArea)//如果目标不在攻击范围内continue;if(mindist < 0 || mindist > dist){//更新目标m_targetEnemy = enemy;mindist = dist;}}}}

12       如何控制子弹发射频率,技能冷却时间等(需示例代码)


private float timer;void Update(){timer += Time.deltatime;if(timer >= 10){timer -= 10f;// 刷新}}

13 

解决场景切换数据保存的问题。

PlayerPrefs.SetString("key", "value");  string str = PlayerPrefs.GetString("key", "defaule"));  


Scene0Main.cs:

 //储存数据的显示      public string testStr;      public string testInt;      public string testFloat; 

 void Start () {          //读取key的值          testStr = PlayerPrefs.GetString("testStr", "default");          testInt = PlayerPrefs.GetInt("testInt", 0).ToString();          testFloat = PlayerPrefs.GetFloat("testFloat", 0).ToString();         }  

<span style="white-space:pre"></span>    PlayerPrefs.SetString("testStr", testStr);              PlayerPrefs.SetInt("testInt", int.Parse(testInt));              PlayerPrefs.SetFloat("testFloat", float.Parse(testFloat));              //切换场景到scene1              Application.LoadLevel("scene1");  


Scenes1

        testStr = PlayerPrefs.GetString("testStr", "default");          testInt = PlayerPrefs.GetInt("testInt", 0).ToString();          testFloat = PlayerPrefs.GetFloat("testFloat", 0).ToString();  


14  unity协程运行机制  和c#多线程运行机制

unity中的协程是一个分部执行,遇到条件(yield return 语句)会挂起,直到条件满足才会被唤醒继续执行后面的代码。其作用就是,总结起来就是一句话:控制代码在特定的时机执行。请你牢记:协程不是线程,也不是异步执行的。协程和 MonoBehaviour 的 Update函数一样也是在MainThread中执行的。使用协程你不用考虑同步和锁的问题。

多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。浏览器就是一个很好的多线程的例子,在浏览器中你可以在下载JAVA小应用程序或图象的同时滚动页面,在访问新页面时,播放动画和声音,打印文件等。  

  多线程的好处在于可以提高CPU的利用率——任何一个程序员都不希望自己的程序很多时候没事可干,在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。  

其中线程的创建有以下三种方法:Thread、ThreadPool、Timer。

线程是进程中的一个实体,是系统独立调度和分派的基本单位

进程:一个程序在一个数据集合上的一次运行运行过程。


15    unity程序中网通通信的几种方式

1.使用Unity3d内置的Network方法,采用RPC(远程过程调用)的方式来进行网络编程。
2.使用第三方的网络服务器构件,如smartFox,netDog(c++)等等。
3.Unity3d 支持 插件开发。
4.对于小规模的网络IO,可以查看WWW这个对象,用HTTP协议来通信。

16  

Unity中资源动态加载的几种方式比较

Unity3D 里有两种动态加载机制:一个是Resources.Load,另外一个通过AssetBundle,其实两者区别不大。 Resources.Load就是从一个缺省打进程序包里的AssetBundle里加载资源,而一般AssetBundle文件需要你自己创建,运行时动态加载,可以指定路径和来源的。  (1).assetBundle就是内部数据读取完后自动创建了一个assetBundle而已Create完以后,等于把硬盘或者网络的一个文件读到内存一个中,这时也就是个AssetBundle内存镜像数据块。释放方式是AssetBundle.Unload(false)  (2).用AssetBundle.Load(同Resources.Load) 会从AssetBundle的内存镜像里读取并创建一个Asset对象,使用Resources.UnloadUnusedAssets()释放全部和Resources.UnloadAsset(gameobject);释放单个;  (3).Instaniate一个Prefab,是一个对Assets进行Clone(复制)+引用结合的过程,使用GameObject.Destroy(gameobject);(注意)游戏对象可能不是动态加载时,但是可能他的材质、图集是动态加载的请把这些应用置为空。

17 啥是shader?

Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方 式和输入的贴图或者颜色等组合作用,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。
18 简述unity的物理系统和动画系统的区别?
Unity的动画系统有专门的Animator Controler来控制动画,可以用Animation 来剪辑自己所需要的动画;
1.如果是旧的动画系统,就只需要给模型添加Animation组件,然后把对应的动画剪辑添加到该组件的动画列表中,然后再脚本中直接根据动画剪辑的索引进行播放。2.你也可以使用新的mecanim动画组件Animator,设置好动画状态机,然后通过动画改变参数来实现动画状态的切换。

而物理系统只是用来添加组件后用相应脚本控制。
19   用unity的API实现将一张图片贴到网格上
public Texture texture;
Texture.maintexture = texture;
给网格添加脚本;
将图片格式转为2DUISprite 或者 Texture 然后拖给脚本。

20 

unity3d 为什么要烘焙?烘焙作用是为了什么?

可以这样理解。你把物体模型放进了场景里之后, 引擎会计算光线,光线照到你的物体的表面形成反光和阴影。 
如果不烘焙, 游戏运行的时候,这些反光和阴影都是由显卡和CPU计算出来的。
你烘焙之后,这些反光和阴影都记录到了你的模型里,变成了新的贴图了,运行的时候,显卡和CPU不需要进行对环境光效果的运算了。如前面的回答,节约CPU资源。
21.Unity3d的物理引擎中,有几种施加力的方式,分别描述出来
rigidbody.AddForce/AddForceAtPosition,都在rigidbody系列函数中

22.物体自身旋转使用的函数?
Transform.Rotate()

23.物体围绕某点旋转使用的函数?
Transform.RotateAround()
24.Unity3d提供了一个用于保存和读取数据的类(PlayerPrefs),请列出保存和读取整形数据的函数
</pre><pre name="code" class="csharp"> // 读取key值            testStr = PlayerPrefs.GetString("testStr", "default");            testInt = PlayerPrefs.GetString("testInt", 0).ToString();            testFloat = PlayerPrefs.GetSting("testFloat", 0).ToString();            //设置key值            PlayerPrefs.SetString("testStr", testStr);            PlayerPrefs.SetInt("testInt", int.Parse(testInt));            PlayerPrefs.SetFloat("testFloat", float.Parse(testFloat));

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

四种。
平行光:Directional Light 点光源:Point Light
聚光灯:Spot Light 区域光源:Area Light
26  static 修饰成员变量与成员函数的作用
http://blog.csdn.net/linux_wgl/article/details/8006250

这是C++对static关键字的重用。主要指静态数据成员/成员函数。

表示属于一个类而不是属于此类的任何特定对象的变量和函数. 这是与普通成员函数的最

大区别, 也是其应用所在, 比如在对某一个类的对象进行计数时, 计数生成多少个类的实

例, 就可以用到静态数据成员. 在这里面, static既不是限定作用域的, 也不是扩展生存

期的作用, 而是指示变量/函数在此类中的唯一性. 这也是”属于一个类而不是属于此类的

任何特定对象的变量和函数”的含义. 因为它是对整个类来说是唯一的, 因此不可能属于

某一个实例对象的. (针对静态数据成员而言, 成员函数不管是否是static, 在内存中只有

一个副本, 普通成员函数调用时, 需要传入this指针, static成员函数调用时, 没有this

指针. )

static数据成员的初始化:

(1) 初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆。

(2) 初始化时不加该成员的访问权限控制符private,public等。

(3) 初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不

是对象的成员。

(4) 静态数据成员是静态存储的,它是静态生存期,必须对它进行初始化。

Static成员函数

静态成员函数和静态数据成员一样,它们都属于类的静态成员,它们都不是对象成员。因

此,对静态成员的引用不需要用对象名。

静态成员函数仅能访问静态的数据成员,不能访问非静态的数据成员,也不能访问非静态

的成员函数,这是由于静态的成员函数没有this指针。

软件开发一般分为五个阶段:1.问题的定义及规划此阶段是软件开发与需求放共同讨论,主要确定软件的开发目标及其可行性。2.需求分析
在确定软件开发可行性的情况下,对软件需要实现的各个功能进行详细需求分析。需求分析阶段是一个很重要的阶段,这一阶段做的好,将为整个软件项目的开发打下良好的基础。“唯一不变的是变化本身”,同样软件需求也是在软件爱你开发过程中不断变化和深入的,因此,我们必须定制需求变更计划来应付这种变化,以保护整个项目的正常进行。3.软件设计
此阶段中偶要根据需求分析的结果,对整个软件系统进行设计,如系统框架设计、数据库设计等。软件设计一般分为总体设计和详细设计。好的软件设计将为软件程序编写打下良好的基础。4.程序编码
此阶段是将软件设计的结果转化为计算机可运行的程序代码。在程序编码中必定要制定统一、符合标准的编写规范。以保证程序的可读性、易维护性。提高程序的运行效率。
5.软件测试在软件设计完成之后要进行严密的测试,一发现软件在整个软件设计过程中存在的问题并加以纠正。整个测试阶段分为单元测试、组装测试、系统测试三个阶段进行。测试方法主要有白盒测试和黑盒测试。以上就是软件开发过程的五个阶段,但是有的时候在软件开发过程中并不是必须按照这个过程进行的。

28 使用unity3d实现2d游戏有几种方式

原理上基本是一种都是把2D图像映射到一个平面网格上,然后让这个网格始终面向摄像机,同时摄像机的投影模式为平行投影(没有近大远小)实际实现上有挺多的,比如可以在3D模式下自己实现上述原理,还可以使用assetstore的一些2D游戏制作插件,还可以使用unity3d自带的2D模式制作。
29 unity3d中的碰撞器和触发器的区别

碰撞器: 一群组件,它包含了很多种类,比如:Box Collider(盒碰撞体),Mesh Collider(网格碰撞体)等,这些碰撞器应用的场合不同,但都必须加到GameObjecet身上。

触发器 ,只需要在检视面板中的碰撞器组件中勾选IsTrigger属性选择框。

物体发生碰撞的必要条件

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

在unity3d中,能检测碰撞发生的方式有两种,一种是利用碰撞器,另一种则是利用触发器。

触发信息检测:1.MonoBehaviour.OnTriggerEnter(Collider collider)当进入触发器2.MonoBehaviour.OnTriggerExit(Collider collider)当退出触发器3.MonoBehaviour.OnTriggerStay(Collider collider)当逗留触发器碰撞信息检测:1.MonoBehaviour.OnCollisionEnter(Collision collision) 当进入碰撞器2.MonoBehaviour.OnCollisionExit(Collision collision) 当退出碰撞器3.MonoBehaviour.OnCollisionStay(Collision collision)  当逗留碰撞器

unity3d中的碰撞器和触发器的区别?

碰撞器是触发器的载体,而触发器只是碰撞器身上的一个属性

当Is Trigger=false时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果,可以调用OnCollisionEnter/Stay/Exit函数;

当Is Trigger=true时,碰撞器被物理引擎所忽略,没有碰撞效果,可以调用OnTriggerEnter/Stay/Exit函数。

如果既要检测到物体的接触又不想让碰撞检测影响物体移动或要检测一个物件是否经过空间中的某个区域这时就可以用到触发器

例子:

碰撞器:汽车被撞飞、皮球掉在地上又弹起效果

触发器:人站在靠近门的位置门自动打开效果

30  物体发生碰撞的必要条件
两个物体都必须带有碰撞器(Collider),其中一个物体还必须带有Rigidbody刚体。
在unity3d中,能检测碰撞发生的方式有两种,一种是利用碰撞器,另一种则是利用触发器。

31 在物体发生碰撞的整个过程中,有几个阶段,分别列出对应的函数
三个阶段
1.OnCollisionEnter(进入碰撞) 2.OnCollisionStay (逗留碰撞) 3.OnCollisionExit(当退出碰撞) 

32.Unity3d的物理引擎中,有几种施加力的方式,分别描述出来
rigidbody.AddForce(添加一个力到刚体。作为结果刚体将开始移动。
/AddForceAtPosition(在position位置应用force力。作为结果这个将在这个物体上应用一个力矩和力。
都在rigidbody系列函数中。

33.物体自身旋转使用的函数?
Transform.Rotate()

34.物体围绕某点旋转使用的函数?
Transform.RotateAround()

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






0 0
原创粉丝点击