Search Unity

Bug What the proper way to work with LimitDOFJoint?

Discussion in 'Physics for ECS' started by Yuriy_Sevastyanov, Feb 6, 2020.

  1. Yuriy_Sevastyanov

    Yuriy_Sevastyanov

    Joined:
    Apr 9, 2017
    Posts:
    25
    I use LimitDOFJoint to approach 2d in DOTS
    But then there is an annoying behavior:
    When I destroy an entity that was linked by LimitDOFJoint I get many errors:

    upload_2020-2-6_12-38-51.png


    I attached a project to reproduce this error:
    1. Load the attached project in Unity
    2. Turn off "Jobs->Burst-Enable Compilation". It's important.
    3. Run the project
    4. Press Space
    What the proper way to work with LimitDOFJoint?
     

    Attached Files:

  2. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    Adding a Joint creates a new Entity with a PhysicsJoint component. This component references the two connected Entities. If one of the connected Entities is then deleted the PhysicsJoint component is referencing an invalid Entity an so cannot find the index of the associated RigidBody. This is the assert you are hitting.
    You should really delete the Entity with the PhysicsJoint component as well. That said, we should also make the CreateJoints function more resilient to invalid data. In this case should the PhysicsJoint component be ignored or should the remaining valid body become connected to the static world instead?
     
  3. Yuriy_Sevastyanov

    Yuriy_Sevastyanov

    Joined:
    Apr 9, 2017
    Posts:
    25
    Thank you for your reply!
    I also found that it breaks by an assert in the code.
    I don't think that I should make my game logic more complex while it works because it's already complex :) I have different entities that can or not be constrained by the joints. I think user code shouldn't know about internal dependencies. I would like to use something like that: 'ON DELETE CASCADE' field. I understand that is not possible now.
    Maybe I will add a system which will spy for the joints and delete orphaned, but it sounds ugly and expensive.
    Is there any sense to keep orphaned joints?
     
  4. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    The assert happens in the BuildPhysicsWorld system in the CreateJoints function.
    If you are comfortable making Unity Physics in a local package, then you can tweak the assert code and assign a BodyIndexPair.Invalid to the pair variable before the Joint struct is created.
    Code (CSharp):
    1.                         bool isInvalid = false;
    2.                         // Invalid if we have not found the body indices...
    3.                         isInvalid |= (pair.BodyAIndex == -1 || pair.BodyBIndex == -1);
    4.                         // ... or if we are constraining two static bodies
    5.                         // Mark static-static invalid since they are not going to affect simulation in any way.
    6.                         isInvalid |= (pair.BodyAIndex >= NumDynamicBodies && pair.BodyBIndex >= NumDynamicBodies);
    7.                         if (isInvalid)
    8.                         {
    9.                             pair = BodyIndexPair.Invalid;
    10.                         }
    This will ignore the Joint instead of asserting. Though, the PhysicsJoint component will still be referencing and invalid EntityID and should really be handled. On Cascade Delete does sound like a nice general non-physics specific fix.
     
    Yuriy_Sevastyanov likes this.