Unity's ui optimization

Reference: https://blog.csdn.net/Rhett_Yuan/article/details/56695170
https://blog.csdn.net/UWA4D/article/details/78376319
https://blog.csdn.net/rhett_yuan/article/ details/55271310
https://blog.csdn.net/UWA4D/article/details/78376319
https://blog.csdn.net/qq_34113388/article/details/64437526

Introduction to UGUI

UGUI is an official UI system launched by Unity, which integrates a WYSIWYG UI solution. It has rich functions and is easy to use, and its source code is also open. Download address: https://bitbucket.org/Unity-Technologies/ ui/src

Compared with NGUI, UGUI has the following advantages:

  1. The WYSIWYG editing method can be edited in the Scene window.
  2. The intelligent Sprite packer can automatically generate atlases according to tags without manual maintenance. The generated atlases are merged in a reasonable manner without redundant resources.
  3. The rendering order is related to the Hierarchy order of the GameObject. The root node is displayed on the bottom layer, and the leaf node is displayed on the top layer. This rendering method makes it more convenient and intuitive to adjust the level of the UI.
  4. RectTranForm and the anchor point system are more suitable for 2D plane layout, and are very convenient for multi-resolution screen self-adaptation.

UI production specifications and guidance methods

This article is about UGUI optimization. You may think that the UI production specifications and guidance methods have nothing to do with optimization. In fact, many performance problems are often caused by the unreasonable use of resources, such as the use of oversized pictures and the use of too many references. Atlas and unnecessary resources are loaded, etc. Unnecessary performance overhead can be avoided if specific specifications are adhered to from the very beginning of designing and making UIs. The author summarizes the following general norms and guidance methods based on multiple projects involved (these norms apply to all projects, whether you use UGUI or NGUI).

Reasonable allocation of atlas, reasonable allocation of atlas can reduce the speed of drawcall and resource loading;

The specific details are as follows:
+ The pictures of the same UI interface should be placed in one atlas as much as possible, so that the drawcall can be reduced as much as possible.
+ Put shared pictures in one or several shared atlases, such as common bullet boxes and buttons; pictures with the same function are placed in one atlas, such as equipment icons and hero avatars; this can reduce the loading speed of the switching interface.
+ Pictures of different formats are placed in different atlases, such as transparent (with Alpha) and opaque (without Alpha) pictures, which can reduce the storage space and memory usage of the pictures. (UGUI's sprite packer handles this automatically)

Reasonable Resource Directory

Only prefab files should be saved in the resources directory, and other non-prefab files (such as animations, textures, materials, etc.) should be placed outside the resources directory; because with the iteration of the project, some resources (animations, textures) may become invalid. If these files are placed in the resource directory, when packaging, Unity will type all the text in the resource directory into a large AssetBundle package (the files in the non-resouce directory will only be typed into the package when referenced), thus Redundancy occurs, increasing unnecessary storage space and memory usage. You can view the codes of all non-prefab resources in the current directory in the console window with the following code (in the Mac environment):
find . -type f | egrep -v “(prefab|prefab.meta|meta)$”

The difference between resources inside and outside the level

The UI resources in the level should not be mixed with the UI resources of the peripheral system; in the level, a large number of characters and scene resources need to be loaded, and the memory is relatively tight. Generally, when entering the level, the resources of the peripheral system will be manually released, so that there are more resources in the level. More memory can be used. If the UI in the battle and the UI of the peripheral system use the same images in the atlas, it may cause the release of the image resources of the peripheral system to fail. The UI resources shared by the level and the periphery need special treatment. Generally speaking, it is a better choice to copy a copy for use in the level.
Appropriately reduce the size of the image. Sometimes the background of the UI system may use a full-screen size image, such as using a 1136*640 size image on an Iphone; using such a size image is very expensive, and you can discuss it with art students. Decrease the precision of the image and use a lower size image.

Texture compression format

Use etc format pictures on android devices. At present, almost all android devices support etc1 format pictures. The advantage of etc1 is that the first pixel only uses 0.5 bytes, while ordinary rgba32 pictures occupy 4 pixels per pixel. Bytes, that is to say a 1024*1024 image, if the rgba32 format is used, the memory occupied is 4M and the etc1 format is only 0.5M. But images using etc1 format have two limitations - length and width must be POT (2 to the Nth power) and do not support alpha channel, so when using etc1, you need an extra image to store the alpha channel, and use a special The shader to sample the alpha. For details, please refer to http://malideveloper.arm.com/resources/sample-code/etcv1-texture-compression-and-alpha-channels/

Remove unnecessary stuff (requires loading)

Delete unnecessary UI nodes, animation components and resources; with the iteration of the project, some UI nodes and animations may have failed, and the failed nodes and animations must be deleted. In many projects, some students, in order to save trouble, Just disable the invalid nodes and animations. Doing so will not put too much load on the cpu at runtime, but it will increase unnecessary loading time and memory usage when loading. For discarded UI image resources, although they are not placed in the Resource directory, they will not be included in the package, but they will still be included in the atlas in Editor mode, which affects optimization decisions. The author wrote a tool for scanning unused UI texture resources, the code address: https://github.com/neoliang/FindUnUsedUITexture ; in addition, for abandoned scripts, there may be some objects that hold references to it, Loading such objects is also time-consuming. The author also wrote a tool to scan abandoned scripts. The code address is https://github.com/neoliang/MissingScriptFinder

CPU optimization

Reconstruction of canvas

Generally speaking, to optimize CPU performance, you should first use the profiler to locate performance hotspots, find the function with the highest consumption, and then find a way to reduce its consumption. After the author's analysis of UGUI using profiler many times, one of the main reasons for its high CPU performance overhead is the reconstruction of UI grid by Canvs. There are many situations that will trigger the reconstruction of grid by Canvas, such as UI elements such as Image and Text. Enable and changes of the length, width or Color properties of UI elements, etc. If there are many UI Mesh vertices in Canvas, this item will have high CPU overhead. In Unity's Profiler, the corresponding Canvas.SendWillRenderCanvases or Canvas.BuildBatch takes up too much time.
The main function of Canvas.BuildBatch is to merge the grids of all UI elements under the Canvas node. The merged grid will be cached, and will only be merged again when the grid of the UI elements below it changes. The network changes of UI elements are mainly due to the rebuilding of Layout or graphic when Canvas.SendWillRenderCanvases is called. The sequence diagram of the calling process of this function is as follows:
This process is executed by CanvasUpdateRegistry monitoring Canvas's WillRenderCanvases (1 in the above figure), mainly to rebuild the layout and graphics previously marked as dirty. The main reason for the dirty layout and graphics is that the UI elements under the Canvas tree structure have changed (such as adding and deleting UI objects, UI element vertices, rec size changes, etc.) Graphic.SetDirty is called (in fact, CanvasUpdateRegistry will eventually be called) .RegisterCanvasElementForLayoutRebuild).
Before rebuilding the layout, the elements in the Layout rebuild queue will be sorted according to their hierarchical depth in the heiarchy (2 in the above figure). The result of the arrangement is that the nodes closer to the root will be preferentially processed.
The rebuild layout (3 in the above figure) is mainly to execute the methods in the ILayoutElement and ILayoutController interfaces to calculate the layout information such as the position and the size of the Rect.
The rebulid graphic (4 in the above figure) is mainly to call UpdateGeometry to reconstruct the vertex data of the mesh (5 in the above figure) and call UpdateMeterial to update the material information of the CanvasRender (6 in the above figure).

Based on the above grid update principle of UGUI, we can make the following optimizations:
1. Use as few UI elements as possible; when making UI, be sure to check the UI level carefully and delete unnecessary UI elements, which can reduce the depth sorting time (2 in the above picture) and Rebuild time (3, 4 in the above picture).
1. Reduce the frequency of Rebuild, separate dynamic UI elements (elements that frequently change such as vertices, alpha, coordinates, and size) from static UI elements and put them in a specific Canvas.
1. Be careful to use enable and disable of UI elements, because they will trigger a rebuild (3 and 4 in the figure) that takes a long time. One of the alternatives is to enable and disable the canvasrender or Canvas of UI elements.
1. Use Text's Best Fit option with caution. Although this option can dynamically adjust the font size to fit the UI layout without exceeding the frame, it is very expensive. Unity will use all font sizes for the element used. The generated primitives are stored in atlas, which not only increases the extra generation time, but also makes the atlas corresponding to the font larger.
1. Use the Pixel Perfect option of Canvas with caution, this option will cause layout Rebuild when the position of ui elements changes. (For example, when ScrollRect is scrolling, if the pixel Perfect of Canvas is turned on, the consumption of Canvas.SendWillRenderCanvas will be high)
1. Use the buffer pool to save the Items in the ScrollView. For elements that are moved out of or moved into the View, do not call disable or enable, but put them in the cache pool or take them out of the cache pool for reuse.
1. In addition to the rebuild process, the touch processing consumption of UGUI may also become a performance hotspot. Because UGUI calls raycast on all visible Graphic components by default. For grahic that does not need to receive touch events, be sure to disable raycast. For unity5 and above, the Raycast Target of graphics can be turned off. For unity 4.6, you can add canvasgroup components to UI elements that do not need to receive touch.

GPU optimized

In general, there are two main reasons for GPU performance bottlenecks: complex vertex or pixel shader calculations and excessive pixel padding caused by overdraw. By default, all UI elements in UGUI use the UI/Defaut shader, so the Overdraw problem can be prioritized during optimization. Overdraw is mainly caused by the overlap of a large number of UI elements. It is relatively simple to view overdraw. Select overdraw mode in the scene window. The brighter the scene in the scene, the higher the overdraw (as shown below).

In order to reduce overdraw, the following optimizations can be done:

  1. Disable invisible UI, such as when opening one system if it completely blocks another system, you can disable the blocked system.
  2. Do not use an empty Image. In Unity, RayCast uses Graphi as the basic element to detect touch. In the project I participated in, many students use an empty image and set the alpha to 0 to receive touch events, which will generate unnecessary touches. overdraw. Unnecessary overdraw can be avoided by receiving events through the following class NoDrawingRayCast.
public class NoDrawingRayCast : Graphic { public override void SetMaterialDirty() { } public override void SetVerticesDirty() { } protected override void OnFillVBO(List vbo) { vbo.Clear(); }}

Summarize

There is no one-size-fits-all method for optimizing UGUI performance, and the author's summary of these experiences can only be used as a reference. Optimizing performance is often a balance between various choices, such as the balance between drawcall and rebuild, the balance between memory and cpu consumption, and the balance between UI image accuracy and texture size. Every optimization may cause bottlenecks to appear in other links. It is necessary to be good at using profiler to find performance hotspots and prescribe the right medicine.

Optimization article two

dc optimization

  1. Reduce overlap, when merging, only ui elements that actually overlap will generate new dc. Look at the overlapping
    of ) and try not to let elements overlap.
  2. The Mask component will have one more dc, and the components under the mask will not be merged with the dc outside the mask.
  3. Cavas division:
    (1) In simple terms, because all UIs under a canvas are combined in one mesh, the cost is high, so complex UIs are divided into sub-canvas.
    (2) Pay attention to the separation of dynamic and static, because dynamic elements will cause the mesh to update the canvas.
    (3) Canvas cannot be divided too finely, causing dc to rise.

Event detection - EventSystem.Update

1. Mainly look at EventSystem.Update in Profiler
2. Graphic Raycater and Canvas binding, will collect all Graphic components on Canvas, you can uncheck the graphic Raycast Target option of components that do not need to detect events

Ui Heavy Building

1. View Profiler's Canvas.BuildBatch
2. The best method for grid reconstruction is to separate static and dynamic. When any element on the Canvas changes, it will cause the entire Canvas to be redrawn, and the changed elements will be separated out.
3. Modify the component's The Color property will also cause the UI to be redrawn, and the tint property of the modified material can be generated. This will have one more dc, because the material has changed.

1、Profier的Canvas.BuildBatch查看
2、对于网格重建最好的方法就是动静分离,当Canvas上的任何一个元素变化时会引起整个Canvas的重绘,将变化的元素单独出来
3、修改组件的Color属性时也会导致UI的重绘,可以生成修改材质的tint属性

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324603393&siteId=291194637