On this page
What NOT to do in Unity: the most common mistakes to avoidLast updated: December 2018
What you’ll get from this page: A guide that you will want to reference throughout your development. Follow these great tips from Unity field engineer Valentin Simonov that will help you set up a smart and efficient development pipeline, and ultimately ship better and more performant content.
The most important part of any software development project because decisions made in the this phase will be difficult to change later on in the development cycle.
Lack of research before starting a project
- Check that all planned features actually work on all target platforms.
The minimally supported devices for your project aren’t specified
- Define the minimally supported device(s) for your content.
- Have them available to your development and QA teams.
- Do this, and you’ll be able to set a realistic performance and frame budget.
Frame and asset budgets don’t get set early on.
- Define budgets for:
- models — how many vertices is the target device able to render?
- assets — how detailed should models and textures be?
- scripts and rendering — what % of the frame do you have for logic, rendering, effects and other subsystems?
Scene and prefab decomposition don’t get set early on.
... or (in other words) everyone works in the same scene.
- Split levels into (additively loaded) scenes.
- Move separate objects into prefabs and edit them in separate scenes.
- Agree on the main scene locking mechanism.
The asset pipeline process is poorly planned
This process is all about getting assets according to the specs from artists into the project.
- If possible, involve a technical artist from the beginning to define this process.
- Define clear guidelines on asset formats and specs.
- Add import time tests.
You don’t have a Build and QA process lined up
- Set up a build machine, or, turn on and set up Unity Teams.
- How will a feature be published to the release build?
- How are the new builds tested?
- Are these tests automated?
- Are statistics recorded?
The project is not started from scratch after initial prototypes
After building a prototype and getting it approved by the management, strongly consider starting it from scratch.
- Decisions made during prototyping usually favor speed.
- Basing your game on a bunch of hacks is not a good start for any project.
Wrong practices and mistakes during development slow the team down and undermine the quality of the final product.
Version control is set up incorrectly
- Use text serialization (by default in Unity).
- Set up built-in YAML merge tool. See more about SmartMerge here.
- Set up commit hooks. See more here.
The Cache Server is not used
- Switching platforms decreases development speed.
- Make sure to set up the new open source Cache Server for your team.
Static data is stored in JSON or XML files
- This results in slow loading.
- Parsing generates garbage.
- Instead, for built-in static data use ScriptableObjects with custom editor tools.
The project contains unused assets, plugins and duplicated libraries
There’s a great chance that unused assets in your project are getting built into the game. Make sure that you don’t leave garbage in your project — if you set up a version control system, restoring files should be easy.
- Check what dependencies assets from the Asset Store drag into the project. You might be surprised realizing that you have 5 different JSON libraries in the project.
- Outdated assets and scripts from early prototypes.
- The practice of moving old assets to "removed" folder still results in resources and scripts being built into the game.
Repetitive actions require manual work
- For every repetitive task there should be a script automating it.
- Make sure that you can "play" the game or interactive content from any scene.
- Automate all the steps of build process, so that the application can be built with Cloud Build or locally with a press of a button.
Profiling your project in the Editor only
- Always profile the content on your target device; if you profile in the Editor only, you can miss actual performance bottlenecks.
Not using both built-in and platform-specific profiling and debugging tools
- Use the built-in Unity Profiler, Memory Profiler and Frame Debugger.
- Platform-specific tools include Xcode Instruments, Mali Graphics Debugger, Renderdoc, etc.
Profiling and optimization are done too late in the development cycle
- The longer you wait with profiling, the larger the performance costs can become.
- Start profiling early on, so you’re sure your project fits into the frame, memory and disk size budgets.
Optimization is not based on test data
- Make sure that you are optimizing actual bottlenecks.
- Use the Tools specified above to gather correct data.
Not enough knowledge about your target platform(s)
- Make sure you have enough knowledge about your target platform(s).
- Desktop, mobile and console platforms have very different bottlenecks.
Assets (models, textures, sounds) take up most of the size of your game. Having just one wrong mesh in the project can nullify all the optimizations your programmers have done.
Sprite atlases are not set up correctly
- Use 3rd-party tools (like Texture Packer) to create atlases or group sprites together in Unity. This will reduce the number of draw calls in the game.
Texture settings are not set up correctly
- Make sure that you know the right texture settings for the target platform:
- What compression does the platform support?
- Do the textures need mip maps?
- Set up an automated way to apply these settings for new textures using AssetPostprocessor API as shown by this project
- Prevent artists from committing textures with wrong settings.
Asset Bundles contain duplicated textures
- It is easy to make a mistake in setting up Asset Bundles build system. Get good guidelines here. It is especially bad for duplicated textures.
- Use Asset Bundle browser to track dependencies.
Poor practices and mistakes in code architecture and development result in low productivity.
Code is very abstract and hard to follow
- Abstract Enterprise code is rarely justified.
- It makes code harder to reason about.
- It runs slower and IL2CPP has to generate more code.
Architectural conventions are not defined or poorly documented:
- Avoid writing your code so that you are using different methods for accomplishing the same task, for example using different:
- Config formats (files, properties, assets).
- Events (Unity events, C# events, SendMessage).
- Which manager is responsible for which objects?
There’s not a thorough understanding of Unity frame loop
- When Awake, OnEnable, Update and other methods are called.
- When coroutines are updated.
- How FixedUpdate is executed.
Script initialization logic relies on Unity execution order
- Either "it just works this way" or abusing Script Execution Order.
Framerate is not taken into account when scripting logic or animation
- Use Time.deltaTime for FPS independent scripts.
High CPU usage results in "laggy" gameplay experience and drains the battery faster.
Too many scripts have Update() method
- Native -> Managed calls have some overhead. See this blog post for more details.
- Use custom managers instead.
All custom Behaviours inherit from an abstract class with Update/Awake/Start methods defined
- Now all your scripts have Update() method.
All game systems are updated every frame
- Define how frequently you want to update different systems in your game/content such as:
- Moving objects.
- AI and path finding.
- Logging and saving game state.
- Other "heavy" systems.
Data and references to objects needed frequently are not cached
Cache data you need frequently:
Frequently instantiated objects are not pooled
- Instantiating objects is slow.
- Create pools of objects at the start of the game.
- Reuse objects instead of creating new ones.
Memory is allocated every frame
- Even small allocations every frame will sooner or later cause a GC spike.
- Try to eliminate ALL allocations.
Memory allocating APIs are used instead of non-allocating alternatives
- String concatenation.
- Unity APIs returning arrays:
- Physics.RaycastAll, Mesh.vertices, GetComponents, etc.
High GPU usage results in low framerate, drains battery faster and the game/content is perceived as "running slow".
For mobile: The project has too much overdraw
- Mobile GPUs can only draw so many pixels per second.
- Overdraw is one of the biggest performance bottlenecks on mobiles.
- Don’t draw unnecessary transparent images.
- Use more complex meshes to crop fully transparent areas.
For mobile: The shaders are too complex
- Don’t use Standard Shader on mobiles.
- Create custom specialized shaders.
- Use simplified versions or turn off some effects for low-end devices.
Too many dynamic lights are used with Forward rendering
- Every light adds a render pass for every illuminated object.
Wrong settings in the project break dynamic batching
- Objects must be "similar" to be dynamically batched.
- Frame Debugger shows why certain objects were not batched.
LODs are not used or are not set up correctly
- LODs let rendering further objects take fewer resources
Unity UI is a very artist friendly tool, but it is rather easy to set it up incorrectly, so it would consume much CPU and GPU resources.
Different resolutions and aspect ratios are not taken into account
- Test UI on devices with different resolutions and aspect ratios
- Sometimes it is better to create different UI screens for different devices
Animated elements are in the same Canvas
- When an element changes Canvas has to create a new combined mesh
- For complex Canvases this might be costly
- Move animated elements to separate Canvases
"Opening" a new window is not optimized
- When a new window or a big chunk of UI is created the game experiences a noticeable lag. You should minimize this effect.
- Make UI windows less complex.
- Split UI in parts.
- Cache windows.
Lists contain large amount of items
- Dynamically reuse list items instead of creating all of them at once.
- Create a nested Canvas in the list.
- Use open source implementations, such as this.
Unity Buffbot is here to make your work easier
Sign up to receive weekly tech and creative know-how from Unity experts.Subscribe