performance optimization


I'm currently stuck, cause my pinball game does not perform well. Frames seem to stutter, although the profiler shows about 90 FPS. The problem gets worse if I start the game as standalone (fullscreen, dual monitor setup with horizontal span => 2560 x 1024).

The scene is quite simple. According to stats window, there are 200k triangles, 131k vertices and 340 Draw Calls.

Because of high velocities, I won't like to decrease fixedDelta time (which is 0.02). I use physics for controlling flippers, the "start catapult" and for pinball-collisions.

When I disabled most of the mesh renderers, the performance was slightly better, but still stuttering.

What I did so far to enhance performance:

  • use #pragma strict to force static typing (no dynamic type inference)
  • Call Find and GetComponent functions only in Awake(), never per frame.
  • Removed Rect object creation from OnGUI function

I'm afraid I started to enhance at the low level before really knowing where the performance drop comes from... Any ideas how to track the issue?

I'd like to use the profiler, but it drops performance even more. According to profiler, most of the time is spent in Camera.Render (in editor mode on one monitor) although the scene is quite simple, and in Physics.Simulate. I don't use any fancy Quality Settings (they are set to "Good.").

Can we trust the profiler or is it more reasonable to test timing from within my scripts only? One thing I noticed is, that whenever I hit a certain key in standalone fullscreen mode (for launching the pinball out of the "start catapult"), performance drop is worst, although barely noticeable in editor mode - according to profiler, Scripts aren't a real issue...

The machine I run the game on: Win XP, Core2Duo 2.0GHz, 2 GB RAM, GeForce 8600 GT 512MB.

You should expect to be render-bound, not physics bound (rendering budget can be adjusted in quality settings, physics can't).

Try to recursively GetComponentsInChildren() and hide all the meshes and see if just simulating physics is hitting you. If so, you can try to reduce the number of active rigidbodies and/or avoid embedding colliders in complex transform heirarchies (the physical space is flat w/o parent-child relationships, and needs to model these with implicit joints).

In a pinch, you could try to reduce the number of solver iterations the physics does to get a one-time cut-accuracy-for-speed bump, but it's generally good to hold that in your back pocket as a worst-case-scenario, instead of relying on it.

Have you enabled rigidbody interpolation for all fast-moving objects, such as the ball?

I've uploaded my (Windows) project including all graphics and script features:


EDIT: you also need to install Visual Studio 2008 redistributables: and maybe you have to copy pthreadVC2.dll of my installation into the Unity\Editor installation folder.

EDIT: here's my project without the Windows related stuff:

BTW: This morning I've tested the scene on a high end graphics machine: Quadro FX 3700, 1GB VRAM, 12 GB RAM, Xeon Processor, resulting in the same issue. Weird!

For correct display you should setup your dual screen monitors as horizontal span with a resolution of 2560x1024 (so 1280x1024 each).

The pinball game runs in fullscreen mode. Input: I: to toggle input mode (either get input from COM interface or keyboard. Default is COM). Space: Launch ball Left Ctrl: left flipper Right Ctrl: right flipper ESC: end game R: reset ball

I know collider geometry could be reduced, but as I stated earlier this didn't help. Maybe anyone can tell where my mistake is...? Or if Unity is causing frame stalls from time to time...? Please help!

Sounds like you should increase the physics framerate, which is 50fps by default at .02. Therefore if the game runs faster than 50fps, the ball won't update every frame, which could cause some stuttering (although using interpolation should largely fix that). With a pinball game, I'd be inclined to use 100fps for physics anyway.

Problem solved. The issue was due to the plugin, where I'm accessing a serial port. I didn't notice the mistake there, because Unity seems not to have the plugin updated when I tried to reload it.