0/ 31/ /0

This time we will share several technical topics which are related to Program development. It is recommended to read for 15 minutes. Any unique insights or discoveries, please feel free to contact us or discuss.



Q1: The characters in our project will have some streamers on their arms. Some of the character’s streamers will have a strange rotation angle after being set to Humanoid mode, which is inconsistent with the animation displayed under Max and Generic. For example, in Max, there is an animation of a streamer drooping, and the two streamers under the Humanoid will show up as an X-shaped cross.


The contents checked so far are as follows:

1. The skeleton redirection in Avatar is normal, and it is T-Pose. Except for the arm streamer, the animation of other skeletons is normal.

2. The mask in animation import settings has checked all skeletons.

3. I previously thought that the error was caused by the Twist skeleton of the arm, but later the animation was still abnormal without this skeleton.

4. Under Muscle Setup in Avatar settings, adjuste the Upper Arm Twist parameter and Lower Arm Twist parameter can slightly fix the problem, but it cannot be completely repaired, and other parts of the animation may have problems.

5. Comparing the Animation files in the two modes, I find that the data of the corresponding frame is different, and the transform value of two modes of the same skeleton is different in the same frame.


I wonder if anyone meets the similar trap? Please share your experience.

Changing to Humanoid, the skeleton will have interpolation of spatial conversion and intermediate skeleton, so it may cause incomplete correspondence of position information. You’d better pass an example for us to check. Or can you try using extra skeletons to hang the streamers instead of putting them on skeletons mapped by Humanoid, so that the extra skeletons will use Generic mode and avoid being affected by Humanoid.

Thanks to Saber for providing the answer above.

Have you checked whether positions of the skeletons which have streamers on the arms in Avatar’s T-pose are abnormal? The 3D Max on my computer has been uninstalled, so it is not convenient for testing. When doing Retargeting, you should pay attention to the position of the skeleton in question in Unity’s T-pose, it should be the same as the position of the skeleton in 3D Max which has pose by default.


Humanoid type animation will also change to store the difference value after selecting Avatar, these values are the “subtraction” of each pose and T-pose in the animation, and then the difference value will be applied to the target model at runtime. In the same model, the theoretical result should be exactly the same as that in Generic mode, otherwise it should be caused by some inconsistencies in the animation file or some poses in the model file.


It is not convenient for me to do Demo verification for the time being. It is recommended to take the same animation file to export a Mesh and an animation, and then use this set of resources for verification to see if the animation effect can be realized correctly. If it works, then what I said can be verified.

Thanks to Jia Weihao for providing the answer above.

Currently, I find a solution:

As mentioned in the question, in Avatar’s Muscle Setting, adjust the Upper Arm Twist parameter and Lower Arm Twist parameter can slightly fix the problem. Later, I carefully study these parameters and find that my previous adjustment method is wrong.

I guess the reason may be that Humanoid does not support the mapping of Twist skeletons, so these two parameters are added to realize additional movement of the additional skeletons on the arm.

When Lower Arm Twist is 0.5 by default, the armband will rotate with the wrist.

When Lower Arm Twist is 0, the arm rotation is only affected by the elbow, and the effect is the same as Generic.


The skeleton levels are as follows:

Thanks to Wang Yang for providing the answer above.


Q2: I use Resources.UnloadAsset () to unload the loaded image and find that the unloading is invalid, the code is as follows:

When I load for the first time, the memory looks like this:

When I call Resources.UnloadAsset, the memory changes, but it is still in the memory:

It is not completely cleared from memory until the last call to Resources.UnloadUnusedAssets():

If I don’t unload UnloadAsset, the loaded sprite can still be used:

My understanding is this, when I call Resources.UnloadAsset to release a Sprite, the Image referencing this Sprite should also lose resources. I don’t know if I misunderstand something. The current situation is that after I UnloadAsset, the reference image of this Image still exists.

Your understanding is correct, your code is only operated on Sprite, but not on Texture indexed by Sprite, so UnloadAsset will not unload Texture, when it has no index, it can only be uninstalled through UnloadUnusedAssets.

This answer is provided by UWA


Q3: I load JSON on the Internet in the project, and use OpenCTM in memory to generate the Unity Mesh. However, when the reverse sequence OpenCTM format is generated, a large number of GC will also be generated. By positioning, I find that the problem is on the following constructor function. Is there any solution?

The plug-in used is the C # library of OpenCTM. The problem is that during the analysis of OpenCTM data, too many OutWindow classes are instantiated, resulting in a lot of garbage, which leads to the trigger of the garbage collection mechanism, so the time for parsing data becomes much longer.


The optimized method is: cache an OutWindow instance.

Thanks to Wang Yang for providing the answer above.


Q4: How to solve the problem of displaying white on the screen of specific models?

We have also encountered this serious problem on iPhone X, and it seems that there are errors in the calculation of black spots.


Test situation: After checking the code, the programmer suspect that there is a problem at the DOF stage, Bloom amplifies the problem, but this problem cannot be solved by modifying the code. The problem is caused by the Fresnel effect. In the calculation of pow (1-NdotV, exp), it is suspected that 1-NdotV is triggered at 0, modify it to Max (1-NdotV, 1e-4). (1e-4 is 10 to the power of -4, that is, 0.0001).

Thanks to Wen Ya for providing the answer above.


Q5: We want to expand the color change function based on GPU Skinning, that is, different teams have different colors, like this:

My current method: I change the Shader myself, it is possible to perform in the non-running state, but all instances will become the same as soon as it starts running.


If I replace shared Material with my new Material, it doesn’t work as well, then I simply create a new Shader. After running, the parameters of Shader will still be forced to be unified, that is, the performance becomes the same. Then I make two Textures for different shaders and assign different mappings, but the situation is the same after startup. I feel that as long as the Shader is the same, no matter what is replaced or changed, it will be replaced to a certain one during the operation.


Please tell me whether my idea is wrong, or if I don’t notice something in the process?

Don’t assign directly to your HSV through Property, it won’t work like this:

Because the final material used by this system will eventually be hosted, but not the one you create.


If you want to customize some parameters, you need to use MaterialPropertyBlock. In GPU SkinningPlayer.cs, you can find this MaterialPropertyBlock, and then set the values you need, like the following:

Thanks to jim for providing the answer above.

This is the 67th UWA Technology Sharing for Unity Development. As we all know, Our life has a limit but knowledge has none. These problems are only the tip of the iceberg and there are more technical problems during our program development which deserve to discuss. Welcome to join UWA Q&A community, let‘s explore and share knowledge together!




Post a Reply