Search Unity

Specific Paddle Control for BrickBreaker

Discussion in '2D' started by DavidKlecker, Jan 24, 2020.

  1. DavidKlecker

    DavidKlecker

    Joined:
    Jan 3, 2020
    Posts:
    15
    I've been tackling a problem for about a week. Perhaps someone here can point me in the right direction. I want to adjust the bounce of the ball on the paddle so there is a way to control the angle of the bounce. What I want specifically is that when the ball comes from the left and hits the left side of the paddle it will go left, and when it comes from the right and hits the right side of the paddle the ball will go right. I have that part of algorithm working. What isn't working is based on where the ball hits I would like to adjust the angle.

    For example if after normalizing where the ball hits the paddle from -1 to 1. If the ball hits says -.80 from the right I want the ball to bounce with a greater angle than normal. If the ball hits say -.6 from the right then I want the ball to have a more shallow angle.

    Here is the algorithm I have thus far.

    Code (CSharp):
    1.            
    2. //Allows me to adjust the bounce and angle direction freely
    3.  GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Kinematic;
    4.             Vector2 w = GetComponent<Rigidbody2D>().velocity;
    5.  
    6. //Get the normalized location of where the ball hits the paddle between -1 and 1, 0 being the center.
    7.             float PaddleHitLocation = ReturnLocationOfPaddleHit(collision);
    8.  
    9. //Get a bounceAngle from this normalized value
    10.             float bounceAngle = PaddleHitLocation * 75;
    11.  
    12.  
    13.             w.x = w.x + (Mathf.Cos(bounceAngle));
    14.             w.y = w.y + (Mathf.Sin(bounceAngle));
    15.  
    16. //This allows the ball to go left when the ball comes from the left the ball hits on the left side of the paddle and vice versa for the right.            
    17.             if (w.x < 0 && PaddleHitLocation > 0)
    18.                 w.x *= -1;
    19.             else if (w.x > 0 && PaddleHitLocation < 0)
    20.                 w.x *= -1;
    21.  
    22.             GetComponent<Rigidbody2D>().velocity = w;
    23.             GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Dynamic;
    24.  
    Thanks for any help and assistance.
     
  2. DavidKlecker

    DavidKlecker

    Joined:
    Jan 3, 2020
    Posts:
    15
    Okay... I have made some headway. Vector2.Reflect is basically the method that will create the advanced ball bouncing on my paddle. I provided a picture to help. The first one is how the reflect method works normally. However based on where the ball hits the paddle I want to "distort" the red line in order to provide a deeper reflection for the ball, especially if it hits closer to the end.

    Here is the code I have now.

    Code (CSharp):
    1.             float PaddleHitLocation = ReturnLocationOfPaddleHit(collision);
    2.             PaddleHitLocation = PaddleHitLocation * 0.9f;
    3.  
    4.             var speed = LastFrameVelocity.magnitude;
    5.             Vector2 normalized = collision.contacts[0].normal;
    6.  
    7.             var direction = Vector2.Reflect(LastFrameVelocity.normalized, normalized);
    8.             Vector2 w = direction * Mathf.Max(speed, minSpeed);
    9.             GetComponent<Rigidbody2D>().velocity = direction * Mathf.Max(speed, minSpeed);
    10.  
    PaddleHitLocation is a normalized value of where the ball hits the paddle with -1 and 1 being the far edges and 0 being the middle. Normalized is just the normal proper reflection value represented by the first picture. this is the variable I need to "adjust" but I don't know how yet. I'm tweeking things here and there, but not able to get a proper response. Currently the above works especially when converting back to setting the ball velocity. The last two lines were for debug. I couldn't get the last line to give me any information so I created a new line to store that information into w.

    i suppose the idea is that I can change the direction however not sure where I would do that in the velocity method. Would this be setting the x and y values? Wouldn't this effect the magnitude and thus make the ball accelerate when I recalculate by new vector from direction * Mathf.Max(speed, minSpeed)?

    Thank you for any help you can provide.
     

    Attached Files:

  3. DavidKlecker

    DavidKlecker

    Joined:
    Jan 3, 2020
    Posts:
    15
    I'm thinking I'm beginning to see a potential solution. Hopefully someone can correct my mistake. I've some initial testing to no avail.

    The ball coming into the paddle is going to have a speed and direction. The speed is my magnitude and the direction is the normalization of the vector itself from the property normalized. Let's say that the magnitude of the ball is 13 and the normalization vector of my ball is [.4, .9]

    My normal reflection vector is just a perpendicular line from the paddle. This can have magnitude of 1 and a normalized value of [0, 1]. This represents a vector going straight up.

    The resulting reflection vector is calculated in this fashion, r=d−2(d⋅n)n where d is my initial direction vector (normalized) and n is my normalization vector and d dot n is the dot product. Using d = (.4, .9) and n as (0, 1) R will be (.4, -.9). I am able to do this math to confirm for myself for understanding purposes.

    Therefore the change should lie in the vector n which determines my reflection. Instead of (0, 1) I need to change it to something like (.2, .8). Whatever I change it to it needs to have the same magnitude of 1 so that when my ball doesn't increase or decrease speed when I convert it back. However it trying these values, the ball speed does in fact change. Perhaps I am forgetting or missing a key piece in altering a vector in a way that keeps the magnitude intact.
     
  4. Tom-Atom

    Tom-Atom

    Joined:
    Jun 29, 2014
    Posts:
    153
    1] some simple tutorials just revert y direction. It is equal to reflection from flat horizontal surface,
    2] most of the brickbreakers have flat paddle and reflection has nothing to do with physics - it simply checks how far is impact point from center of paddle and calculates new direction.
    3] long time ago we created Shards - the brickbreaker, where paddle is curved and all reflections are pure 2D physics (video:
    , app: https://play.google.com/store/apps/details?id=com.sbcgames.shardsl). We had to solve some isses - after a few reflections (from bricks, paddle, walls) ball could start to fly in pure horizontal or vertical way (not much fun to look at ball bouncing from left to right forever :)). We had to detect when movement is too vertical or too horizontal and adjust it.
     
    eses likes this.