# Simulating beer pong physics in Unity

I'm trying to create a simple beer pong game in Unity. The basic idea is this - when it's your turn to shoot, you use your mouse to pick a point on the table that you want the ball to hit and bounce off of.

Then you press the left mouse button, and while it's pressed, move it up and down to determine the degree of the arc of the shot (the ball should hit the same previously chosen spot on the table no matter which degree is chosen).

The arc should be visible as well. It would look something like this:

So my questions are:

1. Given a target point and a launch angle, how do I calculate the trajectory?
2. Given the same, how do I calculate the force to apply to the ball?
3. What is the best way to display the trajectory in Unity? My first idea is manually placing a bunch of particles (which is how I did it in the screenshot), but I'm not sure if that's the best choice performance-wise.
• Sounds like a fun game. What do you have so far?
– Evorlor
Commented May 18, 2015 at 0:02
• @Evorlor not much. The ball physics are the first thing I'm trying to do, but without much luck.
– ivan
Commented May 18, 2015 at 10:34
• Can we play the game when it's ready? :P Commented Aug 21, 2016 at 19:58

This is fun! The trajectory is just a bunch of mathfz and a line renderer. Check out this post for more information on that which details how to calculate the trajectory. Line renderers are definitely your best bet for visualization. Even on mobile, 5-10 line renderers would be no problem. The alternative would be to hard-code the visualization with a (code-created) mesh or directly rendering to the screen, both of which are not fun.

As for physics, I bet you can use Unity's PhysX out of the box. You'll have to play with the initial force to apply but the direction should be about the direction the camera is facing. All you have to do is multiply by some factor to get it working well.

float X = 10;

• Thanks. But the post you linked doesn't really help me. He uses predefined starting velocity and applies it to the projectile. What I need is a bit different. Yeah, Unity's out of the box physics will do just fine, but I'm not sure how to calculate the force I need to apply to the ball.
– ivan
Commented May 18, 2015 at 10:39
• With a pre-defined velocity, you can actually use ForceMode.VelocityChange. That makes a lot more sense for trajectory calculation. With the above code, your starting velocity is 'Camera.main.transform.forward * X'. Commented May 18, 2015 at 17:20
• Yes, but with a predetermined velocity, I can't leave both the starting angle and the target up to the player. And I want the player to be able to determine the starting angle AND the target because it makes more sense for a beer pong game.
– ivan
Commented May 18, 2015 at 17:54
• No, the velocity is not predetermined. Camera.main.transform.forward is the direction the camera is facing and it was used for the sake of example. It's 100% variable. Just use an FPS controller or something. Btw, don't think of angles. Think of directions with a magnitude of 1 (like slopes on a graph) because that's how the ball thinks when it travels through space. Commented May 18, 2015 at 18:11

So I started writing some code for you. Then when I tested it, it didn't have the desired result. Here is the code so far. If anyone know what is wrong with it, do tell :-)

/// <summary>
/// Adds the velocity to simulate throwing a ball
/// </summary>
/// <param name="angle">The angle of the throw along the z axis</param>
/// <param name="direction">The degrees of the throw to the left or right</param>
/// <param name="power">The power of the throw</param>
private void ThrowBall(float angle, float direction, float power)
{
angle = Mathf.Max(Mathf.Min(0, angle), 90);  //Make sure angle is between 0 and 90
direction = Mathf.Max(Mathf.Min(-45, direction), 45);  //Make sure direction is between -45 and 45
power = Mathf.Max(1, power);  //Make sure there is a power of at least 1
float xForce = Mathf.Cos(angle) * Mathf.Sin(direction);  //Get the force to apply to the x axis to throw the ball to the left or right
float yForce = Mathf.Sin(angle);  //Get the force to apply to the y axis based on the angle
float zForce = Mathf.Cos(angle) * Mathf.Cos(direction);  //Get the force to apply to the z axis based on the angle
Vector3 force = new Vector3(xForce, yForce, zForce).normalized;  //Get the force in a Vector3 and normalize it so that the angle does not affect the power
GetComponent<Rigidbody>().AddForce(force * power);  //Get the Rigidbody Component and apply the force to it based on the angle and power
}


It works if throwing in a straight line, but when adding a left/right directional force, it raises faster than it moves forward. I am very interested in finding an answer to this. I am going to keep looking, and I will update the code as I find out more information.

As for the trail, I would just add particles behind it.