Calculating a randomized rotation of a 2D projectile to keep it inside the Y axis on-screen,

New to Unity, and rather rusty on my programming so I’m struggling with this calculation in particular.

Basically I’m programming a fancy pong, and what I want is when the ball hits one side, the ball is given a random rotation which will not hit the bottom/top of the screen and leave the play area. Whilst I have the rotation and behavior sorted as such, I cannot for the life of me stop it from occasionally choosing an angle causing it to go off screen. My x length is 30, and my y height is 14 (from -7 to 7, rather than starting from 0)

What I’m using is:

public float rotationcontrolBall;

    rotationcontrolBall = Random.Range(Mathf.Rad2Deg * Mathf.Atan((-7 - TennisBall.transform.position.y) / 30), Mathf.Rad2Deg * Mathf.Atan((7 - TennisBall.transform.position.y) / 30));

I’m unsure if maybe I’m not calculating the difference between the Yposition and the edges of the screen, or I’m not using Mathf correctly, but it still seems happy as ever to launch itself slightly off-screen sometimes.
This is also how I’m controlling the rotation:

    if (rotationcontrolBall < 0)
        TennisBall.transform.Rotate(0f, 0f, 360 + rotationcontrolBall);
        TennisBall.transform.Rotate(0f, 0f, rotationcontrolBall);

I’d be very grateful if anyone can tell my why I’m being absolutely silly here.

I can see three things that might be wrong:

  1. I have not necessarily interpreted the layout of your game correctly, but assuming you are moving the tennis ball along it’s local ‘up’ vector, then your calculations give the impression that you expect a zero degree rotation to point the local ‘up’ vector along the global ‘right’ vector. You could solve this in a couple of ways, adding 90 degrees to your current calculation might be the simplest since you are working in 2D.

  1. You have not taken into account the side that the ball is on, so assuming you have a correct rotation on the right hand side of the map, then when you are on the left hand side of the map, all of your rotations will point out of the map as they will be off by 180 degrees.

  1. transform.Rotate rotates the transform from it’s current rotation as opposed to setting the rotation directly, as you seem to be calculating your desired rotation rather than your desired rotation change this will cause incorrect behaviour over time. You can set the rotation directly using transform.rotation = Quaternion.Euler(0, 0, rotationcontrolBall);

Hope that helps!