Ball can became very slow after been squish against the side wall

The title says everything. This is not a rare occurrence, if I play for 30 minutes this problem will appear at least once (if I squish the ball against one lateral wall times enough).
Some times the ball can stop almost completely.
There is a solution for this? Maybe a way to speed up the ball if the ball became too slow…
After research a little, I realized that “speed” is not as simple as “one number”, is more complicate and involves Vector 2 values. Not an easy thing to understand.

There is a link with the discussion. Look at @Banpa solution, it’s better than mine :

You can use a float value for speed.
(This is more like “desired speed” or “speed I will enforce”.) You’re right that velocity is measured with a vector (Vector2), but we can use this float value to modify the velocity vector.

The actual speed if the ball is the magnitude of its velocity vector. Vectors are usually thought of as arrows and expressed as Vector2s. Even though we write them as coordinates, lime (4,3), they can be better thought of as modifiers such as (+4, +3). It may help to keep thatin mind.

A (4,3) vector, for example, points 4 units to the right and 3 units upward. The length of the arrow is it’s magnitude, which can be calculated by pythagream theorem. In this case, the length of a vector that goes 4 units across and 3 units upward is 5. (4 squared is 16, 3 squared is 9, 16+9=25, and the square root of 25 is 5.)

So vector (4,3) has a magnitude of 5. If this is a velocity vector, that would be the speed. A vector that goes 8 units across and 6 to the right would be going in the same direction but have twice the magnitude.

We can add vevtors together to get new vectors, such as adding (1,2) to (4,3) to get a new vector of (5,5).

One confusing thing is that we also use Vector2s to represent position. We can even take a position, add a vector to it, and get a new position as a result. When we add a vector to a position, we get a Vector2 that represents a new position - we do that a lot. You can also add a vector to a vector to get a new vector. That’s what we are doing with our “velocity tweak”. Because we get a new velocity vector as a result, that vector has a new magnitude, which means our ball has a new speed. Speed is the magnitude of the velocity vector.

Unity automatically calculates the magnitude of any vector by adding .magnitude at the end. The magnitude of a vector is a float.

Vectors can be modified by multiplication and division math operations. For example, you could multiply a vector by 2, or divide it by 5, or something. This is called scaling the vector, and the number you are multiplying or dividing by is called the scalar. When you scale a vector, you apply the scalar to each of it’s coordinates. For example, Vector2(4,3) * 2 would get you a new vector2 (8,6). Coincidently (or not), the magnitude is modified by the same amount. When we doubled each coordinate in the vector, we also doubled its magnitude (from 5 to 10, in this case).

This part’s a bit of a heavier concept in my opinion, but bear with me here. One of the most useful vector math operations is to take a vector and scale it down using its own magnitude as a scalar. This is called “normalizing” a vector. When you do this, you get a “unit vector” (or “normalized vector”). A unit vector is just a vector whose magnitude is equal to 1. They are not special, but they are so useful that they get a name. Unity has a function (Vector2.normalized) to get the unit vector from any vector by performing this normalize operation.

The vector (4,3) has a magnitude of 5, so we can find the unit vector by dividing by 5: (4/5, 3/5). This gets us a vector going in the same direction but only with a magnitide of 1, thus it doesn’t go as far (or as fast, in this case).

Why are normalized vectors so useful? Because they are easy to scale. Once you have your normalized velocity, all you have to do is scale that by your desired speed. Boom. New vector2, going at the exact speed you want, but with no change in direction.

Here’s how it would look in Unity:

[SerializeField] float ballSpeed = 5f;
const float maxTweak = 1f;
Rigidbody2D rigidBody;

//in Start()
rigidBody = GetComponent();

//in FixedUpdate()
rigidBody.velocity = TweakVelocity(rigidBody.velocity);

//later in code, new method
Vector2 TweakVelocity (Vector2 vel)
{
float Xmod = Random.Range(-maxTweak, maxTweak);
float Ymod = Random.Range(-maxTweak, 0f);
Vector2 modVel = vel + new Vector2 (xMod,yMod);
ModVel = modVel.normalized * ballSpeed;
return ModVel;
}

1 Like

Thank you for the very complete answer, I’ll create a new simple file and play with this info.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms