I found that the basic method to stop boring ball loops did not work for all instances in my game, so i have added a definite push away from the left and right walls and top collider, plus a lifter to stop the ball spending ages bouncing across the screen before it comes back to the paddle. The margins are set as config variables half a Unity Unit in from the colliders, and blockBase is set at 4, because having blocks below that point makes the game unplayable unless you have super-fast reactions.
unstickFactor is a [SerializeField] so i can play with it in the inspector. Set too high and the ball builds up speed too quickly. I have found that a value of about 0.1-0.2 works best for my ageing reactions.
Also, i have changed the velocityTweak calculation so that it can go negative in x and y, otherwise the tweak is always a push towards the top right-hand corner.
Here is my MotionUnstick Method:
private Vector2 MotionUnstick()
{
float unstickVectorX;
float unstickVectorY;
if (transform.position.y > topMargin)
{
unstickVectorY = -unstickFactor;
}
else if (transform.position.y < BlockBase)
{
unstickVectorY = unstickFactor;
}
else
{
unstickVectorY = 0f;
}
if (transform.position.x < leftMargin)
{
unstickVectorX = unstickFactor;
}
else if (transform.position.x > rightMargin)
{
unstickVectorX = -unstickFactor;
}
else
{
unstickVectorX = 0f;
}
Vector2 unstickVector = new Vector2(unstickVectorX, unstickVectorY);
Vector2 velocityTweak = new Vector2
(UnityEngine.Random.Range(-randomFactor, randomFactor),
UnityEngine.Random.Range(-randomFactor, randomFactor));
velocityTweak += unstickVector;
return velocityTweak;
}