Search Unity

Triple performance by removing rigidbodies from trigger colliders ?

Discussion in 'Physics' started by Ali_V_Quest, Mar 23, 2019.

  1. Ali_V_Quest

    Ali_V_Quest

    Joined:
    Aug 2, 2015
    Posts:
    138
    Hi,

    I have 3000 moving trigger sphere colliders, I have rigidbodies on them set to kinematic.
    Unity official docs recommends moving them with their rigidbody.
    However, the performance is really poor ( drops to 15 fps ), I tried removing the rigidbodies & move the triggers with their transform & the performance more than tripled.

    here are the numbers:
    ( I know fps is not an accurate measure, but the difference is very clear in performance & I simply want to compare different systems - not get absolute numbers )

    1. moving triggers / rigidbody game objects using transform.position gives me 15 fps
    2. using rigidbody.position or .movePosition gives 15 fps, it goes up to 30fps when disabling Physics.autoSyncTransforms
    3. removing the rigidbodies ( keeping only trigger colliders ) & using transform.position generates 60 fps

    4. using Update is much faster than Fixed Update ( whether using transform.position or rigidbody.position or .MovePosition)


    @MelvMay
    1- I need to know if moving trigger colliders without a rigidbody can cause bugs, because performance wise, it is clearly much much faster.
    2- is there any reason why removing rigidbodies enhances performance ? ( am doing anything wrong ? )

    Thanks ;)
     
    Last edited: Mar 23, 2019
    Zamaroht likes this.
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,455
    I already saw your other post here and answered for 2D physics because I don't work on the 3D physics team. You need to speak to @yant
     
    Last edited: Mar 24, 2019
  3. Ali_V_Quest

    Ali_V_Quest

    Joined:
    Aug 2, 2015
    Posts:
    138
    Hi @MelvMay
    Thanks for the help, I thought you worked the 3D physics.
     
  4. Ali_V_Quest

    Ali_V_Quest

    Joined:
    Aug 2, 2015
    Posts:
    138
    Hi @yant , What do you think about this performance behavior ?
    Thanks
     
  5. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    596
    So to clarify -- we made the static Colliders use the same pruning structure as the dynamic ones around Unity 5.0, that came in with the PhysX 3.3 upgrade back then. Before that, it was super costly to move the static Colliders without Rigidbodies, and the knowledge about that had been spread out for ages. Unfortunately, when the PhysX change went in, not all of the places were updated so you can still encounter recommendations to use Rigidbody when it's no longer actually needed so.

    Now, as to the downsides -- yes there are. Static colliders aren't exactly expected to be moved around frequently. There is a bunch of optimisation involved. Some objects won't be awoken up when the platform they rested on top of has been moved away. Vehicles have a lot of that stuff going for perf reasons.
     
    Ali_V_Quest likes this.
  6. Ali_V_Quest

    Ali_V_Quest

    Joined:
    Aug 2, 2015
    Posts:
    138
    @yant Thanks a lot for helping,
    Just to clarify, I'm not using static colliders ( just moving trigger colliders without rigidbodies on them ).
     
  7. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    596
    A static collider is any Collider that doesn't have Rigidbody component attached to any gameobject up the hierarchy. It's indeed supposed to be stationary, not moved., however the cost of that move has been reduced dramatically over the years like I posted above. Thanks for your interest in physics.
     
    Ali_V_Quest likes this.
  8. Ali_V_Quest

    Ali_V_Quest

    Joined:
    Aug 2, 2015
    Posts:
    138
    Ah I see, I thought it should be marked as static
    Thanks again for the help
     
  9. hungrybelome

    hungrybelome

    Joined:
    Dec 31, 2014
    Posts:
    336
    @yant So do you recommend adding kinematic rigidbodies to colliders that are triggers? Right now I have a lot of trigger colliders that are parented to my moving character, that are used only for Sphere/Raycasts. I'm wondering if I would get better performance by adding kinematic rigidbodies to them, and them making sure their layer does not interact with another layer in the Physics matrix.
     
    Bumpty likes this.
  10. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    596
    I'd suggest to try what works best for your setup actually - try this way and that way and see what performs better. Raycasts don't need Rigidbodies, at all. Queries will do just fine with Collider no matter whether they are moved or not. Pay attention to the flag called auto sync transforms. If it's on, then the Raycast will sync transform before calling in to PhysX, and will not sync otherwise. NB: transforms are sync'ed at least once just before the simulation regardless of the flag.
     
    hungrybelome likes this.
  11. hungrybelome

    hungrybelome

    Joined:
    Dec 31, 2014
    Posts:
    336
    Thanks, I'll give it a try.

    Just to be sure, for a collider to be considered static, does it only have to not have a Rigidbody? Or does the gameObject also have to be marked static with one of the StaticEditorFlags, like StaticEditorFlags.BatchingStatic?
     
    Zamaroht likes this.
  12. yant

    yant

    Unity Technologies

    Joined:
    Jul 24, 2013
    Posts:
    596
    Only the fact whether there is a Rigidbody anywhere up in the hierarchy is considered for the static thing. The flags you mention don't apply to physics at all.
     
    Zamaroht and hungrybelome like this.
  13. rc82

    rc82

    Joined:
    Jan 28, 2020
    Posts:
    44
    Thanks for this thread! Removed my rigid bodies from my projectiles and gained a steady 4-5fps boost right away!
     
    Zamaroht likes this.
  14. abandon_games

    abandon_games

    Joined:
    Sep 1, 2017
    Posts:
    38
    this thread needs to be shouted from the mountain tops - so much conflicting information out there about rigidbodies, thank you for being the voice of clarity @yant

    hoping you might be able to clarifying a couple more questions about rigidbodies in 3D:
    1. is a collider still considered "static" if it is on a child object of a kinematic rigidbody? can/should I move the child by its transform?
      • i.e. I have a player character parent that has a rigidbody > I set it to kinematic to move the player character via scripting > the player character has a child object with colliders on it (i.e. a weapon in-hand) > I want to move that child object with player input via scripting => do I move that child object by its transform (
        child.transform.position = someNewVector3
        )? do I still need to go through the parent rigidbody somehow? or should this object not be a child and have its own rigidbody in this case?
        • is the answer to this question also true if the child object only has trigger colliders? or a mix of both?
    2. the Collision manual for Kinematic Rigidbody Collider states "You can move a kinematic rigidbody object from a script by modifying its Transform Component" but this hard to believe given everything I've read so wanted to confirm:
      • is this true? I can safely (performance-and-fidelity-wise) change the position and rotation of a kinematic rigidbody by directly manipulating the transform of its GameObject?
        • i.e.
          someGameObjectWithAnRb.transform.position = someNewVector3
      • or should I still go through its rigidbody?
        • i.e.
          someRbReference.position = someNewVector3
        • i.e.
          someRbReference.MovePosition(...)
    3. lastly, does the movement of kinematic rigidbodies and static colliders need to happen in FixedUpdate? or can it be done it Update?
      • or would you recommend it always be done in FixedUpdate since the Update frequency varies by framerate?
    again, thank you for clarifying this physics for us @yant , been dying to pick the brain of someone with your knowledge
     
    Zamaroht likes this.
  15. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,455
    First, here's the TLDR:
    1. No, it's a Collider attached to a Kinematic Rigidbody so it should be clear it's Kinematic.
    2. If it moves in physics, move a Rigidbody and use its API to effect that move. That doc page need updating.
    3. Always do it prior to the simulation running so FixedUpdate if that's when physics is running

    Full explanation.

    Point 1:

    It's not about a consideration of being Static. In-fact a Collider isn't even this because it's actually the Rigidbody(2D) that is as it has three behavioural modes of operation which are Static, Kinematic and Dynamic. You can find this information online for various physics engines as it's not related specifically to Unity either and whilst your post is about 3D, the 2D reference here should help a little but there's a bunch of online guides, tutorials etc like this.

    Every single Collider is "attached" to a Rigidbody(2D) so it's therefore stated that a Collider itself is Static, Kinematic or Dynamic even though it's technically best to think of the body being that and the colliders are along for the ride.

    For 3D there's no explicit "Static" option though, there's only a "IsKinematic" option which let's you select Kinematic (when it's on) or Dynamic (when it's off). This differs from 2D physics where there's an explicit Rigidbody2D.bodyType property allowing you to select it. All collider are attached to a body where a body is what a Rigidbody(2D) contains; It's the thing in the underlying physics engine. I think it'd be nice to have feature parity here to reduce some confusion.

    I say body because in Unity there's a specific implicit behaviour where if you don't add a Rigidbody(2D) then the Collider is implicitly Static because it's added to a ground-body that is Static.

    So if you want to know what's Static, Kinematic or Dynamic; look at the body (Rigidbody). In 3D, as I've said, the only way to have Static is to not add a Rigidbody.

    It makes no difference if it's children, triggers or anything else. The ability for a Collider to be implicitly Static by not adding a Rigidbody(2D) is supposed to be a time-saving exercise so you don't need to add one for stuff that isn't going to move. Do devs move Static stuff? Yes. Should they? No. Is Unity honour bound to support Transform changing and then having to update physics stuff? Yes. Is it optimal? No. Can you do a lot of it without killing performance? Yes but it's designed to not be moved still. It's your script though, the freedom is yours.

    Point 2.

    That part of the 3D Rigidbody manual should be changed. The rule is, if it moves, it's a Rigidbody(2D) that should be moved via its API. Forces, Impulses, Velocity, MovePosition/MoveRotation, Explicit setting of Body position/rotation etc. Again, if you want to modify the Transform then you can do it but understanding what the difference is, is the most important part in knowing whether it's appropriate or not.

    Setting an explicit position/rotation means you teleport there. You can cause overlaps which the solver then has to solve and other issues such as interpolation issues. If it's 3D and Kinematic then use the provided MovePosition/MoveRotation.

    The worst part of modifying the Transform is the expectation that it somehow lets other systems know it's changed; it doesn't. Systems only know about it when they run! Renderers have it easy because they run per-frame anyway and read the latest Transform. Physics doesn't run per-frame (by default) so it only sees that change when the simulation runs (sync-transforms).

    This is why you should get the Rigidbody to move and use interpolation to get the Transform updated per-frame.

    Point 3.

    You can run physics per-frame, per-fixed-update or whenever you like. The main thing to understand when asking questions like "does the movement of kinematic rigidbodies and static colliders need to happen in FixedUpdate?" is that the answer could be "yes" but also, "it depends" and also "no". Unhelpful I know.

    MovePosition/MoveRotation don't move it there and then, it cannot simulate it there. You calling it is saying "I'd like to move the position/rotation when the simulation runs" so it happens when the simulation runs and is complete when the simulate step completes. If you call the MovePosition in Update and the Physics is running in the FixedUpdate, maybe your frame-rate is 200fps but fixed-update is only 50fps (50Hz); this means you'll call MovePosition 4 times before it's even processed; only the last one will be handled. In this scenario, yes, call it in FixedUpdate as it happens just before physics runs. The answer would be no if you we not running physics like that, maybe manually for instance.

    The physics system is super simple in reality. It runs by default in the fixed-update. If you perform an action that is only going to happen when the simulation runs then doing it per-frame is at best a waste of time and at worst, causes problems such as when devs add forces per-frame to find that faster frame-rates means more force added. For all other stuff like queries, run them whenever you like; the results won't change from frame-to-frame if the physics isn't running per-frame though.

    Likely I didn't answer all the bits you need to know and/or there are technicalities/oddities in 3D physics that might make some of what I said not strictly true in all cases so I'll leave others to advise you on those.

    Anyway, hope that helps.
     
  16. abandon_games

    abandon_games

    Joined:
    Sep 1, 2017
    Posts:
    38
    thank you for the details @MelvMay, it's sometimes difficult to understand what you can do vs what your should do when getting information from a 3rd party (i.e. devs) - it's nice to get cold hard facts from an authority on the matter from which to build our understanding

    if I could boil your answer down to one line it would be: Unity has done everything it can to support moving an object by its transform without totally killing your performance, but unless you want to risk unexpected behaviors (described above) all movement of an object should occur through a rigidbody

    I believe I'm beginning to see the light here, but I'm still a bit fuzzy about a scenario described in this post I made - I'm certain almost every first person game ever made has a similar setup but I can't find a straight answer, consider (in 3D):
    • a first person player character with a rigidbody
    • the player character holds an axe (an object with colliders on it)
    • at certain moments I want pause character movement and allow the player to swing the axe
    What's the appropriate physics setup here? I'm thinking:
    • the axe has its own rigidbody and is attached to the player with a joint
    But the responses to my post and some other recent information would suggest:
    • the axe is a child of the rigidbody and can be moved by its transform
    @MelvMay @yant what is the appropriate setup and technique here?
     
  17. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,455
    The only supported child Rigidbody(2D) is a Kinematic body because (A), it follows the parent as you'd expected a child to follow a parent and (B), when you want to perform explicit movements on a body, you'd always use a Kinematic body.
     
  18. abandon_games

    abandon_games

    Joined:
    Sep 1, 2017
    Posts:
    38
    @MelvMay is the same true for 3D? I'd want to use a kinematic rigidbody for the axe child object?

    this tutorial just spun me around in the other direction... the Moving Static Colliders chapter states "[kinematic rigidbodies] are not needed for simply moving objects without complex physics behavior"

    in the scenario I described above, the colliders on the axe are only used to detect collisions, I don't need them to set off chained physics reactions nor do I need the axe to be affected by physics (it's only moved by player input) => do I still want a rigidbody for this axe?
     
  19. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,455
    Yes. There's no reason for them to be different.

    But that doesn't related to your case. You're wanting a body that works in a hierarchy by following a parent but you also want to be able to move it explicitly yet you're associating this with "simple behaviour"?

    What are "physics reactions" and what does "affected by physics" mean? Try to avoid those kinds of statements because they are super ambiguous. A Dynamic body is the only type of body that has a collision response so I'm not sure what a Kinematic body does that you don't want.

    I think it comes down to understanding what Static, Kinematic and Dynamic bodies are TBH.
     
  20. abandon_games

    abandon_games

    Joined:
    Sep 1, 2017
    Posts:
    38
    I guess I was thinking of "simple behavior" in terms of the physics involved: it's being moved by its parent, and then by the player, its not moving freely in the physical world - but I think I'm picking up what you're putting down, this is an independent body that can be moved by different sources, and therefore needs its own dynamic (kinematic) rigidbody for that body to be treated as such