1
\$\begingroup\$

I've been following this Pong tutorial, which is great: https://noobtuts.com/unity/2d-pong-game. The C#, unity components etc I understand. But what I am having trouble with is understanding the logic of how it reverses the direction of the ball depending on where it hits.

I know that what it is doing is condensing a new Y value to -1, 0, 1, via the hitFactor function, which returns that value and then sets that to the new Y (so going up or down) based on the relative ball position to the paddle, divided by the height/size of the paddle. But that's the bit I don't really truly understand, how does that work and why? I have been using Debug.log to send all the different parts of it to try and understand, as well as visually looking in Unity and trying to figure it out from there via the inspector, but I'm just having a mental block. To me I can vaguely see how this code is finding a relative position and then dividing by the height of the paddle to somehow condense it to this range but I'm really just stuck on it in my head.(the hitfactor function itself is basically where I am stuck)

Here's the function:

float hitFactor(Vector2 ballPos, Vector2 racketPos,
            float racketHeight) {
// ascii art:
// ||  1 <- at the top of the racket
// ||
// ||  0 <- at the middle of the racket
// ||
// || -1 <- at the bottom of the racket
return (ballPos.y - racketPos.y) / racketHeight;
}

And in context with the collision:

if (col.gameObject.name == "RacketLeft") {
    // Calculate hit Factor
    float y = hitFactor(transform.position,
                        col.transform.position,
                        col.collider.bounds.size.y);

    // Calculate direction, make length=1 via .normalized
    Vector2 dir = new Vector2(1, y).normalized;

    // Set Velocity with dir * speed
    GetComponent<Rigidbody2D>().velocity = dir * speed;

I'm sure this is a very basic thing, but I am struggling with this type of thing. I am on Khan academy, starting from very basic stuff and working my way up, so no doubt maybe when I get to vectors I might understand this more, but I'd like to try and really get my head around this particular issue.

Sorry for the very basic question, I have been dabbling in C# and Unity for a while, but I have realised my weakness is really in the basic core logic of some things....I am a composer by day but I really enjoy trying to get back into this side of my brain, I guess it's super dusty in there hahaha.

Thanks so much in advance for any help, I truly appreciate it.

\$\endgroup\$
0
\$\begingroup\$

The (ballPos.y - racketPos.y) / racketHeight calculation is what we call a linear interpolation.

(ballPos.y - racketPos.y) calculates the distance of ball from the center of the racket.

Then you divide it by the height of the racket to normalize the scale so that if the ball hit the top of the racket the value is 0.5, and if the ball hit the bottom of the racket the value becomes -0.5.

In other words, we scale the range to [-0.5, +0.5].

Note: This calculation doesn't assure that the value stays within [-0.5, +0.5] range. For example, if the ball is above the racket the result will be greater than +0.5, and if it is below the racket the result will be lower than -0.5.

What assures the value to stay within this range is your collision check. If the ball is colliding with the racket, surely it must be touching the racket, therefore it cannot be above or below the racket.


Vectors are denoted with tuples. The notation of (8, 3) means 8 on X axis and 3 on Y axis.

(1, 0) is a vector from left to right.

If you increase the Y value it starts pointing upwards. (1, 0.5) points in approx. +26.5 degrees (starting from +x axis).

If you decrease the Y value, it starts pointing downwards. (1, -0.5) points in approx. -26.5 degrees (starting from +x axis).

(0, 1) is a vector from bottom to top.


Since your code maps the Y hit point in (-0.5, +0.5) range, we can put that directly in the Y component of the final vector to get a range that starts from (+1, -0.5) and goes to (+1, +0.5).

As you may remember, (+1, -0.5) is a vector that points towards -26.5 degrees and (+1, +0.5) points towards +26.5 degrees. Therefore we created a range of angles of [-26.5, +26.5].


One final problem is that the length of the vector (1, 0) is not same as the length of the vector, for example, (1, -0.5) or (1, 0.234).

To fix this, we simply normalize the vector, meaning we scale it so that the length of vector equals 1. In Unity, you can simply call the_vector.normalized to get the normalized version of the vector.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Wow, thank you so so much for taking the time to write all this and help me understand this. I really appreciate it. \$\endgroup\$ – heckadactyl Nov 5 '18 at 19:43
  • \$\begingroup\$ @heckadactyl I am happy to help. \$\endgroup\$ – S. Tarık Çetin Nov 6 '18 at 11:11
  • \$\begingroup\$ "If the ball is colliding with the racket, surely it must be touching the racket, therefore it cannot be above or below the racket" ...by a distance more than the ball's own thickness. If we had a 1-unit tall ball hitting a 1-unit tall paddle edge-on, the hit position could be as far as ±1 from the center of the paddle. \$\endgroup\$ – DMGregory Nov 6 '18 at 11:26
  • \$\begingroup\$ @DMGregory I left that detail out intentionally to make it easier to grasp for beginners. \$\endgroup\$ – S. Tarık Çetin Nov 7 '18 at 6:39
0
\$\begingroup\$

It just sets the y based on the position of the ball relative to the paddle. At the top it will bounce in a 45 degree angle, at the bottom in a -45 degree angle. It's called linear interpolation.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for letting me know, I'll have a look into it, appreciate it. \$\endgroup\$ – heckadactyl Nov 5 '18 at 9:40
  • \$\begingroup\$ @heck if an answer solved your problem, press the green tick mark \$\endgroup\$ – Bálint Nov 5 '18 at 10:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.