- Home /
Kinematics: Trying to get an object to land at a known point
Hello, everyone. I'm trying to toss an object so that it always lands at a determined point, regardless of where it starts initially, and always in the same amount of time. I am trying to use basic kinematics to achieve this, but the object is not reaching the point as I desire. Here is my code:
float d = Vector3.Distance(destination,rb.transform.position); //Get distance between the current position and the destination
float tsqr = timeToReach*timeToReach; //Get the time to reach the destination squared
float m = rb.mass; //Get the mass of the object to be tossed
float f = (float)(d/((.5)*tsqr))*m; //d = v*t + (1/2)at^2 substituting a for f/m and solving for f
rb.AddForce (f * Vector3.forward); //Apply force to rigidbody
What might I be doing wrong? Any help would be greatly appreciated.
Answer by aldonaletto · Dec 28, 2012 at 12:17 AM
Supposing the equation is correct for what you want to do, you should apply a constant force to get the desired result - a single AddForce applies the force only during one physics cycle, which usually is 20mS (unless you change Fixed Timestep in the Time Manager). You should instead use AddForce in FixedUpdate to apply the constant force, or add a Constant Force component and set its force property to the calculated value.
But I suspect that this is not what you actually want: applying the calculated constant force accelerates an object from 0 to some velocity in such a way that the object crosses the specified distance in the desired time - but only if gravity is off: if gravity is on, the rigidbody also falls towards -Y (default gravity), crashing to the ground or reaching a point well below your target. If gravity is on, you must use a ballistic equation instead - but solving it to reach the target in a predefined time is a pain in the ass.
I created a function that calculates the initial direction/velocity to throw an object so that it lands at the target position, provided that the starting and target positions are approximately at the same heights (the function compensates for height differences that are small when compared to the horizontal distance). The time to reach the target can't be specified, but if this can help you, take a look at my answer in this question.
Hi; thanks for the response. When trying to use your function, though, the target is always off; it always seems to land a little bit past the target each time. How might I go about fixing this? Also, if I would like to draw out the parabola/trajectory of the projectile's flight, how would I go about doing that? Thanks.
The function tries to hit the target position, not the ground below it - if the target object is a too above the ground, the projectile will land after it. You must place the target object's center at such height that the projectile hits the ground and the target position at the same time.
You can use a LineRenderer to draw the trajectory: create an empty game object, add a LineRenderer and child it to the projectile, then add the script below to the projectile:
using UnityEngine;
using System.Collections;
public class DrawTrajectory : $$anonymous$$onoBehaviour {
public float interval = 0.5f;
private LineRenderer lineRender;
private int nVertex = 0;
private Vector3 lastPos;
void Start () {
lineRender = GetComponentInChildren<LineRenderer>();
lineRender.SetVertexCount(1);
lineRender.SetPosition(0, transform.position);
lastPos = transform.position;
}
void Update () {
if (Vector3.Distance(transform.position, lastPos) > interval){
lineRender.SetVertexCount(nVertex+1);
lineRender.SetPosition(nVertex, transform.position);
lastPos = transform.position;
nVertex++;
}
}
}
The projectile draws its trajectory each interval distance. If you want to destroy the projectile but still keep it's trajectory, unchild the trajectory object before destroying the projectile.