Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/joanstinson/unityuioptimizationtool
A Unity Editor tool that automatically optimizes selected UI game objects (including Prefabs) to save you time.
https://github.com/joanstinson/unityuioptimizationtool
csharp unity-optimization unity-prefabs unity-ui unity3d unity3d-editor unity3d-plugin
Last synced: about 12 hours ago
JSON representation
A Unity Editor tool that automatically optimizes selected UI game objects (including Prefabs) to save you time.
- Host: GitHub
- URL: https://github.com/joanstinson/unityuioptimizationtool
- Owner: JoanStinson
- License: mit
- Created: 2022-11-05T17:32:29.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2022-11-26T15:16:50.000Z (almost 2 years ago)
- Last Synced: 2024-09-22T11:02:27.597Z (5 days ago)
- Topics: csharp, unity-optimization, unity-prefabs, unity-ui, unity3d, unity3d-editor, unity3d-plugin
- Language: C#
- Homepage:
- Size: 956 KB
- Stars: 134
- Watchers: 8
- Forks: 15
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Unity UI Optimization Tool
A Unity Editor tool that automatically optimizes selected UI game objects (including Prefabs) to save you time.
## 🖥️ How It Works
For starters, import the package located in the [Releases](https://github.com/JoanStinson/UnityUIOptimizationTool/releases) section into your project.Now then, inside the Unity Editor, select any number of game objects anywhere: in the scene's Hierarchy, in the Project window or in Prefab Edit Mode.
Next, go to Tools > JGM > Optimize Selected UI GameObjects and press it.
It will automatically optimize the selected game objects (including Prefabs) with the supported techniques.
## 🛠️ Unity UI Optimization Techniques
🛠️ Using more Canvases
### Using more Canvases
Every time a single UI element inside a Canvas changes (e.g. change 1 Text or Image), the whole Canvas has to generate the meshes and draw them all
over again (very costly).🛠️ Separating objects between static and dynamic Canvases
### Separating objects between static and dynamic Canvases
* Static Canvas: contains UI elements that are never going to change; good examples of these are background images, labels, and so on.
* Incidental Dynamic Canvas: contains UI elements that only change in response to something, such as a UI button press or hover action.
* Continuous Dynamic Canvas: contains UI elements that change regularly, such as animated elements.🛠️ Disabling Raycast Target for non-interactive elements
### Disabling Raycast Target for non-interactive elements
For all Image components that are not part of a Button, disable the Raycast Target (basically disable it in all images except for buttons).
Each time there is a UI input (click, tap, scroll, etc.) Unity's GraphicsRaycaster iterates over all the Raycast Targets in the scene, so the less we have the more processing we save.
🛠️ Hiding UI elements by disabling the parent Canvas component
### Hiding UI elements by disabling the parent Canvas component
To avoid the Canvas regeneration, it's good habit to split the UI into different Canvases, and instead of disabling a LayoutGroup, disable an entire Canvas.
🛠️ Avoiding Animator components
### Avoiding Animator components
Unity's Animator components are meant for 3D avatar animations primarily. Using it for UI elements causes extra processing.
Instead, the best approach is to use a custom tweening tool such as DOTween.
🛠️ Explicitly defining the event camera for World Space Canvases
### Explicitly defining the event camera for World Space Canvases
Always set the Event Camera in a World Space Canvas as if there is no Camera assigned, it will call FindObjectWithTag("Main Camera") on every single frame! ☠️
🛠️ Don't use alpha to hide UI elements
### Don't use alpha to hide UI elements
Even though the Image's color property is set to alpha 0, it will still cause a draw call.
Instead, disable the game object itself, or set the alpha of a Canvas Group to 0. This will prevent any draw calls from this object and its childs (0 draw calls).
🛠️ Make sure to use a RectMask2D
### Make sure to use a RectMask2D
Like this, any element that is not inside the Scroll Rect, will not be drawn saving plenty of draw calls.
🛠️ Disable Pixel Perfect for ScrollRects
### Disable Pixel Perfect for ScrollRects
Pixel Perfect makes UI elements appear sharper, but since in a Scroll Rect there's going to be movement, we won't notice it and we'll save a lot of processing.
The Scroll Rect should be on a separate Canvas with this setting off and other UI elements appearing in the same screen, would be in another Canvas with this setting on.
🛠️ Manually stop ScrollRect motion
### Manually stop ScrollRect motion
We can use ScrollRect.StopMovement() to stop the motion once the ScrollRect.velocity is below a certain threshold to reduce regeneration frequency.🛠️ Using empty UIText elements for full-screen interaction
### Using empty UIText elements for full-screen interaction
For a Button that's going to be interactable full-screen, for the Button's Target Graphic, don't use an Image that fills the whole screen and has a color alpha set to 0 (as transparency breaks batching processes).
Instead, for the Button's Target Graphic, use a Text with no Font or Text defined.
🛠️ Reduce Game Objects inside Prefabs
### Reduce Game Objects inside Prefabs
Wherever possible, try to reduce the number of game objects inside of a Prefab, maybe in some occasions it's possible to merge 3 game objects with Images into 1 single game object with 1 Image.🛠️ Avoid Layout Groups when possible
### Avoid Layout Groups when possible
Whenever possible, try to avoid using Layout Groups, specially nested Layout Groups, as it's very costly performance wise.🛠️ Adjust texture compression formats
### Adjust texture compression formats
Always adjust texture compression formats for your UI Sprite assets, to reduce memory footprint. Available compression types can be found [here](https://docs.unity3d.com/Manual/class-TextureImporterOverride.html).🛠️ Use Sprite Atlases always
### Use Sprite Atlases always
Use [Sprite Atlases](https://docs.unity3d.com/Manual/class-SpriteAtlas.html) for grouping single Sprites into one big texture to reduce the number of draw calls.
🛠️ Take order into account to prevent Batch Breaks
### Take order into account to prevent Batch Breaks
Order in UI hierarchies matters. If you have in a hierarchy this order:
* SpriteA1
* SpriteB1
* SpriteA2
* SpriteB2
* SpriteA3
* SpriteB3
(meaning 'A' Sprites are from a specific Sprite Atlas and 'B' Sprite are from another one) it will issue 6 draw calls because the batches are breaking as all Sprites from one Atlas are not consecutively in line. To prevent this Batch Break, order them as in:
* SpriteA1
* SpriteA2
* SpriteA3
* SpriteB1
* SpriteB2
* SpriteB3
As a result, this will only issue 2 draw calls.## 🧰 Tool Supported Techniques
✅ Disabling Raycast Target for non-interactive elements
✅ Avoiding Animator components
✅ Make sure to use a RectMask2D
✅ Disable Pixel Perfect for ScrollRects
## 📚 Bibliography
* [Unite '17 Seoul - Tips and Tricks for Optimising Unity UI](https://www.youtube.com/watch?v=eH-PdFKgctE)
* [Unite Europe 2017 - Squeezing Unity: Tips for Raising Performance](https://youtu.be/_wxitgdx-UI?t=1426)
* [Unity Game Optimization](https://www.amazon.com/Unity-Game-Optimization-Enhance-performance/dp/1838556516)
* [Optimizing Unity UI](https://learn.unity.com/tutorial/optimizing-unity-ui)
* [Optimization Tips for Unity UI](https://unity.com/how-to/unity-ui-optimization-tips#avoid-expensive-ui-elements)
* [Interactive Guide: Cross-Platform UI](https://assetstore.unity.com/packages/templates/tutorials/interactive-guide-cross-platform-ui-208063#description)