Search Unity

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

Question Prevent Object "squishing"

Discussion in 'Physics' started by Clicksurfer, Oct 24, 2020.

  1. Clicksurfer

    Clicksurfer

    Joined:
    Aug 17, 2014
    Posts:
    77
    Hi there :)

    I have an issue in my 2D game where objects will "squish" objects through walls.
    This happens when moving objects (using the Vector2.MoveTowards in script) move into them and there's a wall behind them.
    This is a result of those objects using "Discrete" collision detection instead of "Continuous".



    The issue is when swapping to "Continuous" mode, while the object no longer squishes, it begins teleporting:



    Ideally, I want the object to be pushed up to the wall, and then the moving object to give up and go the other direction. I was able to achieve a similar effect by applying an OnCollisionEnter2D on the moving object:



    However, this approach is not without faults, as now it won't be able to push the ball to the wall, and also it freaks out if the ball is above the moving object:



    Any idea what would be a solution that will allow me to reach the wanted behavior?

    Thanks in advance!
     
  2. Monique_Dumont

    Monique_Dumont

    Joined:
    Feb 18, 2020
    Posts:
    41
    You could check when the ball is moveable, and invoke an event when it's not. Your square is subscribed to the event and when it's invoked, your square knows to stop trying to push the ball. Then you just raycast to check for collision instead of CollisionEnter2D and you're set.
    It's not very elegant but I think it would work. Let me know if you need more details.
     
  3. Clicksurfer

    Clicksurfer

    Joined:
    Aug 17, 2014
    Posts:
    77
    Hi! Thanks for the help!

    I actually achieved the wanted effect without needing to raycast or make many significant changes - all I had to do was detect that the blocking object (in this case the circle) was in the direction of the movement.

    My logic was something like this:

    Code (CSharp):
    1.     private void OnCollisionEnter2D(Collision2D collision)
    2.     {
    3.         //Check if collision is in direction of movement
    4.         Vector2 movementVector = points[pointIndex].position - transform.position;
    5.         Vector2 hitVector = collision.GetContact(0).point - (Vector2)transform.position;
    6.         if (Vector2.Angle(movementVector, hitVector) <= maximumCollisionAngle)
    7.         {
    8.             // Do logic where we backtrack to previous point
    9.         }
    10.     }
    11.  
    12.     private void OnCollisionStay2D(Collision2D collision)
    13.     {
    14.         OnCollisionEnter2D(collision);
    15.     }