Comments and answers for "Shooting a cannonball."
http://answers.unity.com/questions/148399/shooting-a-cannonball.html
The latest comments and answers for the question "Shooting a cannonball."Answer by LeleUnity
http://answers.unity.com/answers/1777394/view.html
@aldonaletto Your code returns error: **"rigidbody.velocity assign attempt for 'Shell(Clone)' is not valid. Input velocity is { NaN, NaN, NaN }. UnityEngine.Rigidbody:set_velocity (UnityEngine.Vector3)"**
----------
maybe because of the angle? Could you show how to get the angle of transform instead your fixed float of 30degrees ? I have done transform.localEulerAngles.x in order to get 60 degree, the inclination af the cannon tip and have done :
ball.GetComponent<Rigidbody>().velocity = BallisticVelocity(target, cannonTip.localEulerAngles.x);
but doesnt work at all... **your code works only on 0 to 90 degrees angles.**
It seems a problem of the square root and angle.. Could you fix it to make it universal ?
Thank you!Sun, 04 Oct 2020 10:39:31 GMTLeleUnityComment by LeleUnity on LeleUnity's comment
http://answers.unity.com/comments/1771865/view.html
Your code returns error: "rigidbody.velocity assign attempt for 'Shell(Clone)' is not valid. Input velocity is { NaN, NaN, NaN }.
UnityEngine.Rigidbody:set_velocity (UnityEngine.Vector3)"
maybe because of the angle? Could you show how to get the angle of transform instead your fixed float of 30 ? I have done transform.localEulerAngles.x in order to get 60 degree, the inclination af the cannon tip and have done :
ball.GetComponent<Rigidbody>().velocity = BallisticVelocity(target, cannonTip.localEulerAngles.x);
but doesnt work at all...Mon, 14 Sep 2020 16:32:03 GMTLeleUnityComment by aldonaletto on aldonaletto's comment
http://answers.unity.com/comments/1545683/view.html
Use a lower elevation angle: the higher the angle, the more the projectile takes to land. Lower angles increase horizontal speed and reduce vertical velocity.
Another alternative is to increase Physics.gravity, but all objects will fall faster - not necessarily a bad deal, since things seem to fall too slowly in Unity.
Remember that Physics.gravity is a Vector3, thus you should do something like this:
void Start(){
Physics.gravity = new Vector3(0,-20f,0); // sets gravity to 20 m/s2
}
Place this code in a script attached to some object in scene (camera, for instance).Fri, 24 Aug 2018 01:13:49 GMTaldonalettoComment by iLyxa3D on iLyxa3D's answer
http://answers.unity.com/comments/1545355/view.html
How to increase speed of object movement? Right now current formula is working, but objects flying very slow..Thu, 23 Aug 2018 07:38:05 GMTiLyxa3DComment by marmildev on marmildev's answer
http://answers.unity.com/comments/1480725/view.html
it's works , great ... :) thank youThu, 15 Mar 2018 12:07:21 GMTmarmildevComment by Khawar-Munir on Khawar-Munir's answer
http://answers.unity.com/comments/1440607/view.html
Thanks a lot for this helpful answer, But what if i want to ad drag in the rigidbody. I am making badminton game. and i want to create a shuttle like projectile. i can't make it touch the target. Please help...Sat, 09 Dec 2017 07:53:16 GMTKhawar-MunirComment by Calos1591 on Calos1591's answer
http://answers.unity.com/comments/1009412/view.html
C# Version.
public Transform myTarget;
public GameObject cannonBall;
public float shootAngle = 30;
Vector3 BallisiticVel (Transform target, float angle)
{
var dir = target.position - transform.position;
float h = dir.y;
dir.y =0;
float distance = dir.magnitude;
float a = angle * Mathf.Deg2Rad;
dir.y = Mathf.Tan(a);
distance += h/Mathf.Tan(a);
float vel = Mathf.Sqrt(distance * Physics2D.gravity.magnitude/Mathf.Sin(2*a));
return vel * dir.normalized;
}
void Update()
{
if(Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.B)){
GameObject ball = Instantiate(cannonBall, transform.position, Quaternion.identity) as GameObject;
ball.rigidbody2D.velocity = BallisiticVel(myTarget, shootAngle);
Destroy(ball, 10);
}
}Sat, 18 Jul 2015 00:25:01 GMTCalos1591Comment by aldonaletto on aldonaletto's answer
http://answers.unity.com/comments/781841/view.html
@Cypras, take a look at [$$anonymous$$er Barkan's answer in this question][1]. I didn't test it, but from the comments it seems to do the job.
[1]: http://answers.unity3d.com/questions/248788/calculating-ball-trajectory-in-full-3d-world.htmlSat, 30 Aug 2014 20:08:22 GMTaldonalettoComment by Cypras on Cypras's answer
http://answers.unity.com/comments/780837/view.html
@aldonaletto Is there a way to make this so this is accurate even when the height of the target object is different than the firing object?Fri, 29 Aug 2014 04:26:23 GMTCyprasComment by sandeepsmartest on sandeepsmartest's answer
http://answers.unity.com/comments/690067/view.html
Dat was fantastic Bro..But how to use your ballistic function with different speeds (Should Reach the Target)??
I actually tried as below but the cannon ball is crossing the target(As i have multiplied with some value to the force required)
May b am incorrect can u please help me with this???Sat, 19 Apr 2014 09:14:25 GMTsandeepsmartestAnswer by Dschonny2000
http://answers.unity.com/answers/582731/view.html
Well, stumbled upon this thread and asked myself same question as Mozes - how can I rearrange this to calc the angle with given velocity?
Tried it with
float angle = ( Mathf.Asin((distance * Physics.gravity.magnitude) / (velocity * velocity)) ) / 2
but that doesn't do the trick. Also, when thinking about it, when velocity is fixed there must be a distance-range (min and max distance) in which there is a valid angle, and in that range there will probably be two angles that do the job.. but I'm just too bad at math to get it..
In case anybody still needs the original Velocity-calculation (thanks for this to aldonaletto!) in c#, here's my translation:
Vector3 calcBallisticVelocityVector(Transform source, Transform target, float angle)
{
Vector3 direction = target.position - source.position; // get target direction
float h = direction.y; // get height difference
direction.y = 0; // remove height
float distance = direction.magnitude; // get horizontal distance
float a = angle * Mathf.Deg2Rad; // Convert angle to radians
direction.y = distance * Mathf.Tan(a); // Set direction to elevation angle
distance += h/Mathf.Tan(a); // Correction for small height differences
// calculate velocity
float velocity = Mathf.Sqrt(distance * Physics.gravity.magnitude / Mathf.Sin(2*a));
return velocity * direction.normalized;
}Mon, 25 Nov 2013 05:05:25 GMTDschonny2000Comment by fafase on fafase's answer
http://answers.unity.com/comments/377353/view.html
I know this is long gone thread but in case...
Drag in real physic is a little complex as stated above but simplified you could do:
var lastDrag : float = 0;
void FixedUpdate(){
rigidbody.AddForce(myTarget*lastDrag);
var drag = rigidbody.velocity * 0.1;
rigidbody.AddForce(-myTarget*drag);
lastDrag = drag;
}
That takes the actual velocity of the object and takes a ratio of it. I give 0.1 but that should be dependent on the geometry of the object...Since it is a percentage, it will just slow down but never push back as this is drag and not wind.
Every FixedUpdate, the previous drag is cancel adding a push in the opposite direction and a new one is added based on the new velocity. It is not perfect but should get you closer.Wed, 09 Jan 2013 10:38:40 GMTfafaseAnswer by Kergal
http://answers.unity.com/answers/296905/view.html
Hey guys I stumbled over this nice thread - which covers exactly what I need, unfortunately everybody is coding in unity script...
i tried to translate the code to c# , but I must have made a mistake.
this is my translation:
public Vector3 BallisticVel(Transform target, float angle){
Vector3 dir = target.position - mySelf.transform.position;
float h = dir.y;
dir.y =0f;
float dist = dir.magnitude;
float a = angle * Mathf.Deg2Rad;
dir.y = dist * Mathf.Tan(a);
dist += h / Mathf.Tan(a);
float vel = Mathf.Sqrt(dist*Physics.gravity.magnitude / Mathf.Sin(2 * a));
return vel*dir.normalized;
}
here I "call" the function :
GameObject ball = Instantiate(ArrowObject,_ArrowObjectPos.position,Quaternion.identity)as GameObject;
ball.rigidbody.velocity = BallisticVel(enemyObject, shootangle);
mySelf is the gameobject the script is attached to ;)
and this is the errormessage I get :
rigidbody.velocity assign attempt for 'Sphere(Clone)' is not valid. Input position is { NaN, NaN, NaN }.
UnityEngine.Rigidbody:set_velocity(Vector3)
I am terrible with all those Mathf. stuff. I was able to use the script like this :
public Vector3 BallisticVel(Transform target){
Vector3 dir = target.position - mySelf.transform.position;
float h = dir.y;
dir.y =0;
float dist = dir.magnitude;
dir.y = dist;
dist += h;
float vel = Mathf.Sqrt(dist*Physics.gravity.magnitude);
return vel*dir.normalized;
}
but like this - i shoot the cannon way too slow and a bit too far.
Any suggestions?Sun, 05 Aug 2012 22:45:42 GMTKergalComment by Menace on Menace's answer
http://answers.unity.com/comments/259746/view.html
Absolutely! The ballistic formula works like a charm. Just trying to find a way to compensate for drag. This will make it perfect.Wed, 30 May 2012 08:39:13 GMTMenaceComment by Fattie on Fattie's answer
http://answers.unity.com/comments/259742/view.html
It's generous of Aldo to provide a ballistic formula -- I've noticed many, many people starting out with Unity ask tis question -- and it always leads to vast confusion!Wed, 30 May 2012 08:28:29 GMTFattieComment by Fattie
http://answers.unity.com/comments/259740/view.html
Important ... You absolutely have to be using **real sized models** in Unity. It's a must, or nothing will work. Your cannonball must be the actual size of a real cannonball, your people must be actually 2m high, everything **must be** actual size. Then, all masses must be realistic in the real world. Hope it helps!Wed, 30 May 2012 08:27:27 GMTFattieComment by Menace on Menace's answer
http://answers.unity.com/comments/259717/view.html
Compensation should do the trick.
With the right compensation taking the rigidbody.drag into account the cannonball should land on the target again. Any idea?Wed, 30 May 2012 07:09:12 GMTMenaceComment by aldonaletto on aldonaletto's answer
http://answers.unity.com/comments/259604/view.html
This function ignores drag. If we knew the drag equation, maybe it could be taken into account - but I haven't the slightest clue about how it's calculated. In real world physics, it's proportional to the square of the velocity - but this doesn't happen with Unity's drag.<br>
But why do you want to add drag to the ballistic trajectory? If the function could compensate for the drag effect, the cannonball would land at the desired point, and nobody would see a difference - so, why to add drag?Wed, 30 May 2012 00:28:41 GMTaldonalettoComment by Menace on Menace's answer
http://answers.unity.com/comments/259557/view.html
Aldo,
Drag is not taken into account. Any idea on what to do if drag is set to for example .25 and still get the right velocity for the projected target distance?Tue, 29 May 2012 23:11:01 GMTMenaceComment by Menace on Menace's answer
http://answers.unity.com/comments/259558/view.html
Drag is not taken into account. When drag is set to for example to .25, the calculated velocity is not enough to reach the target. Any idea on how to take the drag into account and still make the cannonball land on the target position?
Btw. Works great if drag=0 !
Thnx.Tue, 29 May 2012 22:53:59 GMTMenaceAnswer by aldonaletto
http://answers.unity.com/answers/148899/view.html
You must lower the elevation angle. The greatest distance is reached with a 45 degrees elevation, but the ball takes a lot to fall. You can experiment with 30, 20, 15 degrees - but the lower the angle, the higher the force you must apply for the cannon ball to reach the target. It may be easier to set the cannon ball velocity instead of the force applied.
The function BallisticVel in the script below calculates the velocity vector necessary to reach the object **target** when shooting at **angle** elevation. It assumes the target and the cannon are at the same height, but provides some correction for small differences (small when compared to the distance):
function BallisticVel(target: Transform, angle: float): Vector3 {
var dir = target.position - transform.position; // get target direction
var h = dir.y; // get height difference
dir.y = 0; // retain only the horizontal direction
var dist = dir.magnitude ; // get horizontal distance
var a = angle * Mathf.Deg2Rad; // convert angle to radians
dir.y = dist * Mathf.Tan(a); // set dir to the elevation angle
dist += h / Mathf.Tan(a); // correct for small height differences
// calculate the velocity magnitude
var vel = Mathf.Sqrt(dist * Physics.gravity.magnitude / Mathf.Sin(2 * a));
return vel * dir.normalized;
}
var myTarget: Transform; // drag the target here
var cannonball: GameObject; // drag the cannonball prefab here
var shootAngle: float = 30; // elevation angle
function Update(){
if (Input.GetKeyDown("b")){ // press b to shoot
var ball: GameObject = Instantiate(cannonball, transform.position, Quaternion.identity);
ball.rigidbody.velocity = BallisticVel(myTarget, shootAngle);
Destroy(ball, 10);
}
}
To test it, create an empty object about 2 units above the ground and attach this script. Make sure the cannonball don't touch any collider when instantiated, or it will not reach the target. Drag the target and the cannonball prefab to the corresponding variables and press b to shoot.Wed, 27 Jul 2011 02:44:25 GMTaldonalettoAnswer by Kith
http://answers.unity.com/answers/148404/view.html
You can add a script to the cannon ball prefabs that adds a constant downward force. By adjusting the amount of the downward force, you should be able to adjust the arc that the cannon ball makes.Tue, 26 Jul 2011 03:05:04 GMTKith