San Mateo 2023 Flashcards
Animators: UI
Something not mentioned on this slide,is the use of animators for UI. The animator system is particularly inefficient when used with Unity UI. Animators animating a property of a UI element will force it to rebuild the Canvas and Layout every frame, and cause unnecessary batching work.
So we recommend avoiding animators with UI.
Physics Simulations: What Are They
Physics ensure that the objects correctly accelerate and respond to collisions, gravity, and various other forces. Physics can apply to your 3D, 2D, object-oriented, or data-oriented games.
Physics Simulations: Performance Cost
Physics calculations can be quite expensive, especially on mobile devices. The total amount of physics calculation depends on the number of non-sleeping rigid bodies and colliders in the scene
and the complexity of the colliders. Even if these aren’t present in your scene, depending on the settings of your game Physics can still have CPU overhead, due to to how frequently it’s being simulated, despite not being used. There are ways to reduce this performance cost, or eliminate it altogether if Physics aren’t necessary for your project.
Physics Simulations: Disable or Reduce Collisions
There are a few possible areas where you can disable or reduce collisions. For instance avoid using the collision module for your particle systems unless you need it. Additionally, Mesh Colliders are generally expensive, so consider substituting more complex Mesh Colliders with primitive or simplified ones to approximate the original shape.
Physics Simulations: Change FixedUpdate to Update
If you do need physics in your game, but your logic doesn’t strongly depend on deterministic physics calculations, we suggest moving fixedupdate logic to Update. That is because this has the frequency of the physics system, and is called every fixed frame rate frame. Like I had mentioned, this is by default set at .02 in your physics settings, so could potentially be called twice per frame.
Physics Simulations: Check Project Settings
There are a few changes you can make in your project settings to reduce the impact of physics on your performance. The one mentioned broadly in the project reviews was disabling Auto Simulation. Auto Simulation has CPU overhead due to housekeeping operations of the physics simulations, and will automatically run the physics simulations. If you don’t need Physics simulations running constantly, you can choose to disable this, but enable it manually to give you explicit control over when physics runs.
You can also disable Auto Sync Transformations in your project settings to avoid excess synchronization that occurs before every raycast operation.
Physics Simulations: Adjust Fixed Timestep
The physics engines work by running on a Fixed Timestep, which defines the time delta used by each Physics Step. The default value is at 0.02, which equates to 50 frames per second. If you were to leave your physics Timestep at this default value with a target frame rate of 30 fps, it would be called twice per frame. If you need physics in your game, you can increase the Fixed Timestep so Physics aren’t as heavy on the CPU. This can be done via Time Manager or during runtime using the Time.fixedDeltaTime property.
Managed Allocations and Garbage Collection: What is it/How does it work
Automatic memory management allows you to write code quickly and easily, and with few errors without needing to manually request the release of memory. The garbage collector manages a section of memory called the Managed Heap, and will periodically release and allocate memory. However, this convenience does come with memory and performance problems if you’re not careful;
Managed Allocations and Garbage Collection: Performance Cost
- this memory management process impacts runtime performance, because allocating managed memory is time-consuming for the CPU, and could result in stuttering because the garbage collector is unpredictable with when it releases and allocated memory.
- Garbage collection might also stop the CPU from doing other work until it completes.
- Also, when the garbage collector releases an object, the memory it occupied is freed up. However this free space doesn’t become a part of a single pool of free memory, and instead the memory becomes fragmented.
- This ultimately leads to the heap expanding, because the managed heap can’t find or free up a single block of contiguous memory to assign new allocations.
Managed Allocations and Garbage Collection: Avoid Temporary Allocations
It’s common for an application to allocate temp data to the managed heap in each frame, but this does affect the performance as I mentioned before. If a program allocates one kilobyte (1KB) of temporary memory each frame, and it runs at 60 frames per second, then it must allocate 60 kilobytes of temporary memory per second. Over the course of a minute, this adds up to 3.6 megabytes of memory available to the garbage collector. So try to get to as close to 0 bytes allocated per frame as possible. As an example of an issue with managed allocations, in one game your team was seeing around 32.8 Kilobytes allocated every frame. Per frame allocations can quickly add up so this is particularly important, and it can cause runtime hitches caused by Garbage Collection.
Managed Allocations and Garbage Collection: Use Project Auditor
Most of the code paths that cause managed memory allocation can be easily spotted with the help of the Project Auditor. In particular, the code analysis section of the tool that uses Roslyn Analyzers helps to quickly identify the location of managed memory allocations. We recommend that teams try the tool and strive for having code without allocations during gameplay.
Managed Allocations and Garbage Collection: Avoid Debug Logging
Debug logging is great for diagnosing issues, but it does create strings, which are subject to garbage collection. You should aim to remove logging from your final builds. If left in the final build, these calls will still try to write to some console, and the string will still be allocated. You can create a wrapper to make a custom logger, which can enable or disable logging in your build, but will still create string garbage from where the log function was called from.
Resources Folder: What is it
This is the system that allows developers to store Assets within one or more folders named Resources and to load or unload Objects from those Assets at runtime using the Resources API.
The Resources folder may be useful in some trivial cases, if the content is:
- Generally required throughout the project’s lifetime
- Not memory intensive
- Not prone to patching, or does not vary across platforms or devices
The resources folder can be very useful for fast prototyping, but for full production it presents many problems and we don’t recommend using it for several reasons
Resources Folder: Performance Issues
It can bloat the size of a project’s build, lead to uncontrollable excessive memory utilization, and significantly increase application start up times. Every asset within Resources folders, and every asset it references, are included in Resources system data. Because of this, the time required to initialize the Resources system increases with the number of files within Resources folders.
Another common issue with Resources folders is that everything inside a Resources folder will be included in the build, even debug and placeholder assets. Unity can strip unused assets in other folders to remove them from builds, but it has no way of knowing which assets might be loaded from Resources at runtime, so it does not discriminate.
Asset management because very difficult as the number of assets in those folders increase.
The Resources system makes it hard to deliver custom content to specific platforms and eliminates the possibility of incremental content upgrades.
Resources Folder: Switch to Addressables
Using Addressables can improve runtime memory by introducing weak references to prevent assets from being loaded. Weak references mean that you have control over when the references asset is loaded into and out of memory, and the addressable system will find all the necessary dependencies and load them too. Addressables can be daunting to set up, but it’s worth it. We recently put out a blog about addressables best practices, and have a specific guide about setting up addressables for a mobile game with frequent content updates that might come in handy.
We do recommend completely switching to addressables, because if you use asset bundles and resources together in tandem, that can lead to duplication of assets, leading to further memory bloat.