Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Feature Request Remove and reinsert objects from and to the physics world.

Discussion in 'Physics' started by georgeq, Oct 26, 2022.

  1. georgeq

    georgeq

    Joined:
    Mar 5, 2014
    Posts:
    662
    What would you do if you needed to fully remove an object from the physics world... no collisions, no gravity, no velocity, but still be present on the scene. Probably you would say: "disabale detectCollisions and enable isKinematic on your Rigidbody", but that doesn't seem to quite do the trick. Enabling isKinematic does not automatically set both velocity and angularVelocity to zero, there's no warranty once you disable isKinematic the Rigidbody will start at 0 velocity. Also, it seems the physics engine is wasting time on objects that won't have any effect on the physics world, because if your Rigidbody has collisionDetectionMode set to Continuous, you'll get your console spammed with warning messages as soon as you enable isKinematic even when detectCollisions is disabled!

    Probably you end up with something like this:

    Code (CSharp):
    1.  
    2.    internal void DisablePhysics() {
    3.       if(continuous) {
    4.          body.collisionDetectionMode = CollisionDetectionMode.Discrete;
    5.       }
    6.       body.velocity         = Vector3.zero;
    7.       body.angularVelocity  = Vector3.zero;
    8.       body.isKinematic      = true;
    9.       body.detectCollisions = false;
    10.    }
    11.  
    12.    internal void EnablePhysics() {
    13.       body.isKinematic      = false;
    14.       body.detectCollisions = true;
    15.       if(continuous) {
    16.          body.collisionDetectionMode = CollisionDetectionMode.Continuous;
    17.       }
    18.    }
    Which is not a big deal, but it is kind of annoying to know the physics engine is wasting time trying to simulate something that clearly won't yield any results, specially when you have lots of this kind of objects. The best solution for this particular case seems to be, to remove the Rigidbody and disable all colliders and then reenable all colliders and add a new rigid body, but that's kind of an overkill.

    --------

    On a different scenario, sometimes you don't want objects to just disappear from the scene, in some cases you may want to animate their size down to zero. In my opinion if an object is zero size the physics engine should completely skip it, but again, you still get warning messages which means it is wasting time trying to get results out of something that obviously won't produce any.

    --------

    It would be very useful if there was a function that would enable/disable the Rigidbody and all it's associated colliders in a single operation.
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,136
    I'm not in the 3D physics team but it sounds like you're confusing what the simulation (PhysX) is doing when you're saying it's "wasting time doing X" and what Unity is doing letting you know there's an error condition.

    If an error/warning is being reported then it's mostly a case of perhaps that it shouldn't be "spammed" but issued once only. It's also not good practice to not produce a warning when there's a bad state. I don't see why the fact that "detectCollisions" should not warn about bad state but again, I'm not in the 3D team but thought I'd respond.

    btw, what warning message are you talking about here? I can look it up for you to see what's triggering it.

    In terms of your feature request, this sounds the same as what's already in 2D i.e. Rigidbody2D.simulated but I'm not sure if that's part of PhysX or not.

    EDIT: I see there's a "PxActorFlag::Enum::eDISABLE_SIMULATION" in PhysX which supports Static and Dynamic actors but not Kinematic.
     
  3. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,477
    Never seen that behavior. Enabling isKinematic causes both velocities to be zero one physics frame later, unless you move it with MovePosition or MoveRotation. Then disabling isKinematic restarts the rigidbody simulation with zero velocity.

    I use that trick constantly for resetting vehicles: enable kinematic, wait one physics frame, disable kinematic. It's the only method I know that reliably removes all velocities from the rigidbody, even when the WheelColliders are doing their shady stuff.

    If the kinematic rigidbody is also moved to a layer without collisions, then these rigidbodies wouldn't be included in the physics queries so (as for my understanding) they would be effectively "out of the physics world".

    Most likely it's not supported on Kinematic actors because simulation is already disabled on these.
     
    MelvMay likes this.
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,136
    Yes, I guess it's not the equivalent of the Box2D "active" i.e. the Unity Rigidbody2D.simulated because that doesn't just take it out of the view of the solver, it removes any contacts and removes shapes from the broadphases but keeps them in memory so you can activate them super fast.
     
    Edy likes this.
  5. georgeq

    georgeq

    Joined:
    Mar 5, 2014
    Posts:
    662
    Sorry if didn't make a good job explaining the point. My point is that detectCollisions=false + isKinematic=true, doesn't seem to do the trick of fully removing the object from the physics world, and please notice I'm using the word "seem" to underline the fact that I do not know nothing about the Unity internals. I am not complaining about the warning messages, I understand they serve to the purpose of early detect potential problems, so that's OK. What I argue is that if these messages appear on the log, that means the code that generates them is still ruining which possibly indicates the rigid body is still being processed by the collision detection algorithm even when detectCollisions was previously set to false, I understand there may be a good reason for that, and that's precisely the reason for my request.
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,136
    What I was trying to highlight is that the collision detection (and all simulation work) is done inside PhysX itself (actors, shapes etc) and none of that puts messages up etc. Unity itself puts messages into the console etc about the higher level stuff Rigidbody, Collider etc during the player-loop. My point is that these two things are separate. Disabling features like collisions doesn't stop Unity from still having to perform higher level checking etc. The details of that depend on the specific subject.

    For instance, in 2D, disabling the simulation means nothing happens during a simulation step but when Unity has stepped the (Box2D) simulation, it then has to iterate Rigidbody2D so they can write to the Transform. Ones that have their simulated propery disabled are skipped but they are still "accessed". The performance impact of this is lower than anything the profiler would likely pick up.

    For 3D though, I believe deactivating the GameObject the Rigidbody is on is the only way to completely remove it from the PhysX world because any PhysX objects are destroyed. Keep the Rigidbody on a separate GameObject and toggle the active state would do the trick because it destroys everything then recreates everything. Again, not a 3D physics dev though.

    Also, as I asked above, if you tell me which message, I can take a look at what point inside the Unity player-loop its state is checked and the message put out.
     
  7. georgeq

    georgeq

    Joined:
    Mar 5, 2014
    Posts:
    662
    Fair enough.

    The message I get is this: "Kinematic body only supports Speculative Continuous collision detection", even though detectCollisions is set to false... in my opinion I should only see this message when detectCollisions is set to true, because I suppose it is only then when it really becomes a potential problem, but again, I don't know the internals... if having collisionDetectionMode set to Continuous can still lead to trouble even when detectCollisions is false, then it's OK, keep showing the message.

    Now, analyzing it a bit further, you're right, the message does appear only once, but when you have a lot of objects in the same condition it looks like Unity is spamming the console.
     
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,136
    I agree as I said above, sounds like you should only get this once. Perhaps when entering play-mode or something. I'll take a look at the code for you.

    Hold please! :)
     
  9. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,136
    Note I did read that you confirmed it was from multiple Rigidbody. I'm still checking when it's output.
     
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,136
    What Unity version are you using?

    I only ask because it looks like that message may have been removed because I can no longer find it in any of the source.
     
  11. georgeq

    georgeq

    Joined:
    Mar 5, 2014
    Posts:
    662
    2020.3.36f1
     
  12. georgeq

    georgeq

    Joined:
    Mar 5, 2014
    Posts:
    662
    Thanks!
     
  13. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,136
    I just checked out the source for 2020.3 and it's in there for sure when setting the Rigidbody to be kinematic:
    Code (CSharp):
    1. WarningStringObject("Kinematic body only supports Speculative Continuous collision detection", this);
    In 2021.1 I cannot find it so it was removed.
     
  14. georgeq

    georgeq

    Joined:
    Mar 5, 2014
    Posts:
    662
    Thank you very much!!!... Good to know, although we'll probably stick with 2020 for a while.
     
    MelvMay likes this.