大家好,

我正在开发一个大型开放世界Unity游戏(地图大小可以达到16x16km或更大),并已建立一个自定义的确定性植被流式系统。 我使用Flora(由Magnetic Arcade提供)进行GPU驱动的渲染。

该架构使用64m网格单元(与A*路径寻找项目RecastGraph瓦片匹配)基于玩家周围的3个环系统:

环3(视觉-~700m):纯Flora GPU实例。 没有GameObject。

环2(导航-~200m):真实的GameObject,带有MeshColliders。 需要为RecastGraph创建NavMesh。

环1(交互-~150m):真实的GameObject,带有游戏脚本(例如可摘取的树)。

设置:

植被位置是通过稳定的哈希(无场景序列化)进行确定性的计算。当一个单元进入环2时,我们需要交换便宜的Flora GPU实例和真实的Prefab(带有FloraInstanceRenderer组件以保持批处理)以便它获得一个碰撞器。当它离开时,Prefab会禁用并重新启用Flora实例。

瓶颈:

数学/规划阶段非常快(~1.6ms每个单元)。然而,实际的物质化(生成Prefab,添加组件,注册Flora渲染器)花费约7.0ms每个单元。

由于当前的单元转换是原子的,穿过边界会导致~15-30个单元排队。这导致了巨大的帧跳(最坏情况下~37ms在一个帧内)因为我正在同时进行数十个Object.Instantiate和AddComponent调用。

我意识到我无法使用Unity Jobs来解决这个问题,因为GameObject/Component的实例化是严格在主线程。

也许是使用一个队列和一个时间预算(例如,在每个帧内处理实例化2ms,分散在多个帧内)进行时间分片来实例化对象。 但是这里的挑战是避免视觉跳跃(Flora实例必须在Prefab完全生成和注册之前保持可见)。

是否有更好的架构模式来在运行时交换GPU实例和物理碰撞器?

使用A*路径寻找项目的人们:您如何处理动态生成数千个碰撞器来为NavMesh切割而不毁灭帧率?

Unity ECS(实体)是否是唯一可以实现毫秒级动态碰撞流式的方法,还是我可以使用标准Prefab + 时间分片来实现?

在动态添加组件的对象池中,有没有什么诀窍可以避免使用预建的Prefab?

任何见解、过去的经验或“不要这样做,做那样”的警告都是非常欢迎的。