UPL5-11——禁用未使用的脚本和对象
UPL5-11——禁用未使用的脚本和对象
本章代码关键字
1 | OnBecameVisible() { } // 当依附对象存在Renderer且对任一摄像机(主摄像机、UI摄像机、小地图摄像机、Scene 视图摄像机等)可见时调用 |
禁用未使用的脚本和对象
所谓的禁用未使用的脚本和对象,是指在 特定游戏类型中 对那些不在玩家视野内,或者离玩家太远的游戏对象,采用不处理他们的优化方案,达到节约性能的目的
尤其是项目内容庞大,场景复杂或者设备性能有限的情况下,这种优化手段非常实用
注意:这种优化方案,只适用于那些禁用对象不会对游戏过程产生明显影响的游戏
Unity 的视锥剔除和遮挡剔除
-
视锥剔除:
自动剔除摄像机视野之外的对象
只影响渲染系统,不会绘制被剔除的对象 -
遮挡剔除:
剔除虽然在摄像机视野内、但被其他物体挡住的对象
同样是只影响渲染系统,防止浪费 GPU 绘制不可见的物体关于遮挡剔除,详细可见:UPL9-4——遮挡剔除
也就是说,Unity 中的视锥剔除和遮挡剔除其实只会优化 GPU 渲染层面的性能
对象身上依附的各种组件,还是会照常执行,并不能起到禁用未使用的脚本和对象 优化 CPU 性能的目的
OnBecameVisible 和 OnBecameInvisible 函数
-
OnBecameVisible():在渲染器(Renderer)对 任一摄像机(主摄像机、UI摄像机、小地图摄像机、Scene 视图摄像机等) 可见时调用 -
OnBecameInvisible():在渲染器(Renderer)对 任何摄像机(主摄像机、UI摄像机、小地图摄像机、Scene 视图摄像机等) 都不可见时调用
1 | private void OnBecameVisible() |
注意:
- Scene 视图摄像机也会导致调用该函数
- 所依附的对象上必须有
Renderer渲染器相关组件 - 对象失活后,由于渲染器也会失活,这两个函数不再响应
- 即使这两个函数所在的组件失活,只要渲染器存在,就会响应
利用距离禁用对象
通过判断需要禁用的对象和玩家或摄像机距离过远时主动禁用对象
比如我们通过怪物、子弹等等管理器,不停判断他们和主要目标的距离
当超过需求值时主动禁用对象
1 | if (Vector3.Distance(this.transform.position, otherTrans.position) >= 50f) |
注意:在进行距离判断时,可以采用距离的平方(Vector3.sqrMagnitude)进行比较,这样可以减少开方的消耗
1 | if ((this.transform.position - otherTrans.position).sqrMagnitude >= 2500) |
主动判断视锥范围
Unity 中提供了一个几何工具类,其中有两个重要方法:
-
GeometryUtility.TestPlanesAABB用于判断一个AABB包围盒是否与一组平面(如视锥体)相交或包含
-
GeometryUtility.CalculateFrustumPlanes用于获取摄像机视锥体六个平面
而通过渲染器可以得到该对象的包围盒:renderer.bounds
常用于:
- 自定义检测
- 自定义剔除
- 镜头内检测
- 优化游戏对象激活与逻辑执行
等等
注意:场景中少量对象,可以放心使用该方法判断,若场景中对象过多,因采用分帧处理等等优化手段降低开销
用法:
1 | private Plane[] _planes; |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 文KRIFE齐的博客!
