为什么要池化对象
本课属于 Coddy Unity 学习旅程的“Unity 游戏架构”单元。第 46 课,共 64 课。
一把每秒发射 10 颗子弹、持续 1 分钟的枪,会调用 Instantiate 600 次、Destroy 600 次。每次 Instantiate 都会复制预制体及其所有组件,并运行这些组件的 Awake、OnEnable 和 Start。每次 Destroy 都会运行 OnDisable 和 OnDestroy,并把对象占用的内存留作垃圾。C# 的垃圾回收器会在之后释放这部分内存,它的工作会落在某些帧上,而不会落在另一些帧上,因此会出现卡顿,在较慢的手机上尤其明显。
对象池会保留对象,而不是销毁它们。用过的子弹会通过 SetActive(false) 关闭并放回对象池;下一次射击时,会从池中取出一颗子弹并将其开启。只有对象池为空时才会运行 Instantiate。射击开始后的头几秒过去后,发射子弹不会再创建新对象,也不会留下垃圾。对象重用时,Awake 和 Start 不会再次运行:它们只会在对象创建时运行一次。每次使用时都必须重置的内容,例如计时器、生命值或速度,会在 OnEnable 中重置,或者由取出对象的代码重置。
对象池适用于那些经常创建后又丢弃的对象:子弹、火花、伤害数字,以及波次游戏中的敌人。对于只出现一次的头目,或偶尔打开的菜单,对象池就没什么用。对象池会一直为其中未激活的对象占用内存,因此应保留合理数量,并释放多余对象。
亲手试试
这节课没有代码挑战。
Unity 游戏架构中的所有课
自己练习: Unity 在线编辑器