面试必问之Unity面试题大全

Unity新手入门进阶之路(群内各种入门资源资料大神):721559786 (加群下载插件资源学习资料)

                                              

  回答有关线程的以下问题。解释你的答案:

   1. 可以使用线程在运行时修改纹理吗?

    答: 编号纹理和网格物体是存储在GPU内存中的元素的示例,除了主体之外,Unity不允许其他线程对这些类型的数据进行修改。

   2. 可以使用线程移动场景上的GameObject吗?

    答: 否。在Unity中,获取Transform引用不是线程安全的。

   3. 考虑下面的代码片段:

class RandomGenerator : MonoBehaviour
{
    public float[] randomList;

    void Start()
    {
        randomList = new float[1000000];
    }

    void Generate()
    {
        System.Random rnd = new System.Random();
        for(int i=0;i<randomList.Length;i++) randomList[i] = (float)rnd.NextDouble();
    }
}

  使用线程改进此代码,因此1000000随机数生成运行时不会损坏性能。

    答:  使用线程时,我们必须避免使用本地Unity结构,例如MathfRandom类:

class RandomGenerator : MonoBehaviour
{
    public float[] randomList;

    void Start()
    {
        randomList = new float[1000000];
        Thread t = new Thread(delegate()
        {
            while(true)
            {
                Generate();
                Thread.Sleep(16); // trigger the loop to run roughly every 60th of a second
            }            
        });
        t.Start();
    }

    void Generate()
    {
      System.Random rnd = new System.Random();
      for(int i=0;i<randomList.Length;i++) randomList[i] = (float)rnd.NextDouble();
    }
}



②  解释什么是顶点着色器,以及像素着色器是什么?

    答:

顶点着色器是一个为网格的每个顶点运行的脚本,允许开发人员应用变换矩阵和其他操作,以控制此顶点在3D空间中的位置,以及它将如何投影到屏幕上。

像素着色器是在网格的三角形中处理三个顶点后,为每个片段(要渲染的像素候选)运行的脚本。开发人员可以使用UV/ TextureCoords和样本纹理等信息来控制将在屏幕上呈现的最终颜色。



③  解释为什么延迟照明会优化带有大量灯光和元素的场景?

    答:

在渲染过程中,计算每个像素是否应该照亮并受到雷电影响,并且每个灯光都会重复这一点。经过对场景中不同灯光的大约八次重复计算后,开销变得显着。

对于大型场景,渲染的像素数通常大于屏幕本身的像素数。

延迟照明使场景呈现所有没有照明的像素(这是快速的),并且以额外的信息(以低开销为代价),它仅为屏幕缓冲区的像素计算照明步骤(其小于所有像素处理的像素为每个元素)。该技术允许在项目中使用更多的光源实例。



④  具有渲染优化的可视化模式有什么好处?如下图所示:


    答:

“透支”模式有助于用户分析在同一个“区域”渲染的像素数量。黄色到白色区域是渲染像素过多的“热”区域。

开发人员可以使用这些信息来调整材料并更好地使用Z-Test和优化渲染。



⑤  解释为什么Time.deltaTime应该用于使依赖于时间的事情正确运行?

    答:

实时应用程序(如游戏)具有可变的FPS。他们有时会以60FPS的速度运行,或者当速度变慢时,它们将以40FPS或更低的速度运行。

如果你想从改变值AB1.0秒就可以不只是增加AB-A两帧之间因为帧能跑多快或慢,所以一帧可以有不同的持续时间。

纠正这种情况的方法是测量从帧XX+1增量所花费的时间通过这样做A来利用这一变化与帧持续时间deltaTimeA += (B-A) * DeltaTime

当累计DeltaTime达到1.0秒时,A将具有假设B值。



⑥ 解释为什么矢量在用于移动对象时应该被标准化?

    答:

规范化使矢量单位长度。这意味着,例如,如果你想以20.0的速度移动,乘法speed * vector每步将产生精确的20.0单位。如果矢量具有随机长度,则该步骤将不同于20.0单位。


⑦ 考虑下面的代码片段:

class Mover : MonoBehaviour
{
  Vector3 target;
  float speed;

  void Update()
  {
  
  }
}

   完成此代码,以便Gameobject包含此脚本随着常量speed移动target,并在距离达到1.0或更小单位时停止移动。

    答:

class Mover : MonoBehaviour
{

  Vector3 target;
  float speed;

  void Update()
  {
      float distance = Vector3.Distance(target,transform.position);

      // will only move while the distance is bigger than 1.0 units
      if(distance > 1.0f)
      {
        Vector3 dir = target - transform.position;
        dir.Normalize();                                    // normalization is obligatory
        transform.position += dir * speed * Time.deltaTime; // using deltaTime and speed is obligatory
      }     
  }
}



⑧ 可以两个GameObject,每个只有一个SphereCollider,都可以设置为trigger和引发OnTrigger事件?解释你的答案。

    答:

不可以。两个物体之间的碰撞事件只有在其中一个物体RigidBody附着在其上时才能引发在实现使用“物理”的应用程序时,这是一个常见错误。



⑨ 以下哪个示例运行速度更快? 解释你的答案。

     1. 1000GameObject,每一个MonoBehavior执行Update回调。

   2. 一个GameObject带MonoBehavior1000个类的数组,每个类实现自定义Update()回调。

    答:

正确的答案是2。

Update回调使用C#的反射,这比直接调用函数显著较慢调用。在我们的例子中,GameObjects每个1000 有一个MonoBehaviour意思是每帧1000次反射调用。

由于直接访问方法创建一个MonoBehaviour一个Update,并使用这个单一的回调到Update给定数量的元素,要快得多。



⑩ 用几句话来解释Unity编辑器中的检查员,项目和层次面板有什么作用。哪个负责引用将包含在构建过程中的内容?

    答:

巡视面板允许用户修改数值(如位置,旋转和缩放),拖放场景对象(如预制件,材质和游戏对象)的引用等。此外,它还可以使用编辑器脚本显示由用户创建的定制用户界面。

项目面板包含项目根文件夹中assets文件夹的文件系统中的文件。它显示了项目中可用的所有可用脚本,纹理,材质和着色器。

层次结构面板显示当前场景结构及其GameObjects及其子项。它还可以帮助用户按照与GameObject的兄弟姐妹相关的名称和顺序来组织它们。依赖于订单的功能(如UI)利用此分类。

负责在构建过程中引用内容的面板是层级面板。该面板包含对应用程序执行时存在或将存在的对象的引用。在构建项目时,Unity会在项目面板中搜索它们,并将它们添加到包中。



⑩① 当应用程序关闭时,按照它们将被调用的顺序排列下面列出的事件函数:

Update()
OnGUI()
Awake()
OnDisable()
Start()
LateUpdate()
OnEnable()
OnApplicationQuit()
OnDestroy()
    答:

应用程序关闭时这些事件函数正确执行顺序如下所示:

Awake()
OnEnable()
Start()
Update()
LateUpdate()
OnGUI()
OnApplicationQuit()
OnDisable()
OnDestroy()

注意:您可能会不同意OnApplicationQuit()上述列表中的位置,但可以通过记录应用程序关闭时发生的调用顺序来验证它是否正确。



⑩② 用下面的代码解释问题,并提供一个可以解决问题的替代实现。

using UnityEngine;
using System.Collections;

public class TEST : MonoBehaviour {
    void Start () {
        transform.position.x = 10;
    }
}

    答:

问题是你不能直接从变换中修改位置这是因为该职位实际上是一个财产(而不是一个领域)。因此,当一个getter被调用时,它会调用一个方法来返回它放入堆栈Vector3 副本

因此,基本上你在上面的代码中正在分配一个结构体的成员,它是一个堆栈中的值,稍后会被删除。

相反,正确的解决方案是取代整个财产; 例如:

using UnityEngine;
using System.Collections;

public class TEST : MonoBehaviour {
   void Start () {
        Vector3 newPos = new Vector3(10, transform.position.y, transform.position.z);
        transform.position = newPos;
    }
}




*面试比棘手的技术问题要多,所以这些仅仅是作为指导。并不是每个值得聘用的“A”候选人都能够回答所有问题,也不会回答他们都保证有“A”候选人。在这一天结束时,招聘仍然是一门艺术,一门科学 - 还有很多工作


猜你喜欢

转载自blog.csdn.net/qq_40930606/article/details/80513078