- Home /
display arc for cannon's ball trajectory?
I have a cannon that shoots a ball using the physics engine.
mass, ball speed and forward direction are the variables used. I believe that gravity is a constant. I am trying to find a way to display where the shot will curve the way most pool games will show you where the ball will go (except for it not curving). With the gravity and it being a curve it'll have to look like a sin wave starting from the cannon position and ending when it first hits something.
any easy way to do this?
I am fairly new to unity so please keep that in mind for "complicated" answers.
thanks
[edit] sorry for the double post, I didn't see my question up and thought I messed up instead of needing to wait for moderator approval.
Answer by redteardrop · Sep 26, 2012 at 01:37 PM
apparently wikipedia and trying to go back to my high school math helped. There also appears to be an issue with addforce. I had to make sure I used ForceMode.Impulse to get an accurate initial velocity. If anyone else wants something like this, check the links below for the wiki math and here is a general rundown.
http://en.wikipedia.org/wiki/Range_of_a_projectile
http://en.wikipedia.org/wiki/Trajectory_of_a_projectile
Things you will need to know to predict the trajectory of a launched object using a single forward axis and no air resistance or wind.
1. initial velocity of item (since f=m*a you can get the velocity by dividing the force applied (use ForceMode.Impulse) by the rigidbody mass)
2. the angle of launch (can be put in a variable in an update function)
3. gravity (should be a constant 9.81m/s^2 (just use 9.81)
Here comes the tricky part. You should be able to google the formuly (I can't find the link right now). What needs to be done is use a linerenderer using enough points and plotting each one based on the y height at a given x. It's a good idea to use a transform variable to point to the world coordinates of your starting position to call in code.
var maxDist;this will get you the max distance on a level surface and you can use that minus the initial position of the start point to get a range and a distance for each x of the linerenderer. This won't work for me since I am shooting from the top of a cliff so I just chose a set interval for each of my x positions.
var velocity;
maxDist = ((velocity * velocity) * ((Mathf.Sin((-angle * Mathf.Deg2Rad) *2))))/9.81;//convert degree angle to radian to use in Sin correctly
To find Y us this code (I'm using a for loop to get each linerenderer position):
rayY[n] = (0) + (rayX[n] * (Mathf.Tan(-angle * Mathf.Deg2Rad))) - ( (g * (rayX[n]*rayX[n])) /(((Mathf.Cos(-angle * Mathf.Deg2Rad) * velocity) * (Mathf.Cos(-angle * Mathf.Deg2Rad) * velocity)) *2));The (0) at the beginning is the initial position of y, mine is kept at 0 here since I have the script attached to a child object and the math is local space so it'll move around the world fine. It should even rotate left or right on the cannon and still work properly this way (haven't tried it) rayX[n] is the x position.
Anyway, hope this helps someone else too. I'll see if I can put it in the asset store at some point just to easily add to a project.
Answer by TowerOfBricks · Aug 05, 2012 at 08:36 PM
Depending on input variables a simple formula can be created which will give the object's position after a given time. See http://en.wikipedia.org/wiki/Trajectory_of_a_projectile
The easiest is probably this one:
public Vector3 PlotTrajectoryAtTime (Vector3 start, Vector3 startVelocity, float time) {
return start + startVelocity*time + Physics.gravity*time*time*0.5f;
}
To extend this you can raycast to see when it first hits:
public void PlotTrajectory (Vector3 start, Vector3 startVelocity, float timestep, float maxTime) {
Vector3 prev = start;
for (int i=1;;i++) {
float t = timestep*i;
if (t > maxTime) break;
Vector3 pos = PlotTrajectoryAtTime (start, startVelocity, t);
if (Physics.Linecast (prev,pos)) break;
Debug.DrawLine (prev,pos,Color.red);
prev = pos;
}
}
This will only draw the trajectory in the editor, but you could draw it in the game with for example vectrosity as Fattie suggested. Also, DO NOT try to calculate with air resistance, that is hard (promise).
In case you are wondering, since there is not air resistance, the mass of the object is irrelevant.
This solution was really useful to me, I'm trying to write something that will simulate where a ball will land before it's thrown and I nearly have it working but I don't have the balls velocity to put into the equation, can you provide any assistance?
Thanks.