Join Michael House for an in-depth discussion in this video Update() overuse, part of Advanced Unity: 3D Game Programming.
In this video, I'm going to show you some techniques for optimizing one of the largest problems in scripting performance: overuse of the Update Method. The Update Method is called on every script, inside every object, every frame. This is the first stop for optimizing the performance of your scripts. The goal is to reduce the amount of code that's run each frame. This makes the frame time shorter, and when the frame time is shorter, the frame rate improves. Let's take a look at some code. Here I have an example script that I'm going to use to show you some optimizations we can implement.
Reducing the amount of code in the Update Method is the first step. These update steering and checks surrounding target methods likely don't need to be run every single frame. We can remove those and extract them into a co-routine like this by running a slow update in our start method, which will for the entire time the game object is alive start the core routine for slow update, which will only run every 0.3 seconds. Additionally, we could move these in to our FixedUpdate method, which is going to run at a time specified by unity.
That can be found in Edit, Project Settings, Time, and our fixed time step is here. The fixed time step also applies to our physics step, so be careful when changing it. If something absolutely can't be removed from the Update method, we can try to disable the script as often as possible. Here's a simple method that will sleep the script for five seconds in between updates. There are other ways to disable a script. For example, we can disable based on visibility. The Mono Behavior class provides two methods, on became invisible and on became visible.
These methods will be called when the camera can no longer see the object or the object just came into view. You can use this, for example, to disable an animation script or any other script that provides purely visible information when it can't be seen by the camera. Another large change for managing the amount of code run per frame is to do something I call flipping the responsibilities. To demo this, let's take a look at this job manager. This job manager is responsible for accepting jobs and then allowing job workers to retrieve jobs.
This system might be used in an RTS-type game where we want to que up jobs for our worker units to do. Every frame, the job workers are going to be either working or looking for work. This means that the more workers we have, the more code is being run every frame because they each have work to do in their update method. This is similar to the scenario instead of 100 enemies checking to see if a player is near enough to attack, have the player script notify an enemy when that player is near enough. This means we only have to do one range check instead of 100.
Let's take a look at this job worker as it is now. We can see that the worker update calls are logged here, and they're ever increasing. We have a number of workers checking for new jobs every frame. Now let's take a look at how we can flip the responsibility. I've written an optimized class as, well which is below here commented out. Both the job manager and the job worker. This improved version instead flips the responsibility and makes the job manager responsible for pushing jobs out to workers.
This means the workers only need to update when they have a job to do, and when they no longer have a job, they simply add their selves to the job manager list as waiting for a job. Let's take a look at this in Unity. So we see we only add 194 worker updates before all of our jobs were completed, and now we only have one manager update per second instead of hundreds of job worker updates per second. In this video, I've shown you some techniques and strategies to reduce the amount of code that's executed each frame. This is essentially achieved by running code less often or running code once for the benefit of multiple entities. It's been famously said that premature optimization is the root of all evil. However, it's also important to design with performance in mind. I've seen many people give up on their games because the performance made the game unplayable and it still wasn't complete. Compared to a large amount of software, games are very resource intensive. This means that a game developer must spend more time considering performance than most other developers
NOTE: This course requires Unity 4.5.5. The newer versions of Unity have done away with the GUI system used in this course, so the interfaces included for many of the scenes will not work with 4.6 and higher. You can download Unity 4.5.5 at http://unity3d.com/get-unity/download/archive.
- Enabling/disabling with scripts
- Translating, rotating, and scaling objects with scripts
- Working with mouse and keyboard input
- Creating custom GUI controls like progress bars
- Loading assets with scripts
- Saving games
- Creating prefabs dynamically
- Making remote procedure calls
- Synchronizing object transforms
- Finding slow code
- Optimizing data access
- Extending the editor
Skill Level Advanced
Q: In the Chapter 3 file EntityLoader.cs, I get an error: DirectoryNotFoundException: Directory 'Assets\' not found. Removing the backslash after 'Assets' fixes it, but then I run into a different error. How do I fix this?
Q: What version of Unity does this course cover?
A: This course requires Unity 4.5.5. The newer versions of Unity have done away with the GUI system used in this course, so the interfaces included for many of the scenes will not work with 4.6 and higher. You can download Unity 4.5.5 at http://unity3d.com/get-unity/download/archive.
Q: The game object in the first chapter's Mouse Input Raycasting sample doesn't appear to follow the mouse. What's wrong?
A: Please enable the Box Collider component (by activating the checkbox next to the component name) on the game object. This is not explicitly mentioned in the video, but it will ensure the raycasts collide with the game object.