Velocity.normalize to a min of one

Hello, I am working on a game with a ball that bounces around a fixed area. I am using this: GetComponent<Rigidbody2D>().velocity = 3 * GetComponent<Rigidbody2D>().velocity.normalized; to keep the ball moving at the same speed but able to change angles. The problem I am running into is that the X or Y can end up as 0 thus the ball stops moving up and down or left and right.

So what I believe is going on is that that line of code will lock the velocity to of X and Y to a sum of 3. thus meaning X can be 0 and Y can be three. So my question is how can I modify this to have it lock between 1 and 3 sum rather than 0 and 3 sum?

Any and all help is greatly appreciated.

If both axis should have a minimum absolute value of 1 that limits the range of each axis to [-2.828, -1] and [1. 2,828] if you want to enforce a total velocity of 3:

94671-velocitylimits.png

To achieve that you want to first normalize the vector the way you did and in addition you would check each component and clamp them appropriately:

Vector2 vec = rb2d.velocity.normalized * 3f;

if (Mathf.Abs(vec.x) < 1f)
    vec = new Vector2(Mathf.Sign(vec.x)*1f, Mathf.Sign(vec.y) * Mathf.Sqrt(3f*3f - 1f*1f));
else if (Mathf.Abs(vec.y) < 1f)
    vec = new Vector2(Mathf.Sign(vec.x) * Mathf.Sqrt(3f*3f-1f*1f), Mathf.Sign(vec.y)*1f);

rb2d.velocity = vec;

Of course the value Mathf.Sqrt(3*3-1*1) is a constant (Mathf.Sqrt(8)) based on your two parameters. So you could pre-calculate it as it never changes.

static float velocityLimit = Mathf.Sqrt(3f*3f - 1f*1f);

Note that if you want to use different “limits” you have to replace all “1f” constants with your desired minimum limit and “3f” with your desired total vector length.

Velocity is direction and speed expressed as a vector. If you don’t allow your velocity vector to have x = 0, you’ll never have your ball going straight up for instance, which breaks the purpose of physic controlled movement.

But your line of code seems not to be the problem for me. I think your problem is elsewhere in your code. Could you share more of your code?

But it wouldn’t know if it should be 1 or -1 of there is no value in an axis? Why not add a little bit of chaos to stop it becoming stuck in left/right or up/down? Something like

GetComponent<Rigidbody2D>().velocity = 3 * GetComponent<Rigidbody2D>().velocity.normalized + Vector2((Random.value * 0.2f) - 0.1f, (Random.value * 0.2f) - 0.1f);