I made a variation

I wanted to improve the ball script for making more arkanoid style: depending on the contact point when ball hits the paddle, change it’s direction as the next image:

In the ball script first i made a float variable called speed magniture, from Ben video the starting magnitude was abount 10 (sqrt(10^2 + 2^2)), so I kept it.

private float speedMagnitude = 10f;

Then, when mouse is pressed I’ve randomized the x between -1 and 1, normalized the vector( so it’s magnitude it’s 1) and multiplied by speedMagnitude:

rb2d.velocity = new Vector2(Random.Range(-1f, 1f),1).normalized * speedMagnitude;
Debug.Log(rb2d.velocity.magnitude);

I’ve assigned a “Paddle” tag to the paddle, and used in OnCollisionEnter2D as following:

if(collision.gameObject.CompareTag(“Paddle”))
{
//distance from paddle’s center (negative if less than 0, positive if greater than 0, of course 0 if 0)
float ballDistance = transform.position.x - collision.transform.position.x;
//percentage between the ball hitting poi and the half leght of the paddle (has values between -1 and 1)
float ratioDistance = (ballDistance / (paddleLenght / 2));
//new velocity depending on the hit point on the paddle
rb2d.velocity = new Vector2(ratioDistance, 1).normalized * speedMagnitude;
print(rb2d.velocity.magnitude);
}

the velocity tweak when hitting walls can be placed on the else statement if you want to vary the direction.

Notes:

  • If we want to make the game more engaging with increasing the velocity (ex. when hitting a n number of brick, when collide, a malus picku, ecc…), the only variable is speedMagnitude.
  • a few link of the math (vector) operation used: scalar multiplication, normalized vector

Try it if you want and send me feedback, tell me if I made any mistake! :slight_smile:

4 Likes

Nice solution there.

I’d just change the starting value of the magnitude, by reading it from ball.velocity.magnitude when the ball it’s fired. This would be useful if, for example, in subsequent levels you want a different starting speed magnitude.

However, I can see a problem with this code: you may end up transferring almost all the velocity to the X component when the ball hits near the end of the paddle, and the new velocity vector is independent completely from the one before the collision, it’d be nice to have a mix of them (part depending on previous vector, part depending on hitting point).

2 Likes

Hello Galandil and thanks for reply :slight_smile:
The y component of the vector when hitting is never 0, infact is fixed to 1. the boundary conditions are -1 < x < 1, the solutions of this is two vectors v1(-1,1) and v2(1,1), bisectors of the second and the first quadrant, since it’s normalized the real boundaries are v1( -1/(sqrt2) , 1/(sqrt2)) and v2( 1/(sqrt2) , 1/(sqrt2)) :wink:
but i’ll try to code you’re solution too. the mix thing seem fun :smiley:

1 Like

Oh, yeah, right, -0.707 <= X <= 0.707 and 0.707 <= Y <= 1 (with Y=1 when X=0).

It’s a good way to get rid of the lock loop of the ball, the drawback thou is that is a little bit simpler for the player (higher X component usually is harder to follow and correct).

To get a higher X component we can double the ratioDistance, so that we get a max(X) = 0.895 and a min(Y) = 0.447.

2 Likes

Yes :wink: you got it! :slight_smile: basically multiply by two the original ratio( who it’s divided by two) it’s the same if we divide it by 4. so the boundaries now are ±1.5 (assuming a paddle of length 3) instead of the preavious ± 1. I’t like “mapping” the paddle :slight_smile:

1 Like

just a little fix: sometimes if the vertical position of the ball is less than the paddle, flickers and doesn’t work very well so inside the if “collisiontag ispaddle?”

float ballDistanceY = transform.position.y - collision.transform.position.y;
if (ballDistancey < 0)
{
return;
}
else
{ //previous code for x}

Nice work :slight_smile:
Thanks for sharing.

Privacy & Terms