I'm trying to create a simple Breakout-style game. In my game, the ball strikes a paddle that moves with the player's mouse. Depending on the position of the strike, the ball changes its direction. This allows the player to aim the ball.
The problem I'm having is that each time I set the position, the ball loses velocity. I've tweaked every Physics2D setting I could find, but I'm not seeing any changes. Here's what my Ball
class looks like:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ball : MonoBehaviour {
public float initialVelocity;
public float collisionAngleRange;
public Paddle paddle;
private Rigidbody2D body;
public void Start() {
body = GetComponent<Rigidbody2D>();
body.velocity = VectorUtilities.AngleToVector2(135) * initialVelocity;
}
// When colliding with the paddle, use the position of the strike to adjust the ball's position.
public void OnCollisionEnter2D(Collision2D collision) {
// Ignore the object if it's not the paddle.
if (!collision.gameObject.CompareTag("Paddle")) { return; }
// Get the collision coordinates
Bounds bounds = collision.gameObject.GetComponent<BoxCollider2D>().bounds;
float left = bounds.min.x;
float right = bounds.max.x;
Vector2 contact = collision.contacts[0].point;
// Interpolate the contact point and determine the angle.
float interpolation = (contact.x - left) / (right - left);
float angle = 90 - collisionAngleRange / 2 + collisionAngleRange * (1 - interpolation);
// Change the direction of the ball without affecting its speed.
body.velocity = VectorUtilities.AngleToVector2(angle) * body.velocity.magnitude;
// Log what's happening with the velocity
Debug.Log(body.velocity.magnitude);
}
}
The VectorUtilities
class looks like this:
using UnityEngine;
// A set of utility methods and extensions for Vector2 and Vector3.
public static class VectorUtilities {
public static Vector2 AngleToVector2(float degrees) {
return new Vector2(Mathf.Cos(degrees * Mathf.Deg2Rad), Mathf.Sin(degrees * Mathf.Deg2Rad));
}
}
Here are my Ball
game object's Rigidbody2D
and CircleCollider2D
settings:
The paddle's settings:
The material settings:
Physics2D settings:
I recognize I could solve this problem by multiplying the ball's normal vector by my desired speed, but it's more important to me to understand why this is happening and to fix the underlying problem. Why does the ball lose speed on every collision, and how can I prevent that from happening?
3.535534
,2.792838
,0.1950009
,0.1201167
and0.002097883
. I'm happy to throw the source code of what I have up on GitHub if you think it would help to poke around in it. \$\endgroup\$Paddle
, but it didn't have any effect. One other odd thing: if I comment out the code in theOnCollisionEnter2D
method, the ball still loses speed. However, the speed remains constant when it strikes the walls. \$\endgroup\$