Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

Experimental contacts modification API

Discussion in 'Physics Previews' started by yant, Jul 3, 2020.

  1. Ruchir


    May 26, 2015
    They act as a multiplier, not an absolute value, so you can update it to be say 0.1 to make the object 10 times heavier and so on.
    Z0mbie1111 likes this.
  2. Z0mbie1111


    Sep 13, 2021
    How do I know what mesh the GetFaceIndex() is for? In your example you only have one collider that has hasModifiableContacts set to true so its pretty easy to figure out. But in real usecases you will obviously have more than 1 collider.

    A similar question about the GetNormal() function. How do I know what collider that normal is for? I have tested using Debug.drawLine to visualize all normals and it looks like GetNormal() includes normals for collider A and B.

    It looks like there are atleast two pairs containing the same collider because the code below prints "Yes" ~half as many times as items in the pairs array. So my theory is that GetNormal and GetFaceIndex is for collider A but I cant find any documentation about it and I really dont want to use it in production if its behaviour is not certain

       HashSet<int> usedOthers = new();

    for (int i = 0; i < pairs.Length; i++)
    if (usedOthers.Add(pairs[i].otherColliderInstanceID) == false)
    Debug.Log("Yes " + pairs.Length);
  3. codebiscuits


    Jun 16, 2020
    You use the collider instance IDs to work out which collider is doing what stuff.
    E.g., in my code I have various ground colliders, and wheel colliders and body colliders and stuff, so I
    Code (CSharp):
    2. //This all lives in a singleton for me, maybe it doesn't need to?
    4. readonly HashSet<int> GroundColliderInstanceIDs = new (); //These are set from various places in my game
    5. readonly HashSet<int> SoftColliderInstanceIDs = new (); //These are set from various places in my game
    6. private void ModificationEvent( PhysicsScene scene, NativeArray<ModifiableContactPair> pairs ) {
    7.     foreach ( var pair in pairs ) {
    9.         //"One cannot rely on the order of Colliders in a pair." -
    10.         var GroundID = GroundColliderInstanceIDs.Contains( pair.colliderInstanceID ) ? pair.colliderInstanceID : GroundColliderInstanceIDs.Contains( pair.otherColliderInstanceID ) ? pair.otherColliderInstanceID : 0; //"is always unique, and never has the value 0" -
    11.         if ( GroundID != 0 ) {
    13.             var nonGroundID = GroundID != pair.colliderInstanceID ? pair.colliderInstanceID : pair.otherColliderInstanceID;
    14.             var softID = SoftColliderInstanceIDs.Contains( nonGroundID ) ? nonGroundID : 0;
    15.             if ( softID != 0 )
    16.                 pair.SetSeparation( i, pair.GetSeparation( i ) + maximumGroundSurfacePenetration ); //Or whatever
    17.     }
    18. }
    I've been using stuff like this & looking at normals and face index and stuff for a year+, it seems to work really nicely (I'm on 2021.3.33f1 LTS, 33 fixed some issues; 2022 LTS seems to have some non-contactmod-related phsyics issues I'm keeping an eye on).
    Last edited: Feb 18, 2024
  4. hhyperstar


    May 27, 2013
    Has anyone had any luck squeezing extra performance out of these callbacks? I love this API but ContactManagerDiscreteUpdate can take up a LOT of cpu time, only a small fraction of which is actually spent of executing my callback code.

    Attached Files:

  5. a436t4ataf


    May 19, 2013
    I use this heavily (to workaround multiple annoying issues/bugs in Unity physics and how it integrates with rest of Unity), but just hit a snag: this seems to be ignored by the Unity implementation of the Joint* classes?

    i.e. when I have:

    1. a floor collider
    1. two object colliders, on separate rigidbodies
    2. each collider has been marked hasModifiableContacts = true

    I get:
    * Physics.ContactModifyEvent = gets called with each collider + floor
    * joint.currentForce = (something huge) for each joint
    * Physics.ContactModifyEvent -- does not get called for the two objects colliding

    What's going on - do joints completely ignore the contacts modification?
  6. a436t4ataf


    May 19, 2013
    Hmm. The more I dig, the more something basic seems to be wrong with the API.

    1. If you have a compound Collider, eg with 15 child colliders on one RB, and its resting on a cube ... then this API invokes 15 times, but incorrectly sends the instanceID of only 'the first child collider' all 15 times, and the instance ID of the cube.

    i.e. somehow ... this is now only ever sending the same pair of instance IDs every frame. It did not used to do this! Same project, same version of Unity ... I used to get NxM invocations, every invoation with a unique pair of instanceIDs.

    Is this a known bug? -- that the ModificationEvent gets 'jammed' on a single pair of instanceIDs, and never works again? I've restarted Unity multiple times, to no success: same problem.
  7. HonduneGames


    May 14, 2015
    Would you mind providing the code for your GetCumulativeRelativeVelocity function? Im trying to do directional friction as well, also by solving for relative velocity and calculating point velocity for each contact in the pairs. I was originally trying to modify the friction value, but after finding your post have been trying to use the target velocity method. The results im getting are super erratic though and I cant figure out whats going on.