The perfect bouncing ball

I’m trying to archieve a perfect bouncing ball. For that I set the bouncyness of the phyiscs material of the ball to 1 and the friction to zero as well as the drag/angular drag to zero. The problem is that the ball seems to gain energy each bounce and jumps higher and higher. Any idea why this happens?

I’ve tried to achieve the same, but tweaking physics etc. doesn’t seem to be enough…there is “leakage” or some other inaccuracy.

In the end I used calculations to lerp to the “right” height.

1 Like

Yeah. The pitty is I had it once working and hence I know it works, but I lost that project due to a crahs. I’m trying now to despairingly re-create the effect… :slight_smile:

What do you mean by perfect bouncing ball? Do you mean it bounces forever, or that it will bounce then eventually come to rest? It sounds like you are trying to achieve the former. If so, I think it works “out of the box.” When I first started fiddling with Unity a few months ago, I created a sphere and gave it a rigidbody. I placed it above a plane and hit play. The thing wouldn’t stop bouncing, but never gained altitude either.

Yes, a forever bouncing ball that does not loose energy. I tried it with several settings meanwhile, changing physics materials and all that, but still it gains height every bounce. I attached a sample project which demoes that effect.

170094–6129–$_bounceball_636.zip (1.37 MB)

When I get home, I’ll do what I did before. If it behaves the same way, I’ll post the settings that are on the material/rigidbody.

Store the ball’s velocity in a member variable somewhere. After any collision, take its new velocity, normalize it, and then multiply by the stored velocity. This will eliminate any small errors caused by the physics engine.

I found a solution for this! Using the idea Podperson had I left out the normalizing, but only saved on the first bounce contact the velocity. When a ball falls down it usually has a negativ velocity.Y value which gets inverted to positive when the OnCollisionEnter occures. Now I save that value in a member variable and override the balls velocity.y value each time a collision occures. That gives an exact the same height bouncing ball. The cool thing with that solution is, you can “spawn” your ball at any height (as required in my game) and it will always use that spawn height for bouncing then.

Thanks to all people helping finding a solution!

That script is attached to the bouncing ball.

var firstTimeVelocitySave = false;
var savedVelocity : Vector3;

function OnCollisionEnter(col : Collision) {
	//print("Collision! " + rigidbody.velocity);
	if (! firstTimeVelocitySave) {
		savedVelocity = rigidbody.velocity;
		firstTimeVelocitySave = true;
	}
	myRigidbody.velocity.y = savedVelocity.y;
}

Hi, I’m a beginner in Unity and I tried to apply your code in 3 cubes I created in my exercise:

But I can’t achieve the effect I want to :hushed:

The 3 cubes just keep going on the y-direction without doing the reverse…

Can you tell me if I’m doing something wrong?

Thanks in advance.

Update the code, it could working very good in my case.

Javascript:

#pragma strict
var firstTimeVelocitySave = false;
var savedVelocity : Vector3;
var myRigidbody : Rigidbody;
var BounceRate:float =1.5;

function OnCollisionEnter(col : Collision) {
//print("Collision! " + rigidbody.velocity);
if (! firstTimeVelocitySave) {
savedVelocity = rigidbody.velocity;
firstTimeVelocitySave = true;
}
myRigidbody.velocity.y = savedVelocity.y;
savedVelocity.y=savedVelocity.y/BounceRate;
}

C#

using UnityEngine;
using System.Collections;

public class ballBounce : MonoBehaviour {

private bool firstTimeVelocitySave = false;
private Vector3 savedVelocity;
//public Rigidbody myRigidbody ;
public float BounceRate =1.5f;

void OnCollisionEnter(Collision collision) {
//print("Collision! " + rigidbody.velocity);
if (! firstTimeVelocitySave) {
savedVelocity = rigidbody.velocity;
firstTimeVelocitySave = true;
}
//myRigidbody.velocity.y = savedVelocity.y;
// myRigidbody GameObject
gameObject.rigidbody.velocity =new Vector3(0,savedVelocity.y,0);
savedVelocity.y=savedVelocity.y/BounceRate;
}

}


www.powenko.com
unity tutorials, http://www.powenko.com/en/?page_id=2928
Powen Ko

Alternatively:

#pragma strict
var Bouncibility:float = 1.1;

function OnCollisionEnter (collision : Collision) 
{
	rigidbody.velocity.y = collision.relativeVelocity.y/Bouncibility;
}

values of bouncibility less than 1 will cause an increase of bounce height after each bounce, over 1 causes a decrease in bounce height

Attach to something with a RigidBody, fiddle with Bouncibility, watch it bounce.

I’m not entirely sure of the thought process behind the other solutions, they seem overly complicated to achieve something so simple. Unless I’m missing some other requirement?

(Sorry to revive old thread, was one of the first things that popped up on Google for this topic though!)

2 Likes

2523136--174972--upload_2016-2-23_20-18-0.png

1 Like

These simple lines of code should work for you:

C#:

public Rigidbody rb;

float storedVelocity;

void Start() {
rb = GetComponent ();
rb.velocity = new Vector3(0, 5, 0);
storedVelocity = rb.velocity.y;

}

void OnCollisionEnter(Collision collision)
{
rb.velocity = new Vector3 (0, storedVelocity, 0);
}