Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Feature Request Full Kinematic Contacts solves contact normal impulse / tangent impulse

Discussion in '2D Experimental Preview' started by Pyromuffin, Sep 18, 2016.

  1. Pyromuffin

    Pyromuffin

    Joined:
    Aug 5, 2012
    Posts:
    85
    Hi! I'm working on a platformer where I'm finding that it would be super great to be able to have a kinematic body behave like a normal dynamic body except in a very few corner cases.

    If we had contact.normalImpulse / tangent impulse we could apply this force in a script to get the body to behave like a dynamic rigidbody, but have the option of modifying this or ignoring this based on certain conditions. For instance, right now when using a dynamic rigidbody i get jittering when moving from ground on to slopes and if I could control the direction of the normal in the collision response (or just eliminate the vertical component), I'd be able to get the behavior i'd like.

    as it is right now, when full kinematic contacts is enabled, contact.normalImpulse is always zero which doesn't do me any good. I'm having to do all kinds of hacks now like casting a capsule every frame to see if I'm about to run into a slope, or even using a kinematic body with full contacts, and then trying to do my own collision response solving in C# and of course it's not going to be as nice as the one that box2D already has.
     
    MelvMay likes this.
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    Well spotted. I believe you'll get impulse info when the kinematic body is touching a dynamic body, maybe when the kinematic body iself has an actual velocity but I'd have to check that. I presume this is happening when the kinematic body is touching another kinematic/static body, the most common case probably being in contact with a static body i.e. the ground.

    I agree though, this is not only nice to have but essential. The next step for me alongside full-kinematic-contacts is to look at the ability to ask Unity to solve (provide you with the new position/velocity) the contact(s) for you upon your request which of course will require some of this information. This would work iteratively and be as stable as the dynamic body is.

    Again, thanks for the heads-up on this. Be sure that I'll take a look at this ASAP!
     
    Last edited: Oct 13, 2016
  3. Pyromuffin

    Pyromuffin

    Joined:
    Aug 5, 2012
    Posts:
    85
    awesome! i spoke with you on slack a few weeks ago (@kelly) about something similar, but i am glad it's getting some attention.

    thanks again!
     
  4. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    I'd love this contacts upon request feature. Would make life a lot easier for doing hitboxes / area enemy detection without needing to be on all of the time.
     
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    If you mean the ability to retrieve contacts, it's in the 2D previews and is on its way to 5.6 as we speak.
     
    Xelnath likes this.
  6. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    I'm not sure. What I want is to define a ColliderPolygon2D IsTrigger and be able to get a list of everything inside or touching it on demand.
     
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    That's in the experimental preview since first release. You can perform a .GetContacts call on a specific collider or rigidbody. You can also see contacts live from the collider/rigidbody 'info' rollout in the inspector.

    Release #2 added a ContactFilter2D that allows you to filter .GetContacts by trigger/collision-normal-angle, layer-mask & depth. In Release #3 this filtering has also been added to .IsTouching as well as to every other physics query i.e. .Cast, .LineCast, .RayCast, .OverlapXXX etc. I tweeted about that here (should give you some idea about it): https://twitter.com/melvmay/status/781033061744054273
     
  8. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Thank you I had no Idea :)
     
    MelvMay likes this.
  9. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Hey @MelvMay, I started looking into this: (using Preview 2)

    Here's a BoxCollider2D that's overlapping with terrain, but no contacts are in the list:

    Screen Shot 2016-11-30 at 3.54.40 AM.png

    You will note the box clearly is overlapping the ground beneath it - and I tried cycling the layers too.
     
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    There were actually a bunch of problems in preview 2 but preview 3 is nealy ready however, note that the inspector shows actually collision contacts and not trigger contacts because it's showing ContactPoint2D detail; triggers do not have contact points. If you require that then do not use a trigger and use a Kinematic body instead with full kinematic contacts checked. That way, the kinematic body does not react to collisions but you get full contact points.

    Preview 3 massively improves the use of ContactFilter2D; it's effectively used in all 2D physics queries. The new contacts API as well as the Composite collider feature has gone into 5.6 alpha which will soon be in its beta phase.
     
  11. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    In addition: If you perform a GetContacts (the one with the Collider2D array arg) on the Rigidbody2D or on the trigger collider itself you will get the collider(s) of the ground returns though.
     
  12. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Okay. So to be sure I'm understanding correctly:

    If I just need a 'hit box' - something that tells me every other Collider2D which is contained Within or Intersecting with a given Is Trigger Collider2D (We'll call it X), calling X.GetContacts() will return the Collider2D of the ground rectangle. (or Tilemap collider in this case)
     
  13. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    Yes, just look at the documentation for the overloads of GetContacts; the one that returns a list of colliders rather than conact points.
     
  14. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    @MelvMay here's an abbreviated version of what I'm doing:

    Kinematic, Use Full Kinematic Contacts, Simulated, etc. Just like you mentioned in the 2d build thread

    Code (csharp):
    1.  
    2. ... class... MonoBehaviour etc
    3. {
    4.    
    5.     public virtual void OnCollisionEnter2D(Collision2D coll)
    6.     {
    7.         MyRigidBody.velocity = Vector2.zero;
    8.     }
    9.  
    10.     private Vector3 _lastVelocity;
    11.  
    12.     void FixedUpdate()
    13.     {
    14.           // Apply the final velocity
    15.         _lastVelocity = GetCurrentVelocity();
    16.         MyRigidBody.velocity = _lastVelocity;
    17.  
    18.         // I actually want to freeze movement if the body's velocity is almost zero...
    19.         if ( _lastVelocity.magnitude <= 0.05f )
    20.             MyRigidBody.constraints = RigidbodyConstraints2D.FreezeAll;
    21.         else
    22.             MyRigidBody.constraints = RigidbodyConstraints2D.FreezeRotation;
    23.  
    24.         int contactCount = MyRigidBody.GetContacts(contacts);
    25.         if ( contactCount > 0 )
    26.         {
    27.             Debug.LogFormat("Contact count: {0}", contactCount);
    28.             MyRigidBody.velocity = Vector3.zero;
    29.         }
    30. }
    31.  
    However, instead of the objects stopping (see https://forum.unity3d.com/threads/physics-how-do-i-set-the-following.449027/) - the two colliders slowly push through each other like molasses.

    I. Just. Want. Hard. Stops.

    Why is this so complex to achieve.
     
  15. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    (BTW, I realize this thread is being conflated with the other one - and this GetContacts() function solves the issue of a hitbox described above. Thanks for that. I am frustrated)
     
  16. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    For starters, I have to say that Experimental 2 isn't for production so maybe your problems relates to this. If you want to work with the 'GetContacts' then I'd recommend at least trying 5.6-beta as it landed there a while ago. Also, Experimental 3 has been released with many fixes and updates. Bugs fixed in 5.5 and 5.6 are not automagically backported into experimental releases. It's just not supported as a production release. We're hoping that the next experimental released will be based upon 5.6.

    Anyway, moving forward; I'm not sure what the constant changing of constraints is all about and I certainly wouldn't recommend it. Changing ANY physics property has consequences, it's not just a data change. Changing constraints means constraint joints are added/removed each fixed update in your script. Box2D doesn't support constraints like this so they're implemented as internal joints. Freeze rotation is fine as that is supported in Box2D however Freeze position is done with joint(s).

    I don't follow the logic above really and don't see how it stops overlaps or colliders sinking into each other. If you have a contact you zero the velocity. What if it's overlapped?

    As to colliders overlapping slowly; it's impossible to figure that out from just looking at the code above. It just sounds like you're trying to perform contact processing with kinematic bodies to produce what Box2D does which won't work unless you have an overlap solver; don't see that above.

    Note for overlap solving; that's coming as I tweet here:
    https://twitter.com/melvmay/status/819902015123890176
    https://twitter.com/melvmay/status/819909676586467328

    I can try to debug the issue in the latest experimental 3 release for 5.6-beta (unless you're using other experimental features like TileMaps of course).
     
  17. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    I upgraded to experimental release 3 the day it came out so that should be fine.

    If you want to try out what I have, I can add you to the project permission on GitHub or mail you a ZIP. Do you have a preference, @MelvMay?
     
  18. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
  19. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    I removed the freeze position constraint - it was just me struggling to get objects to stop pushing each other away.
     
  20. RockyWallbanger

    RockyWallbanger

    Joined:
    Mar 16, 2014
    Posts:
    85
    @MelvMay
    Can we see a legible screen cap of the documentation in that tweet? This sounds like exactly what I need and could eliminate quite a bit of my less elegant work-arounds. Could you clarify, will I be able to ask if two triggers are touching but not overlapping, i.e. sharing an edge?
     
  21. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Collider2D[] colliders = new Collider2D[20];
    int CollidersTouchingCount = GetComponent<RigidBody2D>().GetContacts(colliders);
     
  22. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    I would prefer a simplified repo rather than a full copy of a game as debugging it can be a huge time sink and I'm slammed right now. Can you produce this with a simple set-up i.e. a few colliders and your movement/collision testing; this'll allow me to quickly narrow down what's going wrong.

    Internally, 2D doesn't care about whether shapes are triggers or not; only when it comes to contact processing. The new API allows you to ask questions about spatial positioning of colliders i.e. separation or overlap irrelevant of whether they're set as triggers or even if they are set to contact each other or not (layer mask etc).

    It's better if you download the images after you click on them. They're linked here but because they're large, you'll need to zoom in:

    Collider Distance
    Collider Overlap
     
  23. RockyWallbanger

    RockyWallbanger

    Joined:
    Mar 16, 2014
    Posts:
    85
    A million thank yous. ColliderDistance2D is EXACTLY what I need. What's the first targeted build for these features? Preview 4?
     
    MelvMay likes this.
  24. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    I am trying to slip this sideways into 5.6-beta being as it's completely isolated and is just another query (well 3D physics guys slipped in a Penetration query so why not this?) but failing that it'll be in the next experimental preview 4.

    Right now I'm writing a bunch of tests to support it before I can push to 5.6-beta.
     
  25. RockyWallbanger

    RockyWallbanger

    Joined:
    Mar 16, 2014
    Posts:
    85
    That would be absolutely amazing. Keep up the great work.
     
  26. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Okay. I created the minimal demo.

    Where should I send it to?
     
  27. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    Do you have a drop-box account or anything you can host it so I can download it?

    BTW: This is a thread hijack, it would be best to start a separate conversation.
     
  28. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Last edited: Jan 20, 2017
  29. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    @MelvMay

    Back on topic - Rigidbody2d.OverlapCollider - this isn't ready or in the demos yet, correct?
     
  30. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
    Both the overlap and distance queries alongside a bunch of doco improvements and a rewrite/optimization for all the overlap queries landed in our trunk (5.7) last night and it's currently (as of early this morning) in the review/queue for 5.6.0b7.
     
  31. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,459
  32. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402