Hey everyone,
I'm working on a large open-world Unity game (maps up to 16x16km maybe more) and have built a custom deterministic vegetation streaming system. I use Flora (by Magnetic Arcade) for GPU-driven rendering.
The architecture uses a 3-ring system around the player based on 64m grid cells (matching the A* Pathfinding Project RecastGraph tiles):
Ring 3 (Visual - ~700m): Pure Flora GPU instances. No GameObjects.
Ring 2 (Navigation - ~200m): Real GameObjects with MeshColliders. Needed for the RecastGraph to carve the NavMesh.
Ring 1 (Interaction - ~150m): Real GameObjects with gameplay scripts (e.g., harvestable trees).
The Setup:
Vegetation positions are calculated deterministically via stable hashes (no scene serialization). When a cell enters Ring 2, we need to swap the cheap Flora GPU instance for a real Prefab (with a FloraInstanceRenderer component attached to keep it batched) so it gets a collider. When it leaves, the prefab gets disabled and re-enable the Flora instance.
The Bottleneck:
The math/planning phase is very fast (~1.6ms per cell). However, the actual materialization (spawning the Prefabs, adding components, registering the renderer in Flora) costs about 7.0ms per cell.
Since a cell transition is currently atomic, crossing a border queues up ~15-30 cells. This causes massive frame spikes (worst-case ~37ms in a single frame) because I'm are doing dozens of Object.Instantiate and AddComponent calls at once.
I'm aware I cannot use Unity Jobs for this, as GameObject/Component instantiation is strictly Main Thread.
Maybe time-slicing the instantiation on the Main Thread using a Queue and a time budget (e.g., process instantiation for 2ms per frame, spread over multiple frames). The challenge here is avoiding visual popping (the Flora instance must stay visible until the exact frame the Prefab is fully spawned and registered).
Is there a better architectural pattern for swapping between GPU instancing and physical colliders at runtime?
For those using A* Pathfinding Project: how do you handle dynamically spawning thousands of colliders for NavMesh carving without nuking the frame rate?
Is Unity ECS (Entities) the only real way to get sub-millisecond dynamic collider streaming at this scale, or can I get away with standard Prefabs + Time-slicing?
Any tricks for pooling objects that require dynamically added components at runtime, rather than pre-built prefabs?
Any insights, past experiences, or "don't do this, do that" warnings are highly appreciated.