Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by rjdfhorn2006 · Jul 26, 2011 at 02:40 AM · physicsrigidbodyforceprojectile

Shooting a cannonball.

I have a turret that fires cannonballs. When the player presses the appropriate button, this line of code is ran:

projectile.rigidbody.AddForce(transform.forward * 2000, ForceMode.Impulse);

Here's the problem - the cannonball fires just fine, but it takes a very long time before it begins to descend. This causes a huge problem since the cannonballs always fly over the enemy instead of landing near them. I basically want the cannonball to fall faster, but follow a clean arc. Any ideas on how to do this properly?

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fattie · May 30, 2012 at 08:27 AM 0
Share

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!

6 Replies

· Add your reply
  • Sort: 
avatar image
22
Best Answer

Answer by aldonaletto · Jul 27, 2011 at 02:44 AM

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.

Comment
Add comment · Show 17 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Menace · May 29, 2012 at 10:53 PM 1
Share

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.

avatar image Menace · May 29, 2012 at 11:11 PM 0
Share

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?

avatar image aldonaletto · May 30, 2012 at 12:28 AM 0
Share

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.
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?

avatar image LeleUnity aldonaletto · Sep 14, 2020 at 04:32 PM 0
Share

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...

avatar image Menace · May 30, 2012 at 07:09 AM 0
Share

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?

avatar image Fattie · May 30, 2012 at 08:28 AM 0
Share

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!

Show more comments
avatar image
2

Answer by Dschonny2000 · Nov 25, 2013 at 05:05 AM

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;
         
     }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image sandeepsmartest · Apr 19, 2014 at 09:14 AM 0
Share

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) $$anonymous$$ay b am incorrect can u please help me with this???

avatar image
1

Answer by Kith · Jul 26, 2011 at 03:05 AM

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.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by Kergal · Aug 05, 2012 at 10:45 PM

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?

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by LeleUnity · Oct 04, 2020 at 10:39 AM

@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!

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image hacky4 · Feb 09, 2021 at 10:46 AM 0
Share

I agree, the doesnt work for a range of angles for me too. Don't know what is the issue.

  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

22 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How do I arc a rigidbody so it lands on a target? 2 Answers

Hovercraft Physics Problems 1 Answer

Returning a rigidbody back to its original x and z rotations through physics forces. 2 Answers

How to make a object jump constantly at y and move to the next position to z (perfectly) 0 Answers

Kinematics: Trying to get an object to land at a known point 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges