General Performance Tips
From Unify Community Wiki
Revision as of 18:42, 20 June 2006 by Morgan
The following tips are not meant to be absolutes but rather guidelines for Unity users that want to learn how to make a well performing game.
- Do not have needless meshes. If you have a character in your game, it should probably be only 1 mesh. If you have a ship, it should probably only be one mesh. There is a significant overhead for each mesh Unity renders due to realities of hardware and drivers.
- One material per mesh. Each material that is rendered is treated like a separate mesh getting rendered.
- The performance gained from using lower polygon meshes under 500 polygons is minimal if at all there. The majority of graphics cards have hardware transform and lighting, which means they can process ridiculous amounts of polygons per second. Additionally there is overhead for submitting a mesh to the graphics card to render, so being really thrifty on polygons is probably only making your game look blocky.
- Starting out, make characters with about 1500-2000 polygons. This number can vary wildly, but for starting artists this should provide a good compromise between quality and performance for one level of detail.
- Each pixel light rendered is effectively another rendering pass. Pixel lights can make your game look great but don't go too nuts with them. However, using the Quality Manager to adjust the number of pixel lights rendered for each quality level is a great way to provide ample performance/quality tradeoffs in your built game.
- Spot lights are more expensive than point lights which are more expensive than directional lights. A good way to light a scene is to first get the effect you want correct. Then look at all the lights you have and see which ones are important and see if you can reduce the lights while keeping the effect similar enough.
- Point and spot lights only affect meshes within their range. If a mesh is out of range of a point or spotlight and the light is set to attenuate, the mesh will not be affected by the light thus saving performance. This way one could theoretically have many small point lights and still have good performance because they only affect a few objects. Remember, though, a mesh will only respond to the eight brightest lights affecting that mesh.
- Keep your FixedUpdate functions as lean as possible. These functions can get called around 50-100 times a second per applicable script per object, so they are a good target to optimize. If there are things that need to be only done when the display is updated, put that code inside the Update function.
- If possible, disable scripts on objects when they are not needed. If you have a large level in your game and there is an enemy kilometers away, you can probably switch off its AI script until the camera gets closer. A good way to switch on and off objects is by using gameObject.SetActiveRecursively(false) and sphere or box colliders set as triggers.
- Beware the empty Update functions. When creating new scripts with the Assets menu, they include an empty Update() function. Remove it if you don't need it as it comes at a (rather light) performance cost. This performance cost applies to all overridable functions in MonoBehaviour scripts, with Update and FixedUpdate being the main targets.
- Refer to a GameObject by the most logical component. One could theoretically write: someGameObject.transform.gameObject.rigidbody.transform.gameObject.rigidbody.transform, but there is a whole lot of needless work done there. If you want to deal with an object's Transform, refer to it in your script as such in the first place.
- More complicated looking shaders probably cost performance compared to simpler ones. The VertexLit Diffuse shader should be the fastest shader that still takes a texture and responds to lighting. However, if there are no pixel lights in the scene or if all pixel lights are off in the Quality Manager, most shaders will fall back to a more simple vertex version.
- Keep the size of textures as small as possible while still looking nice. If your graphics card does not have enough memory to keep all the textures in memory at once, they will get placed into regular system memory and uploaded to the card during rendering. This can be okay as there is a lot of bandwidth available on newer computers; however, if you go too nuts your game will completely choke on computers with low amounts of graphics memory.
- The more rigidbodies, the more processor power is required--but it also matters whether the rigidbodies are touching. A stack of many rigidbodies must process physics for all of them when one of them receives a force, at which time there can be a sudden performance drop on a low-end computer (for example, 100 rigidbodies on a 1Ghz G4 has a noticeable effect). Use fewer rigidbodies if you can, or separate them so they interact less with each other at the same time.