Search Unity

Physics - how do I set the following:

Discussion in '2D' started by Xelnath, Jan 2, 2017.

  1. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    1) Define the movement for a rigid body's velocity
    2) If two rigidbody's colliders collide, the rigid bodies stop and do not pass through each other
    3) When scenario #2 occurs involving a non-moving, but not static rigidbody, NO PUSHING OCCURS.

    Basically, I want to control my own movement and use Unity's physics to *prevent* movement, but NEVER to trigger new movement.

    I've tried setting the velocity on the objects every frame... but objects still end up pushing each other around.
     
  2. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    A simple way to do this:
    Code (CSharp):
    1.  
    2. void OnCollisionEnter2D(Collision2D other) {
    3.   other.GetComponent<Rigidbody2D>().isKinematic = true;
    4.   GetComponent<Rigidbody2D>().isKinematic = true;
    5.   other.GetComponent<Rigidbody2D>().isKinematic = false;
    6.   GetComponent<Rigidbody2D>().isKinematic = false;
    7. }
    8.  
    Maybe not the most efficient way to do it, but it should work...
     
    Last edited: Jan 3, 2017
  3. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    I don't understand how the above would work. Can you explain? In the end, don't both continue reacting as normal?
     
  4. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Darn, turns out it doesn't work with the 2D physics. I did something similar with the 3D physics way back, and just converted that. Unfortunately I didn't test it until now, which was stupid.

    What it is supposed to do is turn the colliding objects into kinematic objects (static might have been better), which should turn off movement and rotation. Then they are turned back to non-kinematic and they should be free to react to forces again. But it doesn't seem to work properly with 2D physics. It kinda works, but after some research I see why it doesn't work completely.

    So, I'm sorry for that suggestion :-(
     
  5. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    So, I did some tests. I had a number of boxes moving about and tried to find a way to minimize reactions on collision.

    I got the best result when I used a Rigibody2D set to Kinematic, Simulated on and Use Full Kinematic Contacts to on. Then I placed a tiny script on the objects:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class test : MonoBehaviour
    4. {
    5.     void OnCollisionEnter2D()
    6.     {      
    7.         GetComponent<Rigidbody2D>().velocity = Vector2.zero;
    8.     }
    9. }
    10.  
    WIth low speeds this works perfectly. With higher speeds there might be some slight overlap, since they don't push apart. However, this could be compensated for by making their colliders slightly larger.
     
  6. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    When I tried this with Kinematic turned on, the objects didn't collide with each other. Did this work for you?
     
  7. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Yes, but you have to turn on both Simulated and Use Full Kinematic Contacts.
     
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    If you were to use continuous collision detection (more expensive) then the colliders in question won't be overlapping when you zero the velocties.

    Note that the 'Simulated' should already be on by default otherwise nothing would happen anyway. :)
     
  9. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    If you set the Rigidbody2D bodyType to Kinematic and use kinematic contacts then you will get callbacks when its colliders contact any other bodyType but with them being kinematic the physics system will not apply forces to them. Note that you are still free to set the linear/angular velocity on these bodies as you would a Dynamic bodyType.

    The above set-up is new and it's effectively the equivalent of using dynamic triggers but with the advantage you get full collision callbacks including contact points.
     
  10. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Okay. Nervous, but will try this out.
     
    MelvMay likes this.
  11. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Weird, I did try that and I did get slight overlaps any way. (I guess I shouldn't have delete my test scene, now I have to redo it to try again :) )
     
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    That is odd indeed. Box2D performs a sweep during the update from the old to new position/rotation and moves the body to the correct position rather than with discrete where it leaves it in the new position and solves the overlap using impulse forces.
     
  13. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Here is a screenshoot of my new test scene:


    I did use a pretty fast speed, just to make sure that the overlaps was more visible. However, I do get overlaps at smaller speeds as well. On of the scripts set a start velocity of the Rigidbody2D, nothing more and the other script does set the velocity to zero at OnCollisionEnter2D.

    I found it a bit weird that Continuous Collisions didn't get nice, precise intersections.
     
  14. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    It'll obviously only work if the Rigidbody2D is moving using its velocity (or using Rigidbody2D.MovePosition).

    I'll do a check of my own soon to ensure that the time-of-impact stuff is indeed working for kinematic bodies.
     
  15. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Yes, I did only set an initial velocity. All the brown object started a bit away and got a velocity towards the gray object (which was stationary). Once I did the Rigidbody2D.velocity change I didn't touch it again until the collision. So there shouldn't be anything else but the physics at work.
     
    MelvMay likes this.
  16. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    I've just duplicated the issue. I'll dig further to see why time-of-impact isn't working.
     
    PGJ likes this.
  17. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    Okay so I just found an issue with the time-of-impact code for kinematic bodies using full-contact processing. I'll work on a fix for that later. Box2D sets mass and inertia to zero for static/kinematic bodies which is why in a lot of its code, nothing affects it as calculations end up as zero. I've had to bypass some of this, seems like I missed something in the TOI code.
     
    Xelnath and PGJ like this.
  18. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    oh thank god, do you think this bug will get fixed by June?
     
    Last edited: Jan 4, 2017
  19. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Okay, I tried this out.

    What happened was the callback was correctly called when I intersected another collider object... but it didn't stop the objects from moving through each other if the velocity is updating during the FixedUpdate() function.

    Look, what I want is simple:
    If any objects try to push through each other, they stop. They don't move each other. They just stop.

    Why can't this be easy? I am angry and frustrated.

    I want to set my desired velocity in one place. Then be told if I hit something - and if I'm hitting something NOT move through it. This can't be rocket science.

    Instead, it's telling me that I hit something, but continues to push through it. That's because the OnCollisionEnter2D function is only fired once when the first touch happens, not every time.

    Now, to get what I want, I need to be doing constant movement checks... keeping track of all of the contact points... F*** THIS.

    I just want my objects to not move through each other and not push each other around.
     
  20. 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();  // This is off elsewhere in the game scripts. Just trust me, it provides a non zero vector3.
    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.  
    I am getting 6-12 contact point 2d objects.

    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.
     
  21. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    MyRigidBody's velocity is NOT changed anywhere else in the game scripts. It's only set here... and I am setting it to Vector3.zero if the contacts is greater than 0.

    THIS THING SHOULD BE IMMOBILE, not pushing through like jelly through a cheap plastic collander.
     
  22. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Don't get me wrong, running through walls inconsistently is fun too. -_-

    "50% of the time it works everytime"
    Screen Shot 2017-01-20 at 4.03.38 AM.png
     
  23. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Example of what's happening

    Colliders_BUG_PushThrough.gif
     
  24. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    This is what OnCollisionStay2D is for.

    Also, I have to repeat, if you're using the experimental releases then please post this in the experimental forums or at least state that you're using such a release. There's a huge expectation that you're using a release that's gone through a lot of QA when in-fact you're not.
     
    Last edited: Jan 20, 2017
  25. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    No effect. I still run through the other object's collider.
     
  26. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    What doesn't help, adding *something* to OnCollisionStay2D? Really, this doesn't help. You need to produce a simple reproduction of what you're trying to do else it's almost impossible for me to help you. If you can do that then I might be able to reduce your anger and frustration. ;)

    Please do not use experimental only features when doing a reproduction unless it's about those features specifically.
     
  27. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    @MelvMay

    I have calmed down now.

    I posted this thread in non-experimental land because I wanted to reach an audience for what seemed like a basic need:

    "No push back when two objects collide."

    When that didn't work, I went back to Experimental land to try to determine if two objects were touching using your new feature - and used that to try to make the velocity zero.

    I realize this has to be as confusing for you to follow as it is for me to try to figure out. It feels basic. It's instead a lot of hoops and I don't get why things stop working when I run into them.
     
    Last edited: Jan 20, 2017
  28. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    :)

    No worries on the rest though; I can help you but I need some clarity without all the back/forth.
     
  29. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
  30. piggybank1974

    piggybank1974

    Joined:
    Dec 15, 2015
    Posts:
    621
    I had the same problem, I'll try to dig out the answer for you.
     
  31. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    I've already answered the problem on the thread referred to above. :)
     
  32. piggybank1974

    piggybank1974

    Joined:
    Dec 15, 2015
    Posts:
    621
    but he does say it's not working, or I'm I reading it incorrectly?
     
  33. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    Reading it incorrectly but then again there is a lot to read.

    All the detail is there but the problem was that it's a hierarchical rag-doll Kinematic set-up with colliders requiring Kinematic bodies where they are animated and not just a single root body. The script I provided completely solves the problem in addition to adding a single Kinematic Rigidbody.

    I won't go into it further, it's all in there and more.
     
  34. piggybank1974

    piggybank1974

    Joined:
    Dec 15, 2015
    Posts:
    621
    I see I didn't see the post I thought Xelnath had setup a new thread for it, so I did not select it, it was only when you mentioned the script I selected the new created thread :)
     
    MelvMay likes this.
  35. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,492
    Get ready for some reading then. Oh my! :)