Unity游戏程序员面试题及解答

典型的一些如手写排序算法、一些基本数学问题,在此就不列举了。以下整理出一些代表性的、有参考价值的题,真实面试题,附有本人的解答,欢迎讨论。

 

题1.指出下列哪些属于值类型?

int  System.Object  string  UnityEngine.MonoBehaviour  UnityEngine.Object  struct  enum  Vector3

说明:System.Object是所有类型的基类,其本身是引用类型。

 

题2.获取、增加、删除组建的命令分别是什么?

获取:   GetComponent()     增加:   AddComponent()     删除:   RemoveComponent()  

 

题3.简述你使用过哪些第三方插件?

Skyshop做IBL和PBR,Shatter Toolkit做模型物理破碎,Final IK插件做反向运动学计算。

说明:IBL是基于图像的渲染,PBR是基于物理的渲染。

 

题4.简述一下对象池原理。什么情况下使用?

对象池可以将对象存储在一块预先划出的内存区域中,当需要时可以取出使用,而不需要每次都要实例化新的对象。一般在需要循环获取一个对象但是不关心对象的创造时机时的情况下可以使用。

说明:对象池在很多语言中都有实现。所以回答不必拘泥于某种具体的语言,说出它的思想即可。

 

题5.使用mipmap有什么好处和坏处?什么情况下使用?

答:使用mipmap可以降低现存带宽占用,提升渲染性能,还能减少远处因为分辨率较大的纹理因过分缩小而产生的失真。坏处是会使内存占用变大,某些情况下会导致远处贴图模糊。

说明:mipmap是一种纹理技术, 在三维世界中,显示一张图的大小与摄象机的位置有关,近的地方,图片实际象素就大一些,远的地方图片实际象素就会小一些,就要进行一些压缩,例如一张64*64的图,在近处,显示出来可能是50*50,在远处可能显示出来是20*20.如果只限于简单的去除某些像素,将会使缩小后的图片损失很多细节,图片变得很粗糙,因此,图形学有很多复杂的方法来处理缩小图片的问题,使得缩小后的图片依然清晰.

       Mipmap纹理技术是目前解决纹理分辨率与视点距离关系的最有效途径,它会先将图片压缩成很多逐渐缩小的图片,例如一张64*64的图片,会产生64*64,32*32,16*16,8*8,4*4,2*2,1*1的7张图片,当屏幕上需要绘制像素点为20*20 时,程序只是利用 32*32 和 16*16 这两张图片来计算出即将显示为 20*20 大小的一个图片,这比单独利用 32*32 的那张原始片计算出来的图片效果要好得多,速度也更快.

当然你不需要回答这些原理,简单描述一下即可。

 

题6.叙述一下unity3D中的drawcall合并。

答:Unity中使用两种方法进行drawcall合并:静态和动态。勾选static选项的物体系统强制进行静态合并;对于非static的物体,在材质相同的情况下系统会自动进行动态合并。

说明:就如同D3D的Render()一样,Unity每次在准备数据并通知GPU渲染的过程称为一次Draw Call。注意本题不是要你解释"Drawcall"而是解释"Drawcall合并"。

 

题7.简述兰彻斯特方程在游戏开发中的用途α[M^2- m(t)^2]=β[N^2- n(t)^2]和α[M-m(t)]=β[N-n(t)]

答:式中α、β分别为交战双方在单位时间内毁伤对方战斗单位数,m(t)、n(t)表示在战斗开始后t时刻双方在战斗中尚存的作

战单位数,假设交战开始时刻双方的初始战斗单位数为m(0)=M,n(0)=N,在交战过程中双方战斗单位数符合下列状态方程:

α[M^2- m(t)^2]=β[N^2- n(t)^2]

或者

α[M - m(t)]=β[N - n(t)]。

说明:基本上答到意思就行 。

 

题8.

int[] a = new int[128];

foreach (int aa in a) 
{  
    foreach(int bb in a)  
    {   
        foreach(int cc in a)   
        {    
            cc = 0;   
        }  
    } 
}

上述C#编写的代码片段有什么问题?

答:首先,在foreach中对临时变量cc赋值本身语法就是错误的,编译器通不过编译。其次,这种嵌套多次使用foreach循环的方式是不妥的,因为foreach语句会产生少量的内存损耗,在性能上也不佳。

说明:(1)要说出语法错误; (2)说出foreach内存和性能损耗,或者不如for语句等缺点。 

 

题9.

public class Dialog{}
{
    public static GameObject m_NPC;
    
    public static void ShowDialog()
    {
        m_NPC=Object.Instanciate(Resource.Load("npc") as GameObject);
        SaySomething(m_NPC);
    }
}

void static SaySomething(GameObject npc)
{
    ...
}

假定以上使用C#编写的类没有语法错误,且能在Unity3D引擎中正常使用。问该类存在哪些问题或隐患?

答:以上Dialog类在实际中会多次调用,而每次调用都要重新载入同样的资源和实例化,这是一种损耗性能的做法。

说明:这道题根据题目描述可以推测是取自实际项目中的,那么肯定是存在一定的不妥才拿出来出题的。各位如果还有什么好的建议可以留言。

 

题10.

 1 public struct FallCacheInfo
 2 {
 3     public Transform parent;
 4 }
 5 
 6 public class LevelManager
 7 {
 8     Transform transform;
 9     Dictionary<int,FallCacheInfo> m_FallInfo = new Dictionary<int,FallCacheInfo>();
10     
11     void Fall(int id)
12     {
13         FallCacheInfo fci;
14         fci.parent = null;
15         m_FallInfo[id] = fci;
16 
17         fci.parent = GameObject.findChild("POS");
18     }
19 }
20 
21 void OnWaitFallActorLoaded(int id)
22 {
23     FallCacheInfo fci;
24     if(m_FallInfo.TryGetValue(id,out fci))
25     {
26         transform.parent = fci.parent;
27     }
28 }

上述代码,假定场景中存在名为"POS"的对象,transform也为存在的对象,Fall和OnWaitFallActorLoaded函数依次被执行,请问transform最终被挂到哪个物体(或节点)下?

答:最终被挂在根节点下。

说明:请读者思考。

 

posted on 2016-05-24 18:44  拔丝煎面  阅读(17247)  评论(0编辑  收藏  举报

导航