Search Unity

Important discovery — Empty children of rigidbody reduces a performance [Pictures inside]

Discussion in 'Physics' started by Artaani, Mar 16, 2016.

  1. Artaani

    Artaani

    Joined:
    Aug 5, 2012
    Posts:
    423
    Introduction
    I have a game where player can build their spaceships from premade modules. I do not use fixed joints, instead, I just parent each module to single Rigidbody, but when I start to check optimization, I found an interesting phenomena.


    Phenomena
    When the Rigidbody have children (even empty, without any component except Transform (which can't be removed) it have much worse performance


    In depth analysis
    And this turned out very surprisingly, because seems like no one know about this phenomena. Let's take a closer look via few tests;



    Test №1
    Let's write a loop which will instantiate 100 Rigidbodies (without any component except Rigidbody)
    Each of these Rigidbody will contain 100 children
    Each of this 100 children - it is a basic cube (with 3 components, Mesh Filter, Mesh Renderer, Box Collider
    Each Rigidbody does not touch anything and just wall down under the influence of a gravitation




    Camera is disabled, quality level minimal, scene does not contain any other objects, pure test. Now let's look at the FPS.
    FPS: 300

    Okay, now let's make another test.


    Test №2
    Conditions pretty much the same as in the Test №1, with only one difference:
    Each child (which is basic cube) now have 10 sub-children
    Each of these sub-children is completely empty (it does not have any component except Transform, and even all values of Transform set to 0)



    Let's looks at the FPS again.
    FPS: 150!


    Analysis of the Test №1 and №2
    Such as interesting result! I realized that large amount of colliders in children of rigidbody may impact performance, because it is colliders, that is quite obvious, Rigidbody should process it.

    But I do not expected that even large amount of completely empty children may impact performance.

    And after that result, I made an interesting assumption. What if colliders in the children does not have any influence on performance at all? What is performance decreased due to children itself, not a colliders?

    Let's check it!


    Test №3
    As in the test 1, lets instantiate 100 Rigibodies, but, instead of instantiating 100 children for each Rigidbody, let's add to each Rigidbody a 100 Box Collider components, and move "center" parameter of each Box Collider to the appropriate position of boxes from the Test 1.

    There what we got


    And let's check the FPS.
    FPS: 900!


    Analysis of everything above
    So, that is really important discovery for everyone who working on physical sandbox projects!

    Of course someone probably already know that and find my "Important discovery" statement too loud, but I guess that many developers don't know it, because of the next things:

    1
    In this official manual, Unity recommends to add complex, convex colliders as a child http://docs.unity3d.com/Manual/class-Rigidbody.html
    Probably many developers follow this suggestion (including me), but turned out it is wrong.

    2
    Some time ago I found this popular tool https://www.assetstore.unity3d.com/en/#!/content/4596
    (9-th position in "Physics" category sorting by popularity) Seems like authors of this tool is professional and know what they are doing, I do not used this tool yet, however in this video
    on 2:34 you may see that each colliders is also added as a children. So probably even authors of this tool don’t know about this issue.

    3
    At this forum we may found thread where people saying about their methods (parented colliders) and none no said them that they are wrong.

    So, let's check my assumption 1 using one more test:


    Test №4
    Unity manual http://docs.unity3d.com/Manual/class-Rigidbody.html recommends to use several convex colliders as a child of the Rigidbody.

    So, let's compare a performance of two different prefabs:

    Prefab 1:
    Root contains 3 components. Mesh Filter, Mesh Renderer, Rigidbody. Also it contain 4 children, each of them have 1 Box Collider component (as manual recommends)



    Prefab 2:
    Root contains 7 components. Mesh Filter, Mesh Renderer, Rigidbody and also 4 Mesh Collider components.


    Let's instantiate 5000 instance of each prefab and check the FPS:
    Prefab 1: 60 FPS

    Prefab 2: 120 FPS



    Conclusion
    So, what we have. If you have complex collider and you want to separate it on smaller convex colliders, would be better to add several Mesh Collider components on the root, instead of adding additional child, despite the fact that adding a child it is quick and convenient method.

    Or if you have a cannon and want to designate a point where projectiles should be instantiated, would be better to setup at as Vector3 variable from the code, instead of using child and Transform.position.

    Or maybe my testing techniques is flawed, in that case, you may check it by you own, using the tests which are described above. If you need more information about test conditions, let me know.

    My PC configuration:
    Windows 10, 64x
    Intel Core i7 2600K
    GTX 960
    16 Gb RAM
    Unity Pro 5.3.1f1

    But if my tests and conclusions are correct, I think Unity developers should add this information to manual at Rigidbody page. http://docs.unity3d.com/Manual/class-Rigidbody.html

    Also, maybe it is just a bug, because I don't understand how simple children with Transform components may impact physics performance, in that case I would be happy to receive an answer from Unity developers.

    Thanks for your attention!
     
  2. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    I wouldn't be hasty on adding it to manual, i think they really want us to use child objects too. They make projects a whole lot cleaner too. I hope they can optimize it, what you found is really significant difference.
     
  3. Artaani

    Artaani

    Joined:
    Aug 5, 2012
    Posts:
    423
    Yes, I realize that child object is much more comfortable and I am also prefer to use it for fast and easy editing, but actually it makes sense.

    For example, we all know that fast and convenient editing have a cost of performance. For example texture atlas. Many materials is easy to edit, but single material on all objects have better performance.
    Or "Combine Mesh" mesh technology.

    Seems like this rule is actual for physics too.

    But if it is a bug, it would be good to know if developers know about it. But I assume it is "by design" and related to PhysX engine, not for Unity engine.
     
    robertono likes this.
  4. robertono

    robertono

    Joined:
    Jun 3, 2014
    Posts:
    23
    Hi,
    I am guessing, that this load on FPS is because rigidbody needs to move all the transforms that belongs to him (transform component on object with that rigidbody and all other transforms (child transforms)). Each transform movement, especially children movement by root is mathematical calculation, and thats why there is that load.

    What do you think ?
     
  5. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    FPS is hardly relevant, and I don't think your test's are overly valid.

    I would be more interested in a deep profile of what the physics step duration is.
     
  6. Artaani

    Artaani

    Joined:
    Aug 5, 2012
    Posts:
    423
    robertono, yes, seems so. I performed one another test:
    Each child is not parented in Rigidbody, instead of that, each child parented to the new empty object which is follow Rigidbody each frame by modifying its transform.position.

    But it is does not gives performance boost and the FPS similar like in test 1.

    So, conclusion is quite obvious: Amount of children inside a Rigidbody (or any moving Transform) should be minimized (for example, by combining its meshes into single mesh).


    JamesLeeNZ, I checked the profiler, but it does not provide any additional information which can be useful. Besides, the goal of optimization - increase the FPS, so it is actually quite relevant.
     
    robertono likes this.