Under the hood….

Someone in the Unity forums asked me how Zombox maintains performance even with all the active colliders and rigidbodies within the environment. I figured it would be a good time to explain some of what goes on behind the scenes in the Zombox engine.

The game uses a fairly complex pooling system I wrote to create the environment.

Firstly, because everything in the game procedurally generated from a small set of prefabs, I can easily enable/disable anything that is not directly within the view frustum. Not just disable its renderer…but literally remove it completely, and use its gameobject to create something that *is* in screenspace. This means the total number of active rigidbody/static colliders in the game is limited to what’s visible in screen space, because only a finite set of gameobjects are used to create everything. The entire city features over 350 buildings (each with many walls, props, etc….about 40,000 different “pieces” are required to create the whole city), many roads, rivers, etc…but all of that is generated using only 300 gameobjects, which are recycled constantly. This keeps the game running really fast and there are no load times in the huge sprawling environment once the initial city-generation load time is passed (and that initial load time only takes a few seconds).

Secondly, the pooling system also manages the number of active non-kinematic rigidbodies, so that I can easily control the max number of rigidbodies in the game at any time. The downside is that the same small group of rigidbodies are recycled for new zombie/building/environment chunks that are generated, so as new chunks pop in (like when a wall is crumbled, or a zombie is killed), old chunks pop out. But generally this effect isn’t that noticeable and doesn’t detract from the gameplay.

I think I’ve got about 30 rigidbodies in the building-debris-rigidbody pooling system, a dozen in the zombie-limb pooling system and a few more in the environment-debris pooling system. With all of those rigidbodies active and colliding, the game runs at about 20-30 fps on the iPhone 3GS, and 30+ fps on the iPhone 4.

The following gif showing the environment pooling system in action. The white lines represent zombie paths, and the roofs are disabled so you can easily see all the objects necessary to build all the walls of each building.



6 Responses to “Under the hood….”

  1. Atsuko says:

    I used a Collision Tag on the tube and changed the Shape from Automatic to Static Mesh. Basically, look at the rigid body on the Tube and make sure you are using the pnogylos and not a basic primitive shape for the dynamics. The text could be vibrating if you are also trying to animate it. When you use Rigid bodies, you have surrendered control to physical dynamics and have less control than keyframing. If that’s not the issue, then you need to look at the rigid bodies settings to allow it to come to a rest and be less sensitive to forces.

  2. Unislash says:

    Hey Tyson,

    Thanks for the view inside the magic. One question: you say you’re actually removing objects from the scene that aren’t on camera to reduce lag but recycling the game object for something that is on camera… does that mean you swap out the components on the game object to “make” that object that’s on camera? What happens if there’s children objects that need to be instantiated for said object–wouldn’t that take a comparable amount of resources to make as it would to not recycle the game object and instantiate “like normal”?


  3. Tyson Ibele says:

    @ Unislash:

    Hey, all the gameobjects that are used in the pool have the same components. A script that controls special actions (for doors), a meshrenderer, a rigidbody, a collider and a meshfilter. As the procedural system loads/unloads geo, it reads from city data that’s generated when the game loads which tells it what mesh should be applied to a pooled object’s meshfilter, what shader, what collider size/center-position, etc. As the objects are swapped in and out, they take the shape of whatever they need to, as directed by the pool manager.

  4. Unislash says:

    Awesome. And is it always more efficient to do all of that swapping? Or is it more effective only when you have a bunch of colliders?

  5. Tyson Ibele says:

    @ Unislash:

    It’s more efficient with or without the colliders, actually. In my tests, I found that the frustrum culling function alone takes quite a bit of time on iOS devices when there are tens of thousands of GameObjects on screen.

    For some perspective, during gameplay there are always 9 ’tiles’ of the map always visible (a map which is around 64×64 tiles large), and it takes about 200-300 objects in the pool to create the objects necessary to fill those tiles. So if the recycle pool didn’t exist, it would take around 70,000 gameObjects to create all the objects in the city…..that’s a lot of processing time when each one has to be checked to see if it’s in frame — let along processing time for collisions.

  6. Hannelore says:

    I see a lot of interesting posts on your blog.
    You have to spend a lot of time writing, i know how
    to save you a lot of time, there is a tool that creates unique, google friendly articles
    in couple of seconds, just type in google – k2 unlimited content

Log in or Register

Leave a Reply

Your email address will not be published. Required fields are marked *