• 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
1
Question by felixpk · Aug 13, 2014 at 04:47 PM · physicsmathcurvetrajectory

Bomb Trajectory for a "Water Canon" (Maths)

Hey there! I have the following problem:

  • I have a Particlesystem that shoots waterparticles with the local vel = 10

  • There is a target that is not necessarily at the same height as the canon

The Gif should explain what it should be doing, even though there is no variance in the height.

Example

So I started with this formula:

alt text

This formula calculates the needed angle with a given distance ,velocity and height, it looks like so in C#

 private float FindAngleToShoot(float vel, float distance, float height) {
 
         float g = Physics.gravity.y;
 
         return Mathf.Atan(Mathf.Pow(vel, 2) + Mathf.Sqrt(Mathf.Pow(vel, 4) - g * (g * Mathf.Pow(distance, 2) + 2 * height * Mathf.Pow(vel, 2))) / g * distance);
 
 }

I don't really know why this does not work, but it did not change the angle properly.

I started to google again and found another formula, in C# like so:

 private float FindAngleToShoot2(float v, float s) {
         float g = Physics.gravity.y;
 
         return Mathf.Sin(2*(Mathf.Pow(v,2) * g) / Mathf.Pow(s,2)) * Mathf.Rad2Deg;

}

Now I was able to see the angle changing its value, but it changed not properly. It is hard to describe what actually happens, but it was "flattering" around when I moved the canon forward and backward. At some point the water really hit the fire.

So I thought about an appropiate approach and thought you guys could help me.

  1. find the distance to target

  2. be able to decide to have a high angle approach or a low angle approach

  3. setting the angle and velocity of the water

Shouldn't that be all?

And I am going to attach the whole "water" class that should do all the maths.

 public class Water: MonoBehaviour {
 
     public Transform target;
     private Vector3 targetPos;
 
     public float speed = 12; //Speed of the localVelocity of the particle System
 
     void Start() {
         targetPos = target.position;
     }
 
     void Update() {
 
         transform.localEulerAngles = new Vector3(FindAngleToShoot2(speed, Vector3.Distance(transform.position, targetPos)), 0, 0);
 
     }
 
     //approach 1
     private float FindAngleToShoot(float vel, float distance, float height) {
 
         float g = Physics.gravity.y;
 
         return Mathf.Atan(Mathf.Pow(vel, 2) + Mathf.Sqrt(Mathf.Pow(vel, 4) - g * (g * Mathf.Pow(distance, 2) + 2 * height * Mathf.Pow(vel, 2))) / g * distance);
 
     }
 
     //approach 2
     private float FindAngleToShoot2(float v, float s) {
         float g = Physics.gravity.y;
 
         return Mathf.Sin(2 * (Mathf.Pow(v, 2) * g) / Mathf.Pow(s, 2)) * Mathf.Rad2Deg;
     }

Sorry for the oversized post :/

I really appreciate any kind of help!

Felix

c14d095c7d480ca398e25c01a53ed7be.png (2.2 kB)
inclinedthrow.gif (464.0 kB)
Comment
Add comment · Show 3
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 tanoshimi · Aug 13, 2014 at 05:56 PM 0
Share

If this is a particle system, why are you doing the maths manually? Why not just let the physics engine sort out the trajectory for you based on initial velocity, angle, and effect of gravity?

avatar image MrSteve1 · Aug 13, 2014 at 05:58 PM 0
Share

Yeah I was going to say the same thing. Can't you just switch Simulation Space to World?

avatar image christoph_r · Aug 13, 2014 at 06:33 PM 0
Share

tanoshimi and $$anonymous$$rSteve1, the issue isn't the physical representation of the trajectory from what I understand, it's rather a problem of ai$$anonymous$$g. I'll write something up. As a side note, the formula is most likely not working because you did not write it properly in code (you forgot at least one pair of brackets so the entire term that's supposed to be the numerator will be divided by the deno$$anonymous$$ator).

1 Reply

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

Answer by christoph_r · Aug 13, 2014 at 07:08 PM

This is actually more of a physics problem than a programming problem. Using a fixed velocity makes this much easier, though. The formula you picked out makes sense for these conditions. As you already wrote, the way to solve the problem is indeed to gather the information needed (so height and distance) and then calculate the angle with your formula. Then have the cannon shoot the water at the angle (and the fixed velocity). But there are a few other things to consider:

In code, the formula should look like this:

 a = Mathf.Atan((vel^2 - Mathf.Sqrt(vel^4 - g*(g * distance^2 + 2 *y * vel^2))/(g*distance))

Now as you see in the formula, there are two possible solutions, because you'll have to process a quadratic equation somewhere on the way to get to that formula. As you already noted, the two solutions are a high and a low angle (usually). The thing is, the further we get, the further the angle will converge towards 45° until it can't reach the target anymore with the set velocity. So one thing you should do is set a maximum distance for your cannon, or else the maths will start to get a bit messy. The other thing is: Does it ever make sense to use a greater angle? The disadvantage is that it takes a relatively long time for the water to reach the target, so if the target moves, that's not what you want. The advantage, though, is, that you can avoid hitting things you might otherwise hit with a low angle. If that's not something you need to consider though, the low angle is what you want to go with. The formula I wrote up should return the low angle (not 100% sure but pretty sure). To recap: Get the distance and height difference, throw them into the formula and adjust the water firing angle accordingly. Do you want your cannon to have limits for its rotation? If so, you need to set those, too. In that case, if the target is below the cannon and very close it might make sense to fire at a high angle. But if you need help with that, write a comment.

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 felixpk · Aug 14, 2014 at 04:08 PM 1
Share

I appreciate your answer, unfortunately I am not able to test your method because I found a simple method by simply changing the localVelocity of the particle System, it goes like this:

 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;
     }

It works so perfectly that I am begrudge to change it again. But again, thank you very much!

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

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

23 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

Related Questions

How to calculate the angle of a trajectory to hit the target 1 Answer

Drawing projectile trajectory 5 Answers

Calculating 3D Physics Prediction of Shot Direction with Moving target and moving gun (inertia) 1 Answer

LineRender and Gizmos.DrawRay are showing different results for the same input values 0 Answers

Simulating a trajectory that takes collisions into account 2 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