Unity Game
Development:
Common MistakesAlexander Shlygin
Solution Consultant, Unity
ash@unity3d.com
Categories
•Planning
•Development
•Asset Settings
•Programming
•CPU Performance
•GPU Performance
•UI Performance
•Miscellaneous
Common Mistakes
Planning
The most important part in any software development project.
Decisions made in this phase will be very hard to change later in
development cycle.
Planning
Lack of research
• Check that all planned features actually work on all target platforms
• Unfortunately, there are ideas which just can’t be implemented in Unity
Planning
Minimal supported devices are not specified
• Define the minimal supported device(s)
• Have them available to your development and QA teams
• Otherwise, it is impossible to argue about performance and frame budgets
Planning
Frame and asset budgets are not set
Define budgets for models (in vertices), assets (in Mb), scripts and rendering (in ms)
• How many vertices can we render?
• How detailed models and textures should be?
• How many lights will we have?
• What % of the frame do we have for logic, rendering,
effects and other subsystems?
Planning
Scene and prefab decomposition
for the project is not carefully planned
... 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
Planning
Asset pipeline is not set up correctly
The process of getting assets according to the specs from artists into the project.
• Figure out process
• Define clear guidelines on asset formats and specs
• Add import time tests
• Ideally should involve a Technical Artist
Planning
Build and QA process is not set up correctly
• Set up a build machine
• How a feature is published to the release build?
• How are the new builds tested?
• Are these tests automated?
• Is statistics recorded?
Planning
The project is not started from scratch
after initial prototypes
• Decisions made during prototyping usually favor speed
• Basing your game on a bunch of hacks is not a good start for any project
Common Mistakes
Development
Wrong practices and mistakes during development slow the team
down and undermine the quality of the final product.
Development
Version control is not set up correctly
• Use text serialization (by default in Unity)
• Set up built-in YAML merge tool https://docs.unity3d.com/Manual/SmartMerge.html
• Set up commit hooks
https://github.com/3pjgames/unity-git-hooks
Development
Cache server is not used
Switching platforms decreases development speed.
Development
Static data is stored in JSON or XML files
• Slow loading
• Parsing generates garbage
For built-in static data use ScriptableObjects with custom editor tools.
Development
The project contains unused assets,
plugins and duplicated libraries
• 5 assets from A$ each drag a different JSON parser
• Test assets
• “Removed” assets and plugins are still in the project folder
Development
Repetitive actions require manual work
• For every repetitive task there should be a script automating it
• Make sure that you can “play” the game from any scene
• Automate all the steps of build process
Development
Profiling is only done in the Editor
• Always profile the game on your target device
• In the Editor you are profiling... the Editor
• Easy to miss actual performance bottlenecks
• It is possible to waste time on optimizing wrong things
Development
Developers don’t know how to use
profiling and debugging tools
• Profiler
https://unity3d.com/learn/tutorials/topics/performance-optimization
• Frame Debugger
• https://bitbucket.org/Unity-Technologies/memoryprofiler
• Platform tools: Xcode Instruments, Mali Graphics Debugger, Renderdoc, etc.
Development
Profiling and optimization are postponed
to a later development phase
• Costs become larger
• Might be impossible to fit into frame, memory and disk size budgets
Development
Optimization is not based on test data
• Make sure that you are optimizing actual bottlenecks
• Use the Tools to gather correct data
Development
Poor knowledge of target platform(s)
• Desktop GPUs vs Mobile GPUs
• JIT compilation
• The cost of Draw calls
Common Mistakes
Asset Settings
Assets (models, textures, sounds) take most of the size of your game.
Having just one wrong mesh in the project can nullify all the
optimizations your programmers have done.
Asset Settings
Sprite atlases are not set up correctly
Use 3rd-party tools to create atlases or group sprites together in Unity.
Asset Settings
Texture settings are not set up correctly
• Make sure that you know the right texture settings
• Set up an automated way to apply these settings for new textures
• Prevent artists from committing textures with wrong settings
1. Compression
2. Mip maps
Asset Settings
Asset Bundles contain duplicated textures
• It is easy to make a mistake in setting up Asset Bundles build system
• It is especially bad for duplicated textures
• Use Asset Bundle browser to track dependencies
https://unity3d.com/learn/tutorials/topics/best-practices/
guide-assetbundles-and-resources
Asset Settings
“Optimize Game Objects” is not enabled
on large skinned meshes
• Unity creates a GameObject for every bone
• Syncing their positions is costly
Common Mistakes
Programming
Poor practices and mistakes in code architecture and development
result in low productivity.
Programming
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
Programming
Architectural conventions
are not defined or poorly documented
Code has several ways of doing the same thing.
• Config formats (files, properties, assets)
• Events (Unity events, C# events, SendMessage)
• Which manager is responsible for which objects?
Programming
Poor understanding of Unity frame loop
• When Awake, OnEnable, Update and other methods are called
• When coroutines are updated
• How FixedUpdate is executed
Programming
Framerate is not taken into account
when scripting logic or animation
Use Time.deltaTime for FPS independent scripts
Common Mistakes
CPU Performance
High CPU usage results in “laggy” gameplay experience and drains
battery faster.
https://unity3d.com/learn/tutorials/topics/performance-optimization
CPU Performance
Too many scripts have Update() method
• Native -> Managed calls have some overhead
https://blogs.unity3d.com/2015/12/23/1k-update-calls/
• Use custom managers instead
CPU Performance
All custom Behaviours inherit from
an abstract class with
Update/Awake/Start methods defined
Now all your scripts have Update() method
CPU Performance
All game systems are updated every frame
Define how frequently you want to update different systems in your game:
• Moving objects,
• AI and path finding,
• Logging and saving game state,
• Other “heavy” systems
CPU Performance
Data and references to objects
needed frequently are not cached
Cache data you need frequently:
• Reflection
• Find()
• Camera.main
• GetComponent()
CPU Performance
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
CPU Performance
Memory is allocated every frame
• Even small allocations every frame will sooner or later cause a GC spike
• Try to eliminate ALL allocations
CPU Performance
Memory allocating APIs are used
instead of non-allocating alternatives
• LINQ
• String concatenation
• Unity APIs returning arrays:
Physics.RaycastAll, Mesh.vertices, GetComponents, etc.
CPU Performance
SendMessage() is used
in performance critical code
• SendMessage() is slow
• It uses a string message name
• You should never use it
Common Mistakes
GPU Performance
High GPU usage results in low framerate, drains battery faster and
the game is perceived as “running slow”.
GPU Performance
[Mobile] The project has too much overdraw
• Mobile GPUs can only draw _that 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
GPU Performance
[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
GPU Performance
Too many dynamic lights are used
with Forward rendering
Every light adds a render pass for every illuminated object
GPU Performance
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
https://blogs.unity3d.com/2017/04/03/
how-to-see-why-your-draw-calls-are-not-batched-in-5-6/
GPU Performance
LODs are not used or are not set up correctly
LODs let rendering further objects take less resources
Common Mistakes
UI Performance
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.
https://unity3d.com/learn/tutorials/temas/best-practices/guide-optimizing-unity-ui
UI Performance
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
UI Performance
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
UI Performance
“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
UI Performance
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
https://github.com/boonyifei/ScrollList
Common Mistakes
Miscellaneous
Other issues.
Miscellaneous
The team is waiting for Unity to implement
a feature instead of writing own
or using a 3rd-party solution
• Some features take a long time for Unity to polish
• Remember UI and Nested Prefabs
Miscellaneous
The project relies on Unity features
which are still in Beta
• Be ready that something doesn’t work
• Report bugs
• Have a backup plan
Miscellaneous
Bugs are not properly reported
• We can’t help you if we don’t know you need help
• Bad bug reports will be never looked at
• Support can recommend a workaround
Miscellaneous
In case of a large project, the company
doesn’t have a support contract with Unity
• Developing a large game is hard
• You will get unique issues
• Support has combined knowledge of dozens developers
• Can prioritize bug fixes
• Costs like 1-2 good engineers per year
Planning
• Lack of research
• Minimal supported devices are not specified
• Frame and asset budgets are not set
• Scene and prefab decomposition for the project is
not carefully planned
• Asset pipeline is not set up correctly
• Build and QA process is not set up correctly
• The project is not started from scratch after initial
prototypes
Development
• Version control is not set up correctly
• Cache server is not used
• Static data is stored in JSON or XML files
• The project contains unused assets, plugins and
duplicated libraries
• Repetitive actions require manual work
• Profiling is only done in the Editor
• Developers don’t know how to use profiling and
debugging tools
• Profiling and optimization are postponed to a later
development phase
• Optimization is not based on test data
• Poor knowledge of target platform(s)
Asset Settings
• Sprite atlases are not set up correctly
• Texture settings are not set up correctly
• Asset Bundles contain duplicated textures
• “Optimize Game Objects” is not enabled on large
skinned meshes
Programming
• Code is very abstract and hard to follow
• Architectural conventions are not defined or poorly
documented
• Poor understanding of Unity frame loop
• Script initialization logic relies on Unity execution
order
• Framerate is not taken into account when scripting
logic or animation
CPU Performance
• Too many scripts have Update() method
• All custom Behaviours inherit from an abstract
class with Update/Awake/Start methods defined
• All game systems are updated every frame
• Data and references to objects needed frequently
are not cached
• Frequently instantiated objects are not pooled
• Memory is allocated every frame
• Memory allocating APIs are used instead of non-
allocating alternatives
• SendMessage() is used in performance critical code
GPU Performance
• The project has too much overdraw
• The shaders are too complex
• Too many dynamic lights are used with Forward
rendering
• Wrong settings in the project break dynamic batching
• LODs are not used or are not set up correctly
UI Performance
• Different resolutions and aspect ratios are not taken
into account
• Animated elements are in the same Canvas
• “Opening” a new window is not optimized
• Lists contain large amount of items
Miscellaneous
• The project relies on Beta Unity features
• The team is waiting for Unity to implement a feature
instead of writing own or using a 3rd-party solution
• Bugs are not properly reported
• In case of a large project, the company doesn’t have a
support contract with Unity
Thank you!
Alexander Shlygin
Solution Consultant, Unity
ash@unity3d.com

Шлигін Олександр “Розробка ігор в Unity загальні помилки” GameDev Conference 2018

  • 1.
    Unity Game Development: Common MistakesAlexanderShlygin Solution Consultant, Unity ash@unity3d.com
  • 2.
  • 3.
    Common Mistakes Planning The mostimportant part in any software development project. Decisions made in this phase will be very hard to change later in development cycle.
  • 4.
    Planning Lack of research •Check that all planned features actually work on all target platforms • Unfortunately, there are ideas which just can’t be implemented in Unity
  • 5.
    Planning Minimal supported devicesare not specified • Define the minimal supported device(s) • Have them available to your development and QA teams • Otherwise, it is impossible to argue about performance and frame budgets
  • 6.
    Planning Frame and assetbudgets are not set Define budgets for models (in vertices), assets (in Mb), scripts and rendering (in ms) • How many vertices can we render? • How detailed models and textures should be? • How many lights will we have? • What % of the frame do we have for logic, rendering, effects and other subsystems?
  • 7.
    Planning Scene and prefabdecomposition for the project is not carefully planned ... 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
  • 8.
    Planning Asset pipeline isnot set up correctly The process of getting assets according to the specs from artists into the project. • Figure out process • Define clear guidelines on asset formats and specs • Add import time tests • Ideally should involve a Technical Artist
  • 9.
    Planning Build and QAprocess is not set up correctly • Set up a build machine • How a feature is published to the release build? • How are the new builds tested? • Are these tests automated? • Is statistics recorded?
  • 10.
    Planning The project isnot started from scratch after initial prototypes • Decisions made during prototyping usually favor speed • Basing your game on a bunch of hacks is not a good start for any project
  • 11.
    Common Mistakes Development Wrong practicesand mistakes during development slow the team down and undermine the quality of the final product.
  • 12.
    Development Version control isnot set up correctly • Use text serialization (by default in Unity) • Set up built-in YAML merge tool https://docs.unity3d.com/Manual/SmartMerge.html • Set up commit hooks https://github.com/3pjgames/unity-git-hooks
  • 13.
    Development Cache server isnot used Switching platforms decreases development speed.
  • 14.
    Development Static data isstored in JSON or XML files • Slow loading • Parsing generates garbage For built-in static data use ScriptableObjects with custom editor tools.
  • 15.
    Development The project containsunused assets, plugins and duplicated libraries • 5 assets from A$ each drag a different JSON parser • Test assets • “Removed” assets and plugins are still in the project folder
  • 16.
    Development Repetitive actions requiremanual work • For every repetitive task there should be a script automating it • Make sure that you can “play” the game from any scene • Automate all the steps of build process
  • 17.
    Development Profiling is onlydone in the Editor • Always profile the game on your target device • In the Editor you are profiling... the Editor • Easy to miss actual performance bottlenecks • It is possible to waste time on optimizing wrong things
  • 18.
    Development Developers don’t knowhow to use profiling and debugging tools • Profiler https://unity3d.com/learn/tutorials/topics/performance-optimization • Frame Debugger • https://bitbucket.org/Unity-Technologies/memoryprofiler • Platform tools: Xcode Instruments, Mali Graphics Debugger, Renderdoc, etc.
  • 19.
    Development Profiling and optimizationare postponed to a later development phase • Costs become larger • Might be impossible to fit into frame, memory and disk size budgets
  • 20.
    Development Optimization is notbased on test data • Make sure that you are optimizing actual bottlenecks • Use the Tools to gather correct data
  • 21.
    Development Poor knowledge oftarget platform(s) • Desktop GPUs vs Mobile GPUs • JIT compilation • The cost of Draw calls
  • 22.
    Common Mistakes Asset Settings Assets(models, textures, sounds) take most of the size of your game. Having just one wrong mesh in the project can nullify all the optimizations your programmers have done.
  • 23.
    Asset Settings Sprite atlasesare not set up correctly Use 3rd-party tools to create atlases or group sprites together in Unity.
  • 24.
    Asset Settings Texture settingsare not set up correctly • Make sure that you know the right texture settings • Set up an automated way to apply these settings for new textures • Prevent artists from committing textures with wrong settings 1. Compression 2. Mip maps
  • 25.
    Asset Settings Asset Bundlescontain duplicated textures • It is easy to make a mistake in setting up Asset Bundles build system • It is especially bad for duplicated textures • Use Asset Bundle browser to track dependencies https://unity3d.com/learn/tutorials/topics/best-practices/ guide-assetbundles-and-resources
  • 26.
    Asset Settings “Optimize GameObjects” is not enabled on large skinned meshes • Unity creates a GameObject for every bone • Syncing their positions is costly
  • 27.
    Common Mistakes Programming Poor practicesand mistakes in code architecture and development result in low productivity.
  • 28.
    Programming Code is veryabstract 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
  • 29.
    Programming Architectural conventions are notdefined or poorly documented Code has several ways of doing the same thing. • Config formats (files, properties, assets) • Events (Unity events, C# events, SendMessage) • Which manager is responsible for which objects?
  • 30.
    Programming Poor understanding ofUnity frame loop • When Awake, OnEnable, Update and other methods are called • When coroutines are updated • How FixedUpdate is executed
  • 31.
    Programming Framerate is nottaken into account when scripting logic or animation Use Time.deltaTime for FPS independent scripts
  • 32.
    Common Mistakes CPU Performance HighCPU usage results in “laggy” gameplay experience and drains battery faster. https://unity3d.com/learn/tutorials/topics/performance-optimization
  • 33.
    CPU Performance Too manyscripts have Update() method • Native -> Managed calls have some overhead https://blogs.unity3d.com/2015/12/23/1k-update-calls/ • Use custom managers instead
  • 34.
    CPU Performance All customBehaviours inherit from an abstract class with Update/Awake/Start methods defined Now all your scripts have Update() method
  • 35.
    CPU Performance All gamesystems are updated every frame Define how frequently you want to update different systems in your game: • Moving objects, • AI and path finding, • Logging and saving game state, • Other “heavy” systems
  • 36.
    CPU Performance Data andreferences to objects needed frequently are not cached Cache data you need frequently: • Reflection • Find() • Camera.main • GetComponent()
  • 37.
    CPU Performance Frequently instantiatedobjects are not pooled • Instantiating objects is slow • Create pools of objects at the start of the game • Reuse objects instead of creating new ones
  • 38.
    CPU Performance Memory isallocated every frame • Even small allocations every frame will sooner or later cause a GC spike • Try to eliminate ALL allocations
  • 39.
    CPU Performance Memory allocatingAPIs are used instead of non-allocating alternatives • LINQ • String concatenation • Unity APIs returning arrays: Physics.RaycastAll, Mesh.vertices, GetComponents, etc.
  • 40.
    CPU Performance SendMessage() isused in performance critical code • SendMessage() is slow • It uses a string message name • You should never use it
  • 41.
    Common Mistakes GPU Performance HighGPU usage results in low framerate, drains battery faster and the game is perceived as “running slow”.
  • 42.
    GPU Performance [Mobile] Theproject has too much overdraw • Mobile GPUs can only draw _that 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
  • 43.
    GPU Performance [Mobile] Theshaders 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
  • 44.
    GPU Performance Too manydynamic lights are used with Forward rendering Every light adds a render pass for every illuminated object
  • 45.
    GPU Performance Wrong settingsin the project break dynamic batching • Objects must be “similar” to be dynamically batched • Frame Debugger shows why certain objects were not batched https://blogs.unity3d.com/2017/04/03/ how-to-see-why-your-draw-calls-are-not-batched-in-5-6/
  • 46.
    GPU Performance LODs arenot used or are not set up correctly LODs let rendering further objects take less resources
  • 47.
    Common Mistakes UI Performance UnityUI 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. https://unity3d.com/learn/tutorials/temas/best-practices/guide-optimizing-unity-ui
  • 48.
    UI Performance Different resolutionsand 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
  • 49.
    UI Performance Animated elementsare 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
  • 50.
    UI Performance “Opening” anew 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
  • 51.
    UI Performance Lists containlarge 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 https://github.com/boonyifei/ScrollList
  • 52.
  • 53.
    Miscellaneous The team iswaiting for Unity to implement a feature instead of writing own or using a 3rd-party solution • Some features take a long time for Unity to polish • Remember UI and Nested Prefabs
  • 54.
    Miscellaneous The project relieson Unity features which are still in Beta • Be ready that something doesn’t work • Report bugs • Have a backup plan
  • 55.
    Miscellaneous Bugs are notproperly reported • We can’t help you if we don’t know you need help • Bad bug reports will be never looked at • Support can recommend a workaround
  • 56.
    Miscellaneous In case ofa large project, the company doesn’t have a support contract with Unity • Developing a large game is hard • You will get unique issues • Support has combined knowledge of dozens developers • Can prioritize bug fixes • Costs like 1-2 good engineers per year
  • 57.
    Planning • Lack ofresearch • Minimal supported devices are not specified • Frame and asset budgets are not set • Scene and prefab decomposition for the project is not carefully planned • Asset pipeline is not set up correctly • Build and QA process is not set up correctly • The project is not started from scratch after initial prototypes Development • Version control is not set up correctly • Cache server is not used • Static data is stored in JSON or XML files • The project contains unused assets, plugins and duplicated libraries • Repetitive actions require manual work • Profiling is only done in the Editor • Developers don’t know how to use profiling and debugging tools • Profiling and optimization are postponed to a later development phase • Optimization is not based on test data • Poor knowledge of target platform(s) Asset Settings • Sprite atlases are not set up correctly • Texture settings are not set up correctly • Asset Bundles contain duplicated textures • “Optimize Game Objects” is not enabled on large skinned meshes Programming • Code is very abstract and hard to follow • Architectural conventions are not defined or poorly documented • Poor understanding of Unity frame loop • Script initialization logic relies on Unity execution order • Framerate is not taken into account when scripting logic or animation CPU Performance • Too many scripts have Update() method • All custom Behaviours inherit from an abstract class with Update/Awake/Start methods defined • All game systems are updated every frame • Data and references to objects needed frequently are not cached • Frequently instantiated objects are not pooled • Memory is allocated every frame • Memory allocating APIs are used instead of non- allocating alternatives • SendMessage() is used in performance critical code GPU Performance • The project has too much overdraw • The shaders are too complex • Too many dynamic lights are used with Forward rendering • Wrong settings in the project break dynamic batching • LODs are not used or are not set up correctly UI Performance • Different resolutions and aspect ratios are not taken into account • Animated elements are in the same Canvas • “Opening” a new window is not optimized • Lists contain large amount of items Miscellaneous • The project relies on Beta Unity features • The team is waiting for Unity to implement a feature instead of writing own or using a 3rd-party solution • Bugs are not properly reported • In case of a large project, the company doesn’t have a support contract with Unity
  • 58.
    Thank you! Alexander Shlygin SolutionConsultant, Unity ash@unity3d.com

Editor's Notes

  • #5 Example: Mobile MMO with 100 ppl raids running on iPhone 4.
  • #6 Example: A team is making a game for low-end iOS devices, but nobody has a mac nor an iOS device
  • #7 Example with grass
  • #11 Example: hackathons