[Unity] 利用Culling Group实现LOD和剔除逻辑
注: 至于性能没有做过测试!!! 如果认为有问题那Unity的LodGroup 都没必要用!
官方手册:
https://docs.unity3d.com/2018.2/Documentation/Manual/CullingGroupAPI.html
https://docs.unity3d.com/ScriptReference/CullingGroup.html
https://docs.unity3d.com/ScriptReference/CullingGroupEvent.html
该API于Unity 5.2和之后版本出现
官方文档中提到一个优化:
Mass object movement & CullingGroups
As mentioned in the section on Transform Manipulation, moving large Transform hierarchies has a relatively high CPU cost due to the propagation of change messages. However, in real development environments, it is often impossible to collapse a hierarchy to a modest number of
GameObjects
.
At the same time, it is good development practice to only run enough behavior to maintain the believability of the game world while eliminating behavior the user will not notice – for example, in a Scene with a large number of characters, it is always more optimal to only run Mesh-skinning and animation-driven Transform movement for characters that are on-screen. There is no reason to waste CPU time calculating purely visual elements of the simulation for characters that are off-screen.
Both of these problems can be neatly addressed with an API first introduced in Unity 5.1:
CullingGroups
.
Instead of directly manipulating a large group of GameObjects in the scene, change the system to manipulate the Vector3 parameters of a group of BoundingSpheres within a CullingGroup. Each BoundingSphere serves as the authoritative repository for a single game-logical entity’s world-space position, and receives callbacks when the entity moves near/within the frustum of the CullingGroup’s main
camera
. These callbacks can then be used to activate/deactivate code or components (such as Animators) governing behavior that should only run while the entity is visible.
大量对象移动和剔除群组
如同 Transform Manipulation 那节所述,移动有超大层级结构的 Transform 对象会造成很大的 CPU 消耗。但在现实的环境中,通常不可能将对象结构精简到最少的 GameObjects。
同时,如果可以最好在玩家不发现的前提下,删除玩家看不到的行为。例如,在有大量角色的场景时,只针对屏幕可见范围内的角色计算网格蒙皮(Mesh-skinning)和处理角色动作等等。不需要浪费CPU的资源在计算屏幕外看不到的角色行为。
这两个问题都可以透过 Unity 5.1 导入的 API 来完美解决:CullingGroups。
与其直接操作场景中一大群的 GameObject,而是改变系统操作 CullingGroup 里的一组 BoundingSpheres 的Vector3 参数。每个 BoundingSphere 作为这些 GameObject 在游戏世界中的代表,当 CullingGroup 接近或进入CullingGroup 设定的主镜头的锥体范围内时成员才会收到 callback。然后这些 callback 就可以用来执行启用/停用的程序代码或组件(例如Animators)让物体执行在可见范围内该有的行为。
https://docs.unity3d.com/ScriptReference/CullingGroup.html
https://docs.unity3d.com/2018.2/Documentation/Manual/CullingGroupAPI.html
https://unitycoder.com/blog/2018/10/31/find-nearby-objects-using-cullinggroup/
有两种方式来触发CullingGroup的事件:
- 相机裁剪
- 相对距离(相机或主主角相对于目标物体的距离)
这两种方式可以混用,也可以只使用其中一个
应用场景有:
- 粒子当前不可见时,将其暂停
- 粒子与相机或主角在不同距离阶段时,使用不同的简化版粒子。
- ai不在视野内时停止更新
剔除组是Unity API的一部分,它有效地允许我们创建自己的自定义LOD系统,作为一种方法来提出我们自己的动态替换某些游戏玩法或渲染行为的方法。我们可能希望应用LOD的一些示例包括 用具有较少骨骼的版本替换动画角色,应用更简单的着色器,远距离跳过粒子系统生成,简化AI行为等等。它在游戏玩法领域也有其他用途,
例如确定某些敌人出生点当前是否对玩家可见或者Player是否正在接近某些区域。有各种各样的可能性可与Culling Group系统一起使用,值得考虑。当然,花在实施,测试和重新设计场景上的时间可能很重要。
unity_2017_game_op