• 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
9
Question by yetanotherday · May 06, 2012 at 02:07 AM · shootingballtrajectorythrow

Calculating ball trajectory in full 3d world

Hello

We have quite common problem but we couldn’t figure out any working solution any that fits (all of those bits of code we found on unity forums doesn’t tell us much because we are not programmers). If that’s possible we prefer code in javascript.

Our situation:

  1. Players character is grenadier in full 3d world (he can jump and walk on different levels of high)

  2. Players sees that character as third person from isometric-like point of view (similar to most crpg games like Diablo)

  3. In any time player can throw grenade to any place within range by clicking mouse button on the ground

  4. We know how to find coordinates of player and that click on the ground

    Our problem:

  5.  We don’t know how to calculate the trajectory of thrown grenade in 3d world. Grenade should start from characters position and ends on the clicked ground (right now its misses badly).
    
  6.  We would like to have control over speed, angle and distance in which player can throw grenade.
    

This doesn’t have to be 100% precise , we prefer something that works and works really fast.

Image for better understanding our problem:

alt text

Those two clips can show you what we searching for:

http://www.vimeo.com/8900520 – this one have something we are looking for

http://www.youtube.com/watch?v=kNabvLyUXzI#t=0m32s - here is “feel” of throw we are looking for

Thanks SO much!

trajectory.jpg (21.4 kB)
Comment
Add comment
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

8 Replies

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

Answer by aldonaletto · May 11, 2012 at 12:47 AM

The function BallisticVel below calculates the necessary velocity to reach a target given the launching angle and the target transform. It uses a ballistic trajectory that originally only worked fine for objects at the same height, but I added code to compensate to some extent for different heights - maybe this correction is precise enough in your case.
The function BallisticVel returns a vector velocity ready to be assigned to the grenade's rigidbody.velocity: the rigidbody goes in a ballistic trajectory under physics control and lands on the target point. This script must be added to the grenade launcher (weapon, arm, whatever) because it uses the owner object position to calculate the velocity. The grenade must also not touch any collider when instantiated, or the reaction to the collision will deviate its trajectory:

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 target: Transform; var grenadePrefab: Transform;

function Update(){ if (Input.MouseButtonDown(0)){ var grenade: Transform = Instantiate(grenadePrefab,...,...); grenade.rigidbody.velocity = BallisticVel(target, 45); // pass the angle and the target transform } } The higher the angle, the lesser the error when the heights are different (but the velocity is also lower, what may be a good thing for a grenade). The function doesn't check for invalid parameters, thus it may throw exceptions if the angle is too high (near to 90) or too low (near to 0).

EDITED: If you want to pass the click point instead of a target transform, just modify the first lines of BallisticVel (the target transform is used only to get the target position anyway):

function BallisticVel(targetPos: Vector3, angle: float): Vector3 {
    var dir = targetPos - transform.position;  // get target direction
    ...
Comment
Add comment · Show 8 · 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 yetanotherday · May 11, 2012 at 08:30 PM 0
Share

WOW! That works! Thank You very much!

avatar image Zero_Zagarth · Sep 27, 2012 at 02:15 PM 0
Share

Hey! that's excellent! Thank you brother

avatar image corax · Oct 02, 2012 at 05:34 PM 0
Share

What if we need to check lower ground targets or target up above our heads (90degrees)?

avatar image aldonaletto · Oct 03, 2012 at 12:42 AM 0
Share

You could calculate the elevation angle of the target with a function like this:

 function ElevationAngle(target: Transform): float {
   // find the cannon->target vector:
   var dir = target.position - transform.position;
   // create a horizontal version of it:
   var dirH = Vector3(dir.x, 0, dir.y);
   // measure the unsigned angle between them:
   var ang = Vector3.Angle(dir, dirH);
   // add the signal (negative is below the cannon):
   if (dir.y < 0) ang = -ang;
   return ang;
 }

The target angle may be used to avoid errors, and also to calculate the shooting angle - like this:

 if (Input.$$anonymous$$ouseButtonDown(0)){
   var ang = ElevationAngle(target);                                                                                                                           
   var shootAng = ang + 15; // shoot 15 degree higher
   // limit the shoot angle to a convenient range:
   shootAng = $$anonymous$$athf.Clamp(shootAng, 15, 85)
   // and shoot:
   var grenade: Transform = Instantiate(grenadePrefab,...,...);
   grenade.rigidbody.velocity = BallisticVel(target, shootAng);
 }
avatar image corax · Oct 03, 2012 at 09:18 AM 0
Share

$$anonymous$$y problem is slightly different if you have spare time can check our here :D http://answers.unity3d.com/questions/320449/rigidbody-jump-on-platform.html

Show more comments
avatar image
28

Answer by Tomer-Barkan · May 14, 2013 at 12:36 PM

Actually there's a very simple way using basic physics formulas, with no errors whatsoever regardless of the elevation:

 private Vector3 calculateBestThrowSpeed(Vector3 origin, Vector3 target, float timeToTarget) {
     // calculate vectors
     Vector3 toTarget = target - origin;
     Vector3 toTargetXZ = toTarget;
     toTargetXZ.y = 0;
     
     // calculate xz and y
     float y = toTarget.y;
     float xz = toTargetXZ.magnitude;
     
     // calculate starting speeds for xz and y. Physics forumulase deltaX = v0 * t + 1/2 * a * t * t
     // where a is "-gravity" but only on the y plane, and a is 0 in xz plane.
     // so xz = v0xz * t => v0xz = xz / t
     // and y = v0y * t - 1/2 * gravity * t * t => v0y * t = y + 1/2 * gravity * t * t => v0y = y / t + 1/2 * gravity * t
     float t = timeToTarget;
     float v0y = y / t + 0.5f * Physics.gravity.magnitude * t;
     float v0xz = xz / t;
     
     // create result vector for calculated starting speeds
     Vector3 result = toTargetXZ.normalized;        // get direction of xz but with magnitude 1
     result *= v0xz;                                // set magnitude of xz to v0xz (starting speed in xz plane)
     result.y = v0y;                                // set y to v0y (starting speed of y plane)
     
     return result;
 }

Simply call the function with the origin position, target position and how long you want the throw to take (which will affect the angle). Then apply the result on the object you want to throw with rigidbody.AddForce(throwSpeed, ForceMode.VelocityChange);

Comment
Add comment · Show 10 · 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 Mangesh21 · Oct 03, 2013 at 05:53 PM 0
Share

what is toHoopXZ in above script??

avatar image Tomer-Barkan · Oct 09, 2013 at 05:00 PM 0
Share

was supposed to be toTargetXZ.

avatar image Velo222 · Oct 30, 2013 at 06:50 PM 2
Share

WOW, the function tbkn posted is amazing for me! Thank you very much for posting that. $$anonymous$$an there's some smart people in this world haha.

Just so other people know, the "calculateBestThrowSpeed()" function tbkn posted works great. $$anonymous$$y projectile reaches the static target point AND I can control how quickly. Thank you so much tbkn.

avatar image -chris · Jan 31, 2014 at 11:42 AM 0
Share

I had to change 0.5f to 1f because my projectiles were only reaching half-way, but 1f does the trick for me! Thanks

avatar image BjoUnity3d · Mar 15, 2014 at 11:17 AM 2
Share

I didn't have to change anything, tbkn's script and instructions worked perfectly. Velo222, my feelings exactly. I've been working on this all night and this just solved everything. Nice work tbkn.

Show more comments
avatar image
3

Answer by Piflik · May 10, 2012 at 09:16 PM

Probably you know all this already, but still...you can calculate a parabola given 3 points. You already have two of them: the player's position and the target point. The third would be (roughly) the apex, take half of the distance between the player and the target and the height you want (maybe with player control over the height...how long he presses the mouse button, for example, so he can lob the grenade over walls or even through windows with some exercise).

It would be a good idea to reduce the equation to 2 dimensions. You eliminate the direction and only use the distance. The first point would be (0, chracter.height), the second would be (distance, 0), the last one (distance/2, throw.heigth).

To calculate the parabola you have Ax² + Bx + C = y. Put your three coordinates in there, and you can calculate A, B and C.

You now have the trajectory your grenade should follow, minus the direction, but it should be easy to rotate it around the player once it is calculated. You probably have to control the grenade completely to follow the trajectory. The physics might not give you the desired results. You could try to calculate the starting velocity you need from the height and the distance, but I don't know how difficult that will be and how reliable.

One thing that could be a problem, is to mirror the trajectory at obstacles...don't have a spontaneous idea for this one.

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
2

Answer by fafase · May 06, 2012 at 07:04 AM

check there: http://hyperphysics.phy-astr.gsu.edu/hbase/traj.html#tra7

Then, you will have to compute when they are on different levels, y0 becomes the y of the grenadier. Check "where will it land" at the bottom of the page for this issue.

Also, add the z position to your calculation in the same fashion as x.

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 Ankit Priyarup · Mar 15, 2014 at 11:39 AM

http://www.youtube.com/watch?v=ZCDiTxBT1nE Here's a solution

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

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

28 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 avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Kinect character throwing ball using Physics 1 Answer

How do you make a shoot up feature like in dx-ball? 2 Answers

Android Build help needed regarding ball throw 1 Answer

How can I show trajectory of a bouncing ball OnCollisionEnter/OnCollisionExit? 0 Answers

Show trajectory of a bouncing ball 0 Answers


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