Games based on balls can be a frustrating to build. I’ve done a number of them myself and used a variety of different techniques. The hardest part tends to be getting the physics right. Some games require a ton of tweaking, adjusting rigidbodies, colliders, physics materials and scripts. But in some other games, cheating is the way to go.. Cheating by not using the physics system for bouncing..
Instead of allowing the physics system to control our ball bounces, we’ll create a simple script to do it instead. Instead of adjusting the mass, bounciness, & friction our script will have a single float for the minimum bounce velocity. This will keep our ball bouncing forever, and always at about the same speed.
What’s it look like?
There are a couple things to cover here, we’ll go over them in order.
To start we have a Vector3 for an initial velocity. Like the tooltip says, this is just for the example / debugging. Our OnEnable method will set the initial velocity to this value so the ball starts moving.
The minVelocity field is used to control how slow the ball can go. Every bounce will be at this velocity (or higher).
OnEnable() – Here, we’re caching the rigidbody reference and setting that initial velocity.
Update() – This one’s important. Because we’re going to override the collision behavior, we need to keep track of the objects velocity each frame. When the collisions happen, this velocity is going to change, but for our calculations, we want the velocity before the collision. Saving it off here in Update is an easy solution.
OnCollisionEnter() / Bounce() – This is where we do the work.. even though it’s not much work. Calculating direction is done using Vector3.Reflect. We pass in the last frame velocity (that we cached in Update), along with the collision’s normal. Then we multiply the result by the current velocity OR the minVelocity, whichever is greater.
Bouncing toward the player
In games where you have the player hitting a ball against a surface, you’ll often want to send the ball back toward the player. This might seem ‘not realistic’, but it’s usually way more fun. And it’s pretty easy to do.
The only real difference is when you’re setting the return velocity, we’ll lerp between the direction to the player and the reflect value.
In the editor, we expose a bias field that allows easy tuning of just how ‘toward the player’ the ball goes. The right value for the bias will depend on your game and the play area size.
If you want to try this out and don’t want to setup a couple cubes, you can download the example project here: https://unity3dcollege.blob.core.windows.net/site/Downloads/Ball%20Bounce.zip
This functionality isn’t appropriate for every game, or every interaction in every game.. but there are plenty where it works better than using the default physics setup. Especially the bouncing towards a player.. I’ve used that more than once and found it always made the games more fun and engaging. It’s also worth noting that you can use Vector3.Reflect for all kinds of other functionality, reflecting bullets, beams, or anything else.. so keep it in mind when coming up with new game mechanics 🙂