While playing I noticed that the velocity of the ball kept increasing, which made it very difficult to win large levels. This increase in velocity is due to the random tweak that was added during the course.
To fix this problem I’ve put a SpeedUp guard in my code that activates when a certain velocity is measured.
I added this block of code in the Update() method of my Ball.cs script.
What does it do:
First of all it calculates the actual velocity of the ball. This is done by using the Pythagorean theorem
(a2 + b2 = c2) and found in the first line of code. Because it is located in the Update method it will calculate this velocity every frame.
It checks if the actual velocity is above a certain threshold. In my case I’ve put this threshold at 10, but this value depends on the starting velocity you give the ball and the possible increase due to the tweak. Just test it to find the right value that fits with your build.
If the velocity is too high it will decrease it. Therefor we need to make a new vector which can modified, in my case this is ‘decreaseVelocity’. Both the x and y-value of this vector will be incremented with +0.3 or -0.3. The sign is the opposite of the original velocity (that is why I put in -0.3f and not 0.3f). So if the ball was going in the positive x direction, we want to increment with a negative x-value and the other way around. The same goes up for the y-value.
After the incrementation, it gives this incremented vector back to the object.
I used the lines in comments to test this code and notice the difference in actual velocity before and after the adjustment. These lines can also be used to playtest and find the best values for the threshold and adjustments. First I thought that this sudden decrease in velocity would tamper with the natural flow of the game, but if you choose the right adjustment values (0.3 in my case) this change is barely noticed.
I hope this helps other people that came across this problem and please comment if you find something that I overlooked!
Thanks Jonas. I will write something like this to my script. It is very easy way to do SpeedUp Guard. But best thing is you taugh logic of codes with descriptions. So im sure nobody is gonna copy and paste it.
For abridge some code you can use: float actualVelocity = Mathf.Sqrt(Mathf.Pow(rigidbody2D.velocity.x, 2) + Mathf.Pow(rigidbody2D.velocity.y, 2));
Instead of: float actualVelocity = Mathf.Sqrt(rigidbody2D.velocity.x*rigidbody2D.velocity.x + rigidbody2D.velocity.y*rigidbody2D.velocity.y);
I’m just saving the ball’s speed before making any alterations, tweaking the velocity, normalizing the result, then restoring it to its previous speed. I think it works fine?
I chose to allow the random tweaks to be negative, so that it doesn’t constantly favor going to the right.
If someone likes the idea of the ball speeding up over time, that can still be implemented that here with more control.
If you want to increase the starting speed you just need the change the vector you give the ball in the start method.
On the other hand if you want to increase the maximum velocity the ball can reach (ie the velocity around it will stay during the game), you need to change the parameter in the if-function:
if (actualVelocity > xxxxxx) => x’s represent the default speed you want to give to the ball. To increase the overall velocity just increase it to something more than 10. You can also change this to a public variable and be able to tweak it in-game.
Hi Zach,
I actually didn’t think about extracting the velocity magnitude from the ball, but I guess it works perfect.
I just got two questions:
Does the .normalized behind (rigidbody.velocity.normalized + tweak) work, because it looks a bit of a strange construction?
Why not change the magnitude of the veloctity back to the previous speed after the alterations, instead of multiplying the vector with the speed?
I haven’t tried your code yet, but I can imagine this to be working.
As I understand it, normalized and magnitude are both computed properties of a Vector. Normalized is a version of the vector with a length/magnitude of 1 (when using vectors to represent velocities, length is equivalent to the speed).
(rigidbody.velocity.normalized + tweak).normalized works because I’m adding a vector to another vector, and since the result is a vector, it has the normalized property. If it helps to make it more readable, you could write it out as
Vector3 tweakedVelocity = (rigidbody.velocity.normalized + tweak);
rigidbody.velocity = tweakedVelocity.normalized * speed;
You cannot change the magnitude property directly, as it is read-only, but multiplying a normalized vector by a number has the same effect.