Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

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.

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.



Made With Unity


License


Last Commit


Repo Size


Downloads


Last Release



## 🖥️ 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)