Unity 面试首轮题目记录(问题记录,当前会话归档)

归档日期:2026-04-07
用途:供用户保存,并在新对话中重新上传到 GPT 知识中继续沿用。
说明:本文件只记录每道题第一次出现时的内容,不重复收录同题复习版。我不能自动写回知识库;需要你手动保存并在新对话中重新上传。

当前会话概览

  • 本次首轮记录题目数:13
  • 当前仍在错题本中的题目:1
  • 已通过复习并从错题本移除的题目:
    • Unity 协程原理
    • Awake / Start 生命周期区别
    • Update / FixedUpdate / LateUpdate 区别

1. 请简述 Unity 中协程的原理。

参考答案

协程本质上是 Unity 基于 IEnumerator 做的一种分步执行机制。带有 yield return 的方法会被 C# 编译器转换成状态机对象;Unity 在主线程中调度这个 IEnumerator,通过不断调用 MoveNext() 来推进执行。
当协程运行到 yield return 时,会暂停当前执行并把控制权交回 Unity 主循环,Unity 再根据返回对象决定何时恢复,例如:

  • yield return null:下一帧继续
  • yield return new WaitForSeconds(x):延迟一段时间后继续
  • yield return new WaitForFixedUpdate():下一个物理帧继续
    它看起来像异步,是因为逻辑被拆到了多个时机执行,但它本质上不是多线程,仍然运行在主线程。协程适合延时、等待、分阶段流程和分帧处理,不适合直接解决阻塞 IO 或重计算问题。

当前结果

已掌握(已从错题本删除)


2. 协程既然还是运行在主线程,那为什么很多人会误以为协程能“解决卡顿”?它到底能解决什么问题,不能解决什么问题?

参考答案

协程能缓解的是单帧工作量过大导致的卡顿,而不是让耗时操作本身变快。
它适合把大量逻辑拆成多段、分散到多帧执行,例如分批创建对象、分阶段加载、逐帧处理列表。
它不能解决真正的阻塞型操作,也不能让复杂计算自动并行化。
如果在协程某一步里直接做同步文件 IO、大块解析或重计算,那么那一步依然会阻塞主线程。

当前结果

已理解


3. 如果把一个 100 万次循环写进协程里,但循环中间没有任何 yield return,那它还会不会卡主线程?为什么?

参考答案

会卡。
协程是不是“分帧”,不取决于它是不是 IEnumerator,而取决于执行过程中有没有真正遇到 yield return
如果一大段循环中间没有任何 yield,那它会在当前这次调度里一次性跑完,本质上和普通函数一样,仍然是主线程同步执行。

当前结果

已理解


4. AwakeStart 两个生命周期函数,分别在什么时候被调用?它们的区别是什么?

参考答案

Awake 在脚本实例被加载时调用,且一定早于 StartStart 在脚本启用后、第一次 Update 之前调用。
对于场景启动时就已经存在且 active 的对象,Unity 会先执行完所有对象的 Awake,再开始任何对象的 Start
Awake 更适合做自身初始化、缓存引用、单例赋值;Start 更适合做依赖其他对象初始化完成后的逻辑。
需要注意:不同对象之间 Awake 的先后顺序默认不可靠,不能依赖。

当前结果

已掌握(已从错题本删除)


5. 如果一个 GameObject 是 active 的,但它上面的某个 MonoBehaviour 脚本组件是 disabled,那么它的 AwakeStart 分别会不会执行?为什么?

参考答案

GameObject 为 active、脚本组件为 disabled 的情况下:

  • Awake 会执行
  • Start 不会立刻执行,只有等脚本被启用后,才会在第一次 Update 之前调用
    原因是 Awake 关注的是脚本实例加载时机;Start 关注的是脚本真正进入启用运行状态的时机。

当前结果

已理解


6. 如果一个 GameObject 在场景开始时是 inactive,后来运行时被激活,那么它的 AwakeOnEnableStart 会按什么顺序执行?

参考答案

如果一个 GameObject 在场景开始时是 inactive,那么它的 AwakeStart 都不会在场景启动时立刻执行。
等它后续被激活,并且脚本本身是 enabled 时,通常顺序是: Awake -> OnEnable -> Start

当前结果

已理解


7. 对于场景启动时就存在的多个对象,Unity 能不能保证 A 对象的 Awake 一定先于 B 对象的 Awake?那能不能保证所有对象的 Awake 都先于任何对象的 Start

参考答案

默认情况下,Unity 不能保证 A 对象的 Awake 一定先于 B 对象的 Awake
但对于场景启动时已存在的对象,可以保证所有对象的 Awake 都会先于任何对象的 Start
如果业务上需要明确顺序,应通过 Script Execution Order 显式配置,而不是依赖默认行为。

当前结果

已理解


8. 请简述一下对象池是什么,在游戏开发中我们什么时候会用到它?

参考答案

对象池是一种对象复用机制。对于会被频繁创建和销毁的对象,不是每次都 InstantiateDestroy,而是预先创建一批对象,需要时从池里取出,使用完再回收到池中。
这样可以减少运行时频繁分配内存和销毁对象带来的 CPU 开销与 GC 压力。
适合的场景包括:子弹、特效、飘字、临时敌人、临时 UI 等高频、短生命周期、重复类型对象。
代价是需要额外管理池容量和对象状态重置。

当前结果

已掌握


9. 对象池里的对象在“回收”时,通常要重置哪些状态?你至少说 5 个,不要只答 SetActive(false)

参考答案

回收对象时,至少要考虑以下状态重置:

  • Transform(位置、旋转、缩放)
  • 业务数据(血量、目标、阶段状态等)
  • 计时器 / 冷却 / 计数器
  • Rigidbody / 物理状态(速度、角速度、受力)
  • Animator 参数 / Trigger / 播放状态
  • 粒子系统 / TrailRenderer
  • UI 文本、进度条、透明度
  • 事件绑定 / 委托
  • 协程 / Tween / 定时任务
  • AI / 导航状态
    核心原因是:对象池真正难的不是“存起来”,而是“复用后状态一致”。

当前结果

待复习(仍在错题本)


10. 对象池最大的坑是什么?为什么只 SetActive(false) 往往不够?

参考答案

对象池最大的坑是:

  1. 对象复用后的状态一致性
  2. 池容量策略控制
    只做 SetActive(false) 往往不够,因为对象虽然被隐藏了,但内部数据、物理速度、动画参数、事件绑定、协程等可能仍然残留。
    如果不重置,这些脏状态会在下次复用时一起带出来,造成隐蔽 bug。

当前结果

已理解


11. 请解释一下 Unity 中 UpdateFixedUpdateLateUpdate 的区别,以及它们分别适合处理什么逻辑。

参考答案

  • Update:按渲染帧调用,通常每帧一次,适合输入和普通逐帧逻辑。
  • FixedUpdate:按固定时间步长执行,属于物理更新循环,适合 Rigidbody 相关的物理逻辑。
  • LateUpdate:在所有 Update 都执行完之后调用,适合依赖其他对象本帧最终状态的逻辑,比如相机跟随。
    常见放置方式:
  • 输入:Update
  • 物理:FixedUpdate
  • 相机跟随:LateUpdate

当前结果

已掌握(已从错题本删除)


12. 角色移动、读取输入、给 Rigidbody 加力、第三人称相机跟随,这四件事分别更适合放在哪个函数里?为什么?

参考答案

  • 读取输入:放 Update,因为它跟每帧渲染节奏一致,输入响应更及时。
  • Rigidbody 加力:放 FixedUpdate,因为这是物理更新循环。
  • 第三人称相机跟随:放 LateUpdate,因为它要等角色本帧的移动逻辑先完成。
  • 角色移动:要看实现方式。
    • 如果是 Rigidbody 驱动的物理移动,更适合放 FixedUpdate
    • 如果是普通 Transform / CharacterController 式非物理移动,更常见放 Update

当前结果

已理解


13. FixedUpdateUpdate 在调用频率上的本质区别是什么?为什么这会影响物理和输入的放置位置?

参考答案

Update 按渲染帧执行,通常每帧一次;
FixedUpdate 按固定时间步长执行,所以可能一帧执行多次,也可能某一帧一次都不执行。
正因为两者频率机制不同:

  • 输入通常放在 Update 里采样,更贴近画面刷新节奏
  • 物理逻辑通常放在 FixedUpdate,因为物理系统更需要稳定的固定时间步长
    也就是说,输入更关心“这一帧有没有输入”,物理更关心“每一步是不是按均匀时间推进”。

当前结果

已理解