Apply A Force to Reach a Specific Height

I want to apply a force upwards against gravity such that an object reaches a specific height.

Imagine a ball at rest at position (0,0,0), I would like to bounce the ball upwards such that the highest point it reaches will be (0,3,0) before gravity takes over and pulls it back down.

It is necessary that this looks like a natural motion, and I want to be able to change the height. So that I can bounce the ball to 3, 5, 15, or whatever value I choose to set. I'm not overly familiar with physics. What is the best way to achieve this?

Assuming that the physics in Unity work like real life, then this equation should help (note this is not code, just physics equations)

1) h = (vy)t + 0.5(g)t^2
  which becomes:
2) vy = (h - 0.5(g)t^2) / t

variables:
h = height (in meters)
vy = the initial y velocity of the object when fired (the upward velocity in m/s)
t = time (in seconds)
g= the force of gravity (which should be -9.81 m/s^2)

The maximum height will be reached after this many seconds

3) t = (0- vy) / g

So if you plug in what you get from equation (3) into equation (2) along with your desired height you can get the required y velocity of your projectile. In case you aren't sure what to do with that velocity you can just use some trigometry to get the overall velocity:

alt text

This velocity doesn't necessarily give you the force, though, since Force is based on object mass and acceleration, so I don't know the best way to apply this speed. Also I'm sorry if this isn't the best explanation.

Here is a little example of how you can play with the `AddForce` and check the actual `maximum height` during run-time, while you can check DastardlyBanana's answer for the physics behind it.

In order to see it in action:

  • Create new `Sphere`
  • Put it on the ground (the initial position of the `Sphere` is essential for reseting the experiment)
  • Add a `Physics->Rigidbody`
  • Change the `Material` to `Rubber`
  • Attach this `JavaScript` to it

private var force: String = "100";
private var mass: String = "1.0";
private var time: float = 0;
private var maxHeight: float = 0;
private var startPosition: Vector3;

function Start() {
    startPosition = transform.position;
    resetObj();
}

function Update () {
    time += Time.deltaTime;
    if (maxHeight < (transform.position.y - startPosition.y)) {
        maxHeight = transform.position.y - startPosition.y;
        time = 0;
    }
    if (time > 5) {
        maxHeight = 0;
    }
}

function OnGUI () {
    GUI.Box(Rect(16, 16, 60, 24), "Force Y:");
    GUI.Box(Rect(16, 48, 60, 24), "Mass:");
    force = GUI.TextField(Rect(80, 16, 64, 24), force);
    mass = GUI.TextField(Rect(80, 48, 64, 24), mass);
    if (GUI.Button(Rect(16, 80, 128, 24), "Apply Force!")) {
        rigidbody.mass = parseFloat(mass);
        rigidbody.AddForce(Vector3.up * parseInt(force));
    }
    if (GUI.Button(Rect(16, 112, 128, 24), "Reset")) {
        resetObj();
    }
    GUI.Box(Rect(16, 144, 128, 24), "Max Height: " + maxHeight.ToString("f4") + "m");
}

function resetObj() {
    maxHeight = 0;
    rigidbody.velocity = Vector3.zero;
    rigidbody.angularVelocity = Vector3.zero;
    transform.position = startPosition;
    rigidbody.Sleep();    
}

Hello Lipis,

It definetely worked amazing. I am new on coding. I understand some part of the code you provided but i can’t some of them… can you explain each line of code for what purpose they are there ?. In the end it just worked perfectly.

Thanks you alot once again.