Search Unity

collider2D rotating in 3D = very slow

Discussion in 'Physics' started by laurentlavigne, Jun 24, 2017.

  1. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,364
    The 3D objects roates in all 3 axis, a kinematic rigid2D on the root, parented under the rotating pivot are a few circle 2D colliders.
    I was surprised to see that Physics2D takes 12 ms on a i7 7700 to destroy the collider shapes!
    Could the Physics team optimize that scenario?

    profiler physics 2d collider very slow.png
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    If you want a Collider2D to move you should be moving the body and not the Collider2D itself. If you move the Collider2D then it has to be recreated. The same goes for performing Transformation; do not perform 3D rotations on 2D colliders. PhysX has a transform for this, Box2D does not where effectively any collider shape(s) are immutable and directly live in the space of the Rigidbody2D which is the only thing that should be moving. The same goes for simple things like (say) changing a radius of a circle; that means the circle has to be recreated.

    2D is already pretty optimized in terms of avoiding recreations so it'll only perform them if it's absolutely necessary; rotating a GO in Z with a Rigidbody on it will not cause any of its connected colliders to be recreated. Rotating in XY will (not that circles or capsules will rotate in 3D anyway). All scaling operations will cause a recreate. The same goes for any properties that change the collider geometry. Anything else causing recreation is a bug!

    Also, it won't take 12ms to "rotate a few circle 2D colliders"! In the profiler you're showing this being done thousands of times. Destroying shapes has a larger overhead then creating shapes because there's extra work being done to ensure that when the shapes are recreated, any new contacts on the recreated shapes are paired with the old contacts so you get enter/stay/exit callback consistency. This is a PITA to do but without it, you'd just keep getting enter callbacks.

    FYI: There's work in the planning stages to rewrite large parts of Box2D to get around a bunch of things that are a pain. One of them is this issue with immutable shapes and the other is contact reporting and handling. This work won't start until much later in the year however.

    If you have a simple reproduction case, I'd be happy to take a look at it.
     
    Last edited: Jun 26, 2017
  3. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,364
    Thanks for the thorough background, it is very helpful to know the nuts and bolts, avoids surprised - could the doc team add these details?

    A bit of background so you can understand why box2d is needed in some situations: it's a 3D side shooters. Loads of 3D side shooters have awful impact detection, like Sine Mora, because they use 3D collisions: when the enemy is rotated in some fancy ways, some colliders are off the z=0 plane where the player's bullet live, so you miss an enemy that, in all appearance should get pummeled - very frustrating. Using Box2d enforces a 2D profile that feels right to the player. Huge difference.

    I don't think you need a repro project because what you described is 100% and I worked around it by implementing some aggressive culling, it brought the ms to manageable levels. If you want to access it anyway you can ask the QA folks, they have collab access to "Das Grind Machine". I made a minimum project anyway to show the effect of hundred of 3D animated objects with 2d colliders, just in case there is something I'm missing. attached to case #924706
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    I checked out your project. So not a "few Circle 2D" then, actually hundreds each frame and also you're only rotating in Z and not all three axis. It's really not clear then what you want.

    So back to the project; you are not rotating the Rigidbody2D at all, you are rotating its child hierarchy so colliders are being moved releative to the body, which begs the question why you've even got a Rigidbody2D at all. In your project, you are rotating a GO named "pivot" in Z only. If this is the only GO rotating in Z then add the Rigidbody2D here. This will rotate the Rigidbody2D only and not cause the Collider2D to be modified because they live in the space of the Rigidbody2D and in 2D, a rotation in Z (as well as translation in XY) are fine.

    In summary, move the RB to the "pivot" GO.

    Note however, if you're going to rotate the GO in XY (which is a bad thing to do and doesn't even make sense for some colliders like circles) then you'll get recreations. To be absolutely clear: circles do not rotate in XY as these as 2D colliders, not 3D ones. The vertex based ones don't rotate either, they just have their verts reprojected into 2D after rotation. This is expensive and you need to be sensible and use XYZ translation and Z rotation only for 2D and avoid scaling.
     
  5. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,364
    I understood all that on your first post, but did you understand why I chose to rotate in XY?
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    Sure I understand but I'm re-enforcing why you should not attempt to rotate the colliders. If you have a 3D asset on a GO hierarchy that must rotate, do it on a different part of the hierarchy and ensure you don't rotate the 2D colliders that way.
     
    Last edited: Jun 28, 2017