I have a Rigidbody2D with a CircleCollider2D, on which I display a sprite of a circle. This Rigidbody can be "shot" in my game.
I also have 4 rectangular BoxCollider2Ds on the edges of the game screen.
When I shoot the circle, it rebounds fine from the rectangular colliders, except for cases when the impact velocity normal to the rectangular collider's surface is very small. In that case, the rebound velocity in that direction is somehow zero.
Here is the circle's RigidBody2D and CircleCollider2D setup:
Here is the BoxCollider2D of the rectangular collider:
The material "New Physics Material 2D" attached to the ball and the BoxColliders has Friction set to 0 and bounciness set to 1:
Here are two gifs, the first one demonstrating how it works (correctly) in most cases, and the second one demonstrating what happens on a low velocity impact. The "choppiness" of these gifs is due their "giffy" nature. In my game, the movement is smooth.
I'm wondering why, on the low-velocity impacts, the ball doesn't rebound in the same way as on the high-velocity impacts (i.e, by the outbound angle = inbound angle rule)?
----------------------------
Edit:
----------------------------
I stepped into the circle's void OnCollisionEnter2D(Collision2D collision)
method, and, sure enough, on the very slow collisions, the collision.otherRigidbody.velocity
had a zero-component for the slow velocity of the incoming collision (so depending on whether the impact's x- or y-velocity was slow, the respective component of the resulting velocity was, for whatever reason, set to 0).
Oddly enough (at least for me - I am still not completely familiar with all of Unity's in's and out's), the collision.relativeVelocity
had been updated to hold the correct resulting velocity of the impact. Thus, by adding following code to the OnCollisionEnter2D
method, I am able to handle the collision correctly, even on low-impact collisions:
if (collision.otherRigidbody.velocity.x == 0)
{
collision.otherRigidbody.velocity = new Vector2(collision.relativeVelocity.x, collision.otherRigidbody.velocity.y);
}
if (collision.otherRigidbody.velocity.y == 0)
{
collision.otherRigidbody.velocity = new Vector2(collision.otherRigidbody.velocity.x, collision.relativeVelocity.y);
}
While this seems to solve the issue I am experiencing, it doesn't seem to me that I should need to be doing this...