Search Unity

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

Question One Way Platform registering collision from both sides

Discussion in 'Physics' started by Snowdrama, Nov 6, 2020.

  1. Snowdrama

    Snowdrama

    Joined:
    May 10, 2014
    Posts:
    28
    I am working on a breakout game and I want to have some one way platforms the ball can bounce off the top but pass through the bottom. I have a PolygonCollider2D and a PlatformEffector2D on an object, the rotational offset is 0 and the surface arc set to 180, default values. My ball when moving up towards the platform though, collides with the polygon collider from both sides.

    Some relevant code and screenshots.

    The collider:
    upload_2020-11-6_7-40-41.png
    The Ball:
    upload_2020-11-6_7-48-49.png

    In this image the ball is positioned underneath and starts the game going upwards.
    upload_2020-11-6_7-40-50.png
    However still collides with the platform
    upload_2020-11-6_7-45-39.png

    From The Ball Script:
    Code (CSharp):
    1.  
    2. private void OnCollisionEnter2D(Collision2D other)
    3. {
    4.         Debug.Log(other.gameObject.name, other.gameObject);
    5. }
    Code (CSharp):
    1.  
    2.     void FixedUpdate()
    3.     {
    4.         BallData.Position = BallData.Rigidbody.position;
    5.         MoveBall(BallData, Time.fixedDeltaTime);
    6.     }
    7.     private void MoveBall(BallData ballData, float deltaTime)
    8.     {
    9.         ballData.Rigidbody.velocity = ballData.Direction.normalized * ballData.Speed;
    10.     }
    To my knowledge a rigidbody with a velocity moving at the right angle towards a PlatformEffector2D shouldn't collide with it. So I'm not sure why it would do that.

    Thanks in advance for any help!

    Using Unity 2019.4.8f1
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,105
    When you say it collides with it, what exactly do you mean? Do you mean you see a collision response or that you see a callback? You'll still get a callback to tell you there's a contact but Collision2D.enabled indicates whether it is enabled or disabled. If disabled, there's still a contact but it produces no collision response.
     
    Last edited: Nov 6, 2020
  3. Snowdrama

    Snowdrama

    Joined:
    May 10, 2014
    Posts:
    28
    Ahh that makes sense then, my expectation here was that when the object passes through the platform, the OnCollisionEnter2D would not be called since the colliders are not "colliding" since it passes right through. For me I don't consider that a collision as the platform collider isn't stopping the ball from going through.

    In my case it looked like collision in context because of the way I handle the reflection off of surfaces for the ball.

    When I encounter a collision by receiving the OnCollisionEnter2D callback, I do a reflection over the collision normal to bounce the ball direction away from the wall like below
    Code (CSharp):
    1. private void OnCollisionEnter2D(Collision2D other)
    2. {
    3.     Debug.Log(other.gameObject.name, other.gameObject);
    4.     //when colliding with a surface, set the new direction based on the reflection of the direction over the normal
    5.     BallData.Direction = Vector2.Reflect(BallData.Direction.normalized, p.normal).normalized;
    6. }
    7.  
    Is there a way to tell if the ball is passing through the platform then? How do I differentiate it from a normal surface collision?

    Edit: Missed that it disables the collider, so I can check the collider.enabled.

    Thanks!

    Edit: Dang this doesn't seem to work either the collider is coming back as enabled

    Code (CSharp):
    1. private void OnCollisionEnter2D(Collision2D other)
    2. {
    3.     Debug.Log(other.gameObject.name + ": " + other.collider.enabled, other.gameObject);
    4.  
    5.     //one way platform effector colliders are disabled when going through them
    6.     if(other.collider.enabled != false)
    7.     {
    8.         //Only reflect if we're colliding with something that's enabled == true
    9.         //when colliding with a surface, set the new direction based on the reflection of the direction over the normal
    10.         BallData.Direction = Vector2.Reflect(BallData.Direction.normalized, other.contacts[0].normal).normalized;
    11.     }
    12. }
    13.  
    Possible final edit?: Ahh I'm dumb it's not the collider.enabled it's collision.enabled.

    Actual final edit for anyone who comes here later: The example below is the final version that does in fact work
    Code (CSharp):
    1. private void OnCollisionEnter2D(Collision2D other)
    2. {
    3.     Debug.Log(other.gameObject.name + ": " + other.collider.enabled, other.gameObject);
    4.  
    5.     //one way platform effector colliders are disabled when going through them
    6.     if(other.enabled != false)
    7.     {
    8.         //Only reflect if we're colliding with something that's enabled == true
    9.         //when colliding with a surface, set the new direction based on the reflection of the direction over the normal
    10.         BallData.Direction = Vector2.Reflect(BallData.Direction.normalized, other.contacts[0].normal).normalized;
    11.     }
    12. }
    13.  
     
    Last edited: Nov 6, 2020
    MelvMay likes this.
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,105
    Glad you got it working! :)
     
    Snowdrama likes this.