Realization scheme of flashing white in fixed part of character

Posted May 28, 20207 min read

1) The realization scheme of the flashing white of the fixed part of the character
2) LoadFromStreamAsync loading error
3) Influence of Separate Axes setting
4) Special effects obviously get stuck when close to the camera
5) Time-consuming particles in opaque rendering overhead

UWA Q & A Community:
UWA QQ Group 2:793972859(the original group is full)


Q:Prerequisite:There is a 3D model, only one Skinned Mesh Renderer, and only one Material. I want to realize that when the left hand is hit, the left hand flashes white. The flashing effect of the entire model has been simply realized. For the local flashing effect, there are three options now in mind:

1. Create a partial mask map corresponding to UV. For example, only the left hand part of this image is black, and the other parts are white. To modify Shader, you can use this picture to do calculations with MainTex to realize the modification of the color of the left hand part at runtime.
2. Brush the vertex color on the left hand when modeling, Shader adds vertex color processing.
3. The vertex color is not brushed during modeling, but when running the script to modify the color of all vertices on the left hand, it is also necessary to modify Shader to add vertex color processing.

I want to use the third solution, but there is a problem, how can I efficiently modify the colors of all the vertices of the specified part of the model at runtime? There is a method on the Internet that can be modified by specifying bone as follows:

void Highlight(Transform bone) {
        Debug.Assert(smr! = Null);
        var idx = GetBoneIndex(bone);
        var mesh = smr.sharedMesh;
        var weights = mesh.boneWeights;
        var colors = new Color32 [weights.Length];

        for(int i = 0; i <colors.Length; ++ i) {
            float sum = 0;
            if(weights [i].boneIndex0 == idx && weights [i].weight0> 0)
                sum + = weights [i].weight0;
            if(weights [i].boneIndex1 == idx && weights [i].weight1> 0)
                sum + = weights [i].weight1;
            if(weights [i].boneIndex2 == idx && weights [i].weight2> 0)
                sum + = weights [i].weight2;
            if(weights [i].boneIndex3 == idx && weights [i].weight3> 0)
                sum + = weights [i].weight3;

            colors [i]= Color32.Lerp(regularColor, highlightColor, sum);

        mesh.colors32 = colors;

This only specifies a bone, but there are many nodes in one part of the model, such as:

There are so many in one arm. The above method is a bit computationally expensive. Is there a better plan to achieve the need to modify the color of the specified part?

A:The general idea of optimization is to change space to time. If you want to use the third method and the position of each flash is fixed, you can store the vertices to flash off-line, or store it in memory once in runtime in.

Personally feel that if the position of the flash is fixed under the demand of the subject, the third method may not be the most efficient way:

  1. If you want to modify it at runtime, Mesh needs to be able to read and write, and the memory will occupy two copies;
  2. The Mesh modified at runtime must be resubmitted to the GPU after each modification, which will also take up some time and bandwidth;
  3. If the grid is dense and the number of vertices is large, this kind of calculation itself is more suitable for GPU to do, unless you are clearly a GPU bottleneck, to optimize to the CPU, it is not recommended under the conventional idea.

The first method has more memory consumption for one texture and one more sampling process, but it can be controlled more carefully, especially when the vertices are sparse; the second method reduces the consumption of textures and increases the data of some vertices , Personal feeling is already a very good practice.

Modify the vertex color at runtime. What I can think of is to facilitate the control of the area. For example, any area that is not fixed needs to have its own light up. This calculation needs to be based on the touch position of the attack or attack. The fixed Under the circumstances, I think it is better to do the data offline.
Thanks to Jia Weihao @UWAFAQ Community for providing answers


Q:We recently used the LoadFromStreamAsync interface to load the AssetBundle package, Unload(true) unloaded, and used C # 's FileStream as the way to read the binary file, but it will report when the resource is loaded more Too many open files error, as shown:

Our FileStream is released when AssetBundle is unloaded, the release method is as follows:

mFs = null;

At the same time, we used the adb shell ulimit to check that the upper limit of the handle of the mobile phone is 1024. The number of AssetBundles we loaded at that time was about 500. I did not find similar information on the Internet.

Supplement:We used adb to look at the handles actually used by the process, and compared it with the package that used LoadFromFile without error before, and found that each AssetBundle has an extra handle, and the previous method is not. Now that our FileStream stream is released after Unload, should it be released after the load is completed? But in this way, subsequent loading of the AssetBundle will report an error. The following figure is a screenshot of the extra handle:

A1:It is recommended to use LoadFromFile test to see if there is a problem. Here is the scheme using LoadFromFile + File offset encryption, please refer to Unity AssetBundle Efficient Encryption Case Sharing .

4.5.4. IOS file handle overuse
Current versions of Unity are not affected by this issue.
In versions prior to Unity 5.3.2p2, Unity would hold an open file handle to an AssetBundle the entire time that the AssetBundle is loaded. This is not a problem on most platforms. However, iOS limits the number of file handles a process may simultaneously have open to 255. If loading an AssetBundle causes this limit to be exceeded, the loading call will fail with a Too Many Open File Handles error.

This was a common problem for projects trying to divide their content across many hundreds or thousands of AssetBundles.

For projects unable to upgrade to a patched version of Unity, temporary solutions are:

Reducing the number of AssetBundles in use by merging related AssetBundles

Using AssetBundle.Unload(false) to close an AssetBundle s file handle, and managing the loaded Objects lifecycles manually

Assets, Resources and AssetBundles-Unity Learn
Thanks to Cyclonus @UWAFAQ Community for providing answers

A2:You can try to release the FileStream stream after loading to see if the number of handles is reduced. But I personally think that it is likely that LoadFromStream itself will generate 2 handles, but no test has been done, and the subject can try it.

LoadFromStream currently uses very few teams, which are generally used for encryption, but whether it is really necessary to load each AssetBundle, this needs to be considered by the R & D team. At the same time, if LoadFromStream is really needed, then the most realistic way to follow up is to reduce the number of AssetBundles resident in memory.
This answer is provided by UWA


Q:This problem was discovered when the project was upgraded from Unity 5.6 to 2018, and it is currently suspected to be a particle system bug introduced by Unity 2017/2018.

what happened:

1. The version used is Unity 2018.4.9 LTS(tested Unity 2017 LTS will have the same problem, and Unity 5.6 is correct);
2, the particle is composed of two layers, the back is a sub-emitter of triangles(inherited size), Size over Lifetime is checked, but only a constant(a straight line of 1.0) is given;


  • back

3. If you do not check | Separate Axes |, everything is normal, the screen shows triangle particles with a square background, which is as expected(see blue particles in the picture);

4. If | Separate Axes | is checked, and all three axes are set to a straight line of 1.0, the screen displays triangle particles with a flat rectangular background, which is completely incorrect(see red particles in the figure).

According to my understanding, whether to check | Separate Axes | should not affect the display result, because the three axes are set with the same curve(a straight line of 1.0). It should be noted that this situation occurs only when the back is a sub-emitter of triangles. If it is an independent ParticleSystem, the behavior is correct after a simple test(the display is all square).

How to reproduce:

  • Download the Any3D project in the attachment(available in the original Q & A)
  • Open Scenes/SampleScene scene
  • Click 'Play' to reproduce
  • There are only blue and red particles in the scene and only the Separate Axes settings are different, other settings are exactly the same

I hope to get everyone's help to see if the setting is wrong or how to avoid this problem. Thank you endlessly!

A:Check the 3D Start Size of back \ _red, and find that the X and Y axis zoom are not the same. If both are changed to 2, it will be fine. Also check the 3D Start Size of back \ _blue and find that the effect is the same as back \ _red. Personally feel that 3D Start Size and Separate Axes play the same role, so be consistent.
Thanks for the @UWA question and answer community all day long for providing answers


Q:Free-view game, some skills look normal when they are far away from the camera abnormal. What are the possible reasons?

A:It is likely that the computing pressure on the GPU side is too high, and when close to the special effects, Overdraw must increase significantly.
This answer is provided by UWA


Q:As shown in the picture, is this situation normal? In my understanding, the cost of particles is under Render.TransparentGeometry, why is it reflected in Render.OpaqueGeometry? What does this indicate?

A:This is related to the Render Queue of your particle material; the queue is Transparent, then naturally it is under Render.TransparentGeometry, and the queue is Geometry, then under Render.OpaqueGeometry.
Thanks to Li Xing @UWAFAQ Community for providing answers

Today's sharing is here. Of course, there is no limit to life. In the long development cycle, these problems you may see are just the tip of the iceberg. We have already prepared more technical topics on the UWA Q & A website for you to explore and share together. You who love progress are welcome to join, maybe your method can just solve the urgent needs of others; the "stone" of other mountains can also attack your "jade".

Official website:
Official technical blog:
Official Q & A community:
UWA Academy:
Official technical QQ group:793972859(the original group is full)

Related Posts