Better parabolic motion for bounces


In a previous post, I detailed a methods of using tweens to give explosion debris some bounce and life. I knew at the time that this would be expensive for a large number of particles – but it was the right look and I at least wanted the temporary solution in the game. Consider it a living mockup, waiting to be optimized.

Recently I came across this post on gamasutra by Mohan Rajagopalan describing design philosophies and techniques behind 2D jumps. Sure enough, the parabolic arc equation was exactly what I needed for my debris bounce, which could be considered debris "jumping." Here's the classic formula:

$$y(t) = v_0 + { gt^2 \over 2 }$$

The implementation of this as a Unity component is quite straightforward , and here's a simple version of the Update() function of the behavior:

public void Bounce(int numberOfBounces)
{
	// init
	startTime = Time.time;
	lastYOffset = 0.0f;
	bounceNumber = numberOfBounces;
	bounceVelocity *= 0.5f;
}

void Update()
{
	// if done with bounces, stop
	if (bounceNumber <= 0)
	{
		return;
	}

	// otherwise, calculate current yoffset
	if (bounceNumber > 0)
	{
		// apply classic parabolic formula: h(t) = vt + (gt^2 / 2)
		float time = (Time.time - startTime);
		yOffset = (bounceVelocity * time) + ((gravity * time * time) / 2);
		
		// add to the current position, but subtract last y offset (additive behavior)
		// since this could be moving in the y-axis from other forces as well
		transform.position = new Vector3
		(
			transform.position.x,
			transform.position.y + yOffset - lastYOffset,
			transform.position.z
		);
		lastYOffset = yOffset;

		// if hitting the "floor", bounce again
		if (yOffset <= 0f)
		{
			BounceTimes(bounceNumber - 1);
		}
	}
}

One thing to note is that I subtract the previously calculated y-offset since I am adding the new y-offset to the current position each update. This allows this parabolic offset to be additive to any other motion the game object is already undergoing. This is perfect in my case, since the debris is being ejected by an explosive force, and I am just adding this to the y-axis to simulate bouncing in overhead 2D space. As stated in the original post, the root of all this is the simple fact that Unity doesn't allow gravity in the z-axis for 2D projects.