1) Lua global variable code specification 2) AssetBundle LockPersistentManager overhead 3) Unity built-in fonts are not redundant resources in resource detection reports 4) on specific Android devices 5) Differences in the properties of Mask and RectMask

This is the 238th post of UWA Technical Knowledge Sharing. Today, we continue to select a number of issues related to development and optimization for you. It is recommended that you read for 10 minutes.

UWA Q&A Community: Answer.uwa4d.com UWA QQ Group 2:793972859 (The group is full)


Q: Using Lua as a scripting aid has become very popular, but global variables in Lua are a problem because they can be used without declaration, the compiler does not report errors for renaming and overwriting, and they can be accidentally overwritten and cause bugs. Also, global variables that refer to GameObject can be a leak.

Do you have any code specifications for Lua global variables during development? For example: when can global variables be used? How to declare? How to avoid coverage and other issues, thank you.

A: You can execute the luaGlobalCheck. Lua file at an appropriate time after the Lua virtual machine has started. This file will set the meta table and meta methods of _G. Overriding the _newindex and _index meta-methods to disallow new global variables and to prompt errors when accessing nonexistent global variables. This can be done to avoid creating arbitrary global variables that will pollute the environment and overlay problems.

Luaglobalcheck. lua code is as follows:

SetMetatable (_G, {__newIndex = function(_, k) error("attempt to add a new value to global,key: ")... __index = function(_, k) error("attempt to index a global value,key: ") k,2) end })

Thanks to the @UWA Answers community for providing the answer


Q: When we look at the performance curve, we find that during a particular frame AssetBundle is loaded, LockPersistentManager takes longer. May I ask whether this piece can be optimized?

A1: this shows the current frame or a few frames before there are a lot of resources in the load through LoadAsync, its essence is the loaded resource caused by too much, on its own resources, reasonable optimization can reduce Loading. LockPersistentManager overhead. In addition, by replacing asynchronous loading with synchronous loading, LockPersistentManager does not appear, but the total load time does not change because the total load does not change.

For load optimization of major resources, see the following link: “Unity Loading Module Deep Analysis (Texture)”, “Unity Loading Module Deep Analysis (Grid)”, “Unity Loading Module Deep Analysis (Shader)”, “Unity Loading Module Deep Analysis of Animation”, “Mobile Game Loading Performance and Memory Management Full Analysis”

This answer is provided by UWA

A2: In Unity 2019.4.1, loadFromFileAsync is executed in Integrate Asset of the main thread. LoadAssetAsync of PreloadManager thread cannot be executed at the same time and must be locked. There is a lockpersistentManager that locks until one party ends.

Nature or the implementation is not perfect, can use the Spin Lock has been locked to the Application. The backgroundLoadingPriority time period to the next frame, don’t release Lock to the party.

Unity 2019.4.11 and 2019.4.16 fix main thread read bundles and islocks:

I tested it in Unity 2020.1.17 on iOS and it was basically solved:

However, there are some asynchronous loading of the main thread such as lock phenomenon, it is estimated that the collection of resources is too large dependency time is too long triggered:

Thanks to the @UWA Q&A community for providing the answer


Q: In our project, the Prefab of two interfaces are generated by Unity’s own Arial font and uploaded to resource detection. However, in the report, we don’t see that the built-in font is redundant resource.

A1: The Arial font used in AssetBundle is used as a reference and is not packaged in the corresponding AssetBundle. The Arial font used in AssetBundle is used as a reference and is not packaged in the corresponding AssetBundle. So it’s normal to see no redundancy.

You can use AssetStudio to open Unity Default Resources under Assets /bin/Data/ in the APK package, as shown below:

Thanks to the Xuan@UWA Q&A community for the answers

A2: Arial font is not recommended. On some low-end phones, the Chinese font will not be displayed. The default font will be different on different models.

Thanks to Zheng Xiao @uwa Q&A community for providing answers


Q: On certain Android devices, there was an Adreno freeze issue (GPU hung).

The screen froze and didn’t refresh, but the music and sound effects of clicking the UI still played. There are no exceptions and flashbacks when looking at the CPU using the Unity Profiler. Frozen screen caught the error log can be poked the original Q&A view, please help to see what the inspiration, thank you!

A1: Not sure if the stack is like you. The same thing happened with the Mono package on the Xiaomi phone before, but it didn’t happen again when it was changed to IL2CPP.

Thanks to the @UWA Q&A community for providing an answer

This works for some models, but some MTK phones still have similar issues. Our project also has a similar problem, where the screen or the screen is stuck. It feels like a Unity co-batch issue, dynamic co-batch or GPU Instance. We try to reduce the number of GPU Instances in a single batch, which will be alleviated. It is better to adapt the number according to the mobile phone GPU model.

Thanks to the Jony@UWA Q&A community for the answers

A3: It uses the official GPU Instance solution provided by Unity.


The default Shader for this scheme was initially used to render combat units, causing strange flashbacks and crashes. The default Shader was as follows:

The loadMatFromTexture function in this Shader is called 9 times. The loadMatFromTexture implementation is as follows:

It can be confirmed that the problem here is most likely caused by too many times of sampling, and then modified to use the current frame, no LERP operation, and each vertex is only controlled by two bones, and then tested that there is no crash. Currently, we are still confirming the acceptance of the loss of effect with the art, and the following code looks like this:

Thanks to the @uwa Q&A community for this answer


Q: What is the difference between the performance of the Mask and RectMask in Unity UI?

A1: RectMask2D: does not rely on an Image component, and its cliparea is the RECT size of its RectTransform.

Property 1: All children under RectMask2D node cannot co-batch with external UI node and multiple RectMask2D cannot co-batch with each other.

Property 2: For Depth calculation, all RectMask2D is treated as a normal UI node, except that it does not have a CanvasRenderer component and cannot be treated as the BottomUI of any UI control.

Mask: The component depends on an Image component. The clipping area is the size of the Image.

Property 1: There will be two more Draw calls at the head and tail of the Mask node (the first =Mask node, and the tail = children under the Mask node after traversal). If the conditions of the combined batch are met between the multiple masks, the two Draw calls can correspond to the combined batch (the first of the Mask1 and the first of the Mask2; The tail of Mask1 closes with the tail of Mask2, but the tail does not close.

Property 2: When calculating Depth, when traversal to the beginning of a Mask, consider it as a non-ratable batch UI node, but note that it can be the bottomUI of its child UI node.

Property 3: The UI node within the Mask and the UI node outside the Mask cannot be combined with the batch, but the UI nodes within multiple masks can be combined with the batch if they meet the conditions of the batch.

As can be seen from the property 3 of Mask, it is not that the more masks the worse, because they can be combined. The following conclusions are drawn:

  • When an interface has only one Mask, then RectMask2D is superior to Mask;
  • When you have two masks, they’re about the same;
  • When there are more than two masks, then Mask is superior to RectMask2D.

Thank you for providing answers to the @uwa question&answer community

A2: The conclusion from the consideration of multiple Mask batches is OK, here is a supplement: Stencil is not overdrawn for Mask2D, but each Item is compared to the MaskRect, which has a CPU overhead. (Mask is for many items, Mask2D is recommended for few items)

Thanks to the @uwa Q&A community for providing the answer

A3: From the perspective of UI co-batch, at the same level:

The Mask is a special component with a high priority and will be operated on first. The Mask will change itself and the Material of the UI, which is different.

RectMask2D is a clipper with no special permissions, and its batch rules are the same as any other common component. RectMask2D changes the Clip Rect of the UI in it. So UI components that are not under the same RectMask2D cannot be approved together.

In the reasons of whether UI can be approved, it is speculated that:

Different Rect Clipping refers to switching between RectMask2D and RectMask2D from RectMask2D to ordinary components or vice versa.

Thanks to the Tao@UWA Q&A community for the answers

That’s all for today’s sharing. Life, of course, is long and knowledge is long. The questions you may see are just the tip of the iceberg in the long development cycle, and we have already prepared more technical topics for you to explore and share on the UWA Q&A website. Welcome you who love progress to join us. Maybe your method can solve others’ urgent need. And the “stone” of another mountain can attack your “jade”.

Website: www.uwa4d.com Official Technology Blog: blog.uwa4d.com Official Q&A Community: Answer.uwa4d.com Official Technology QQ Group: 793972859 (The original group is full)