Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
3
Question by chrono1081 · Jun 18, 2011 at 05:23 AM · forceprojectile

How to make projectiles shoot towards their target at variable distances?

Hi guys,

Let me start off by saying I checked google, looked through the documentation and searched the answers and have not found what I was looking for.

I have a canon in my game that sits in the middle of the level that shoots fireballs at the player wherever the player is.. The canon rotates to always face the player and fires the fireballs in the direction of the player, but I am having a hard time trying to calculate the force of the fireballs so that when the player moves the force of the fireball is adjusted to compensate for the distance between the player and the canon.

Here is my script so far:

 var fireballObject : Rigidbody;
 var delayAmount = 2.0;
 var target : Transform; 
 
 private var timeDelay = 0.0;
 
 var fireballObject : Rigidbody;
 var delayAmount = 2.0;
 var target : Transform; 
 
 private var timeDelay = 0.0;
 
 function Update () {
 
     if(Time.time > timeDelay)
     {
         timeDelay = Time.time + delayAmount;
         Debug.Log("Fireball Time!");
         createFireball();
     }
     
     else
     {
         Debug.Log("Still Waiting");
     }
 
     
 }
 
 function createFireball()
 {
     var newFireballObject : Rigidbody = Instantiate(fireballObject, transform.position, transform.rotation);
     newFireballObject.name = "fireball";
     
     newFireballObject.rigidbody.velocity = transform.TransformDirection(Vector3(0, 0, 0));
 }

I know I need to adjust the transform.TransformDirection(Vector3(0, 0, 0)); to compensate for the distance between the canon and the player but I'm just not sure how to go about it. Does anyone have any suggestions?

Also to be more specific this canon does not shoot upwards first, it shoots straight out and the projectile, which is a sphere with a rigidbody attached moves forward at a certain force before succumbing to gravity.

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

5 Replies

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

Answer by chrono1081 · Jun 22, 2011 at 03:27 PM

Thank you all so much for the advice! I haven't got to try any new implementations yet because its finals week but I will try soon :)

Ok it appears I have it working and it will work with rigidbodies!

This code is better optimized if anyone wants it:

 //Exposed variables
 var fireballObject : Rigidbody;
 var target : Transform; 
 var delayAmount = 2.0;
 var forceMultiplier = 1.5;
 
 private var timeDelay = 0.0; //Delay the amount of time until next fireball
 
 function Update () {
 
     //Create variables to hold the vectors
     var targetVector = target.position;
     var sourceVector = transform.position;
     var newVector = Vector3((target.position.x - transform.position.x), (target.position.y - transform.position.y), (target.position.z - transform.position.z));
 
     /*
     The equation for this is:
     T = SQRT( 2h/g) However the sqrt can stay out of the code.
     Make sure to get the absolute value of the equation to avoid a negative square root
     */
     //Solve for time
     var emitterYPos = transform.position.y; //Y distance from ground
     var Ay = Physics.gravity.y; //Ay (Acceleration Y)
     var t = Mathf.Abs( (2 * emitterYPos) / (Ay) ); //Time element
     
     /*
     The equation for this is:
     Vix = d * sqrt(g/2H) However the square root can be left out of the code
     */
     //Solve for the initial X Velocity
     var targetXPos = target.position.x - transform.position.x; //X distance from source
     var targetZPos = target.position.z - transform.position.z; //Z distance from source
     var Ax = 0; //Ax (Acceleration X)
     
     //Calculate the X and Z distances from the target
     var Vix = targetXPos * (Mathf.Abs(Ay / (2 * emitterYPos)));
     var Viz = targetZPos * (Mathf.Abs(Ay / (2 * emitterYPos)));
 
     //Check to see if it is time to shoot a fireball
     if(Time.time > timeDelay)
     {
         timeDelay = Time.time + delayAmount;
         
         //Compare X to Z distances and use whichever is greater for the trajectory
         if(Mathf.Abs(Vix) > Mathf.Abs(Viz))
         {
             createFireball(Vix);
         }
         
         else
         {
             createFireball(Viz);
         }    
     }    
 }


 //Create fireball object
 function createFireball(V)
 {
     var newFireballObject : Rigidbody = Instantiate(fireballObject, transform.position, transform.rotation);
     newFireballObject.name = "fireball";
 
     newFireballObject.rigidbody.velocity = transform.TransformDirection(Vector3(0, 0, Mathf.Abs(V * forceMultiplier)));
     
 }

You will need to assign a target to it to get it to work.

Comment
Add comment · Show 3 · 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 flaviusxvii · Jun 22, 2011 at 03:59 PM 1
Share

You are officially awful at formatting code in your posts :D. I fixed the code from your original post and I'll fix this too.

avatar image chrono1081 · Jun 22, 2011 at 04:02 PM 0
Share

Thank you so much! :D I definitely need to play around with the formatting options more. I do suck at them : /

avatar image AndrewRyan · Nov 29, 2014 at 01:50 PM 0
Share

Thank you so much chrono for sharing your final code.

avatar image
2

Answer by testure · Jun 18, 2011 at 05:48 AM

Check out the accurate lob example for iTween.. it does pretty much exactly what you're describing:

http://itween.pixelplacement.com/examples.php

Although, if you're able to get it going with rigid bodies, I'd like to know as well!

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 Owen-Reynolds · Jun 18, 2011 at 03:50 PM

The basic way to "lead" someone is to estimate time to hit them, and then aim at where they will be in that many seconds (the time to the new target won't be exactly the same, but close enough. Can add tricks later.) The basic way to "lead" is:

 float flightTime = (targ.position - transform.position).magnitude / shotSpeed;
 Vector3 aimPos = targ.position + targ.rigidbody.velocity * flightTime;
 // NOTE: if not an RB, look up their script speed

 Vector3 aimDir = aimPos - transform.position;

Giving the shot a Y speed so it "drops" at the correct distance is a separate problem, and makes the 1st problem more difficult (since angling up reduces flat speed.) Giving the shots a fixed "no gravity" flight time makes it even worse (since the common solutions don't have that in them.)

I'd do it with no gravity first, then "fake" the gravity by aiming a tiny bit up at anything beyond my range (maybe a small random, to make it look like the gunner is guessing.)

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 testure · Jun 18, 2011 at 07:12 PM

I have no idea how you'd go about implementing it (math/physics is not my strong point), but this seems to be the formula you're after:

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

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 chrono1081 · Jun 18, 2011 at 09:55 AM

I'm VERY close, I just can't get it quite right.

My calculations on paper come up correct, but I can't it it to work in Unity. The canon follows the player, and shoots the fireballs, but the behavior isn't correct. If I have my script like below:

 function Update () {

 //Create variables to hold the vectors
 var targetVector = target.position;
 var sourceVector = transform.position;
 var newVector = Vector3((target.position.x - transform.position.x), (target.position.y - transform.position.y), (target.position.z - transform.position.z));

 /*
 The equation for this is:
 T = SQRT( Y / ((0.5 * Ay) + (Viy * T)) )
 */

 var emitterYPos = transform.position.y; //Y distance from ground 
 print("emitterYPos = " + emitterYPos);
 var Ay = Physics.gravity.y; //Ay (Acceleration Y)
 print("Ay = " + Ay);
 var t = Mathf.Sqrt( (emitterYPos * -1) / (0.5 * Ay) ); //Entire equation, don't forget to multiply distance from ground by a negative to avoid a negative square root
 
 print("T = " + t);
 
 /*
 The equation for this is:
 Vix = (x + 0.5 * Ax * T^2) / T
 */
 
 
 var targetXPos = target.position.x; //X distance from source
 var Ax = 0; //Ax (Acceleration X)
 var Vix = (targetXPos / t);
 
 print("VIX " + Vix);


 //Check to see if it is time to shoot a fireball
 if(Time.time > timeDelay)
 {
     timeDelay = Time.time + delayAmount;
     Debug.Log("Fireball Time!");
     createFireball(Vix);
     
     print("TEST");
     print("T = " + t);
     print("X = " + targetXPos);
     print("Y = " + emitterYPos);
     print("Ay = " + Ay);
     print("VIX = " + Vix);
     print("VIX2 = " + Mathf.Abs(Vix));
 }
 
 else
 {
     Debug.Log("Still Waiting");
 }

 

}

//Create fireball object function createFireball(vX) { var newFireballObject : Rigidbody = Instantiate(fireballObject, transform.position, transform.rotation); newFireballObject.name = "fireball";

 newFireballObject.rigidbody.velocity = transform.TransformDirection(Vector3(0, 0, vX));
 

}

Then the fireballs are very weak until I get closer to the canon. If I take this line:

var targetXPos = target.position.x; //X distance from source

and change it to

var targetXPos = target.position.z; //Z distance from source

then the result is almost perfect, except when I approach the Z axis. Then the fireballs drop right in front of the canon :/ Anyone have any ideas?

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

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Shooting a cannonball. 6 Answers

How to control the speed of the projectile motion? 1 Answer

Firing projectile in curve 1 Answer

Setting limits to my trajectory 2 Answers

Making force 0 at some 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