0/ 82/ /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: I would like to ask a question, does the number of skeletons and the number of levels have a great impact on performance ( mentioned in some articles)? After a simple test, we find that the impact is not very significant.


A 3000-face character with 100 skeletons and 7 layers, is this a reasonable indicator? Or there is still a lot of waste?

I don’t know how you test it. When GPU skin is not turned on or special processing methods are used, the performance of CPU is mainly affected. So I think the more scientific method is to judge by counting the time consumption of the animation module in CPU in the case of different skeleton numbers.


For example, there will be n characters in the target scene, so you can place n characters according to 60 skeletons and 100 skeletons, and compare their time consumptions.


In addition, 100 skeletons mean that the maximum skeleton is 100, or it means that the number of skeletons of all characters participating in skinning is 100, there will also be difference here. I have also done a simple test, and I find that the number of skeletons participating in skinning will ultimately affect the performance consumption of Animator.Update. So if you use the maximize skeleton scheme, you don’t need to specifically limit the number of maximum skeletons, but should limit the number of skeletons participating in skinning of each character.


For example, the comparison of performance consumption of animation-related modules on PC:


100 characters and 300 bones all participate in skinning:

100 characters, 300 bones, but only 60 of them are involved in skinning. (Update: After confirmation, it is found that when Unity is exported, the skeletons which do not participate in skinning will no longer be exported. All the concepts of 300 skeletons here only exist in Max, which has been optimized to 60 skeletons in Unity. )

100 characters and 60 bones all participate in skinning:

Of course, we just test the difference of performance here, more real data should be carried out on the target model.


In addition, it may be not good that there are too many layers of skeletons, but if the GameObject optimization option is turned on, I don’t think that there is a big difference in performance between the 7th and 10th layer. I’m not very sure, and I just infer from the animation calculation process – the engine generally stores a transformation matrix to the root node for the direct use by the child node when calculating layer by layer, so it will not add a lot of extra consumption here. However, this suppose requires some tests. I haven’t seen Unity’s source code, so I’m not sure.


In terms of performance, for the project which is just established, 100 bones and 7 layers, I think it is OK, but 3000 faces is a bit conservative. This depends on the specific game type. Of course, the number of skeletons should also be judged according to the type of game. For example, action games may require more skeletons.


PS: Use the humanoid model in this test.


PPS: Explain this experiment again. After communicating with @xin, I find that this experiment is meaningless.


Previously, when I doing the self-research engine, after the model was exported, even skeletons which did not participate in the skinning were exported to the model either, so when the animation was updated, there was an optimization to remove these skeletons. Initially, I wanted to verify through this experiment whether Unity would do such an optimization ( I suppose that Unity will make it because it is basic). However, I found that Unity has already done this optimization in the part of export, that is, there are 300 skeletons in Max, and only 60 are involved in the skinning, so only 60 skeletons are imported into Unity.


The significance is in the limitation on the number of maximum skeletons mentioned above. Our previous limitation on the number of skeletons was at the layer of maximum skeletons, but now it seems that it should be limited to the layer of skeletons in the final model.

Thanks to Jia Weihao for providing the answer above.


Q2: Unnecessary skeletons will disappear after the option “Optimize Game Object” is turned on in animation system. We put a lot of special effect hanging points under skeletons. We are also clear that these hanging points can be exposed through Extra Transforms to Expose, and then use Editor tool for batch processing.


Now I meet a problem, artists hope to add an exposed hanging point. In fact, some FBXs do not have such a hanging point. So I hope to check whether the hanging point exists in the FBX firstly during the process of tool. If this point doesn’t exist, then a new point has no need to be added, because the option “Optimize Game Object” of all FBX are checked before, but there is no way to get the names of all skeleton points before optimization through LoadAsset. Is there any way to get the names of all skeleton points of FBX?

You can use ModelImporter.transformPaths to get all the node paths under FBX.

Thanks to Zhang Shoufeng for providing the answer above.

In addition to ModelImporter, parsing Avatar is also feasible:

public static bool HasSkeleton(this GameObject gameObject, string skeletonName)
    Avatar avatar = gameObject.GetComponentInChildren<Animator>(true).avatar;
    SerializedObject serializedObject = new SerializedObject(avatar);
    var property = serializedObject.FindProperty("m_TOS");
    for (int i = 0; i < property.arraySize; i++)
        string fullSkeletonPath = property.GetArrayElementAtIndex(i).FindPropertyRelative("second").stringValue;
        if (fullSkeletonPath.EndsWith(skeletonName))
            return true;
    return false;

Thanks to Zhang Di for providing the answer above.


Q3: I want to get the SVN version number of my project during packaging. Does anyone know how to get it?

Use SVN info on the command line, and then you can see the version number from the return value.

Thanks to deviljz for providing the answer above.

Pack it with CI

svn log -v -r BASE:HEAD $unity_project_path

SvnVersion=`svn info | grep "Last Changed Rev" | tr -d "Last Changed Rev: "`

echo "SvnVersion:"$SvnVersion

Enable Unity and pass in parameters

$unity_path -batchmode -projectPath $unity_project_path -executeMethod BuildUi.BuildFromCI SvnVersion-$SvnVersion

Obtain it with C #

public static string SvnVersion
                foreach (string arg in System.Environment.GetCommandLineArgs())
                    if (arg.StartsWith("SvnVersion"))
                        return arg.Split("-"[0])[1];
                return "";

Thanks to Bob-637888 for providing the answer above.

Version management

Q4: How do you avoid or resolve the conflict between the Prefabs of two branches on Git? If the external version is rapidly iterating, the internal version is developing for being published in a few weeks later. But if both versions are changed to the same Prefab, how to do when they need to be merged. I use Git, can it be solved with SVN? Or is there any better tool to resolve the conflict (Which is better between Unimerge and UnityYAMLMerge?)

I can provide an idea. We refer to Unimerge to implement a tool of comparison and merge across Unity processes, and open 2 Unity to compare the corresponding Prefab.

Thanks to littlesome for providing the answer above.

The function of Nested Prefab is provided in Unity 2018.3, which can make the granularity of Prefab much finer to reduce the chance of conflict.

Thanks to 加菲教主 for providing the answer above.


Q5: Is it necessary to still use the ETC1 format now (early 2019)? The argument 4 or 5 years ago was that low-end machines couldn’t support ETC2, so we need to use the method “ETC1 + Alpha separation” to support low-end machines.


Today, the high-end machines in the past can only be regarded as mid-range machines. Most of the low-end machines of that year may also be eliminated. In the background that iOS versions of the game agree that the ASTC format does not support 5S by default, is it necessary to use the “ETC1 + Alpha separation” method to set the texture format? After all, using ETC2 by default can save more memory and avoid more troubles than the method of ETC1 + Alpha, and the effect of the former one is better as well.

If it is a game for the domestic market, as long as it is not a chess game (or has special support requirements for low-end mobile phones), ETC2 can be directly used on Android.


But if it is aimed at overseas markets, such as Vietnam, Thailand, India and other regions, it still needs to be carefully considered. According to the feedback from a large number of teams at present, many foreign countries still have lower-grade model equipment. For this situation, it is recommended to communicate with the operation team on occupancy rate of the equipment.

This answer is provided by UWA.

This is the 59th 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