Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by RetepTrun · Nov 01, 2011 at 09:16 PM · rigidbodyvelocitymathangleprojectile

Projectile launch insufficient velocity

I am making a canon in which the maximum range is set in the inspector and a target within that range is fired upon during the game. The canon must rotate to the right angle to account for gravity. How it is suposed to work: at start assume 45deg angle and find speed needed to shoot the set maximum range. Now if a target is within that range we will be guaranteed enough power to hit it with barrel angle.

Its not finding enough power to hit maximum range and therefore anything in between.

I used this for the math and I'm pretty sure I scripted it right http://en.wikipedia.org/wiki/Trajectory_of_a_projectile

See for youself, setup is simple:

  1. Make a cube with this script on it.

  2. Make another cube as a child. (no collider)

  3. Set the child as the "barrel" var.

  4. Set the maxRange variable to desired maximum range.

  5. Set any object (at about the same height) as a target

  6. Set a rigidbody as "projectile

The code may appear a bit long at a 1second glance but it isnt really and I've commented it.

The speed and dist(how far target is) are just temporary as the script adjusts them. Wanted to watch most variables so I didnt make them private.

  var speed:float=10;     //speed of projectile
     var g = 9.81;           //gravity
     var dist:float = 200;  //how far target is
     var maxRange:float=200;  //set your maximum range
     var degrees:float; //launch angle in degrees
     var rads:float;    //                radians
     
     var currot:float=1; //how far we are rotated now
     var rotspeed:int=1; //how fast we rotate the barrel
     var turnspeed:int=10; //how fast base rotates
     var target:Transform; //the target
     var barrel:Transform; //part that aims vertically and bullets come out
     
    
     var projectile : Rigidbody;
     var reloadTime = 0.5;
     var ammoCount = 20;
     private var lastShot = -10.0;
     
     function Start(){
     
     //find speed needed to reach set maximum range at 45deg elevation
     speed=Mathf.Sqrt(maxRange*g);
     }
     
     function Update () {
     
     //aiming the base and range
     if(target){
         //change to local coordinates
         var targetRelative = transform.InverseTransformPoint(target.transform.position);
 
 //distance to target
 
 var range=Vector3.Distance(transform.position,target.position);
     
         //aiming the base and range
             if(range<maxRange){
             //distance to shoot is equal to how far away target is
             dist=range;
     
                 if (targetRelative.x > .004)
                 transform.Rotate(0,turnspeed * Time.deltaTime,0);
                 if(targetRelative.x < -.004)
                 transform.Rotate(0,turnspeed * Time.deltaTime*-1,0);
             }
     }
     
     //math to find angle needed to hit a target within maximum range
     rads=.5*(Mathf.Asin((dist*g)/(speed*speed)));
     degrees=rads*Mathf.Rad2Deg; //conversion to degrees
     
     //rotate the barrel to the degrees needed
         if(currot<degrees-.2){
         barrel.transform.Rotate(Vector3.right*Time.deltaTime*rotspeed*-1);
         currot=currot+rotspeed*Time.deltaTime;
         }
         else if(currot>degrees+.2){
         barrel.transform.Rotate(Vector3.right*Time.deltaTime*rotspeed);
         currot=currot-rotspeed*Time.deltaTime;
         }
         
         
         //fire when barrel is rotated
         if(currot>degrees-.5&&currot<degrees+.5)
         Fire();
         
     }
     
     //basically the rocket launcher from fps tutorial
     function Fire(){
     
     if (Time.time > reloadTime + lastShot && ammoCount > 0) {
             // create a new projectile, use the same position and rotation as the Launcher.
             var instantiatedProjectile:Rigidbody=Instantiate(projectile,barrel.transform.position,barrel.transform.rotation);
             
             // Give it an initial forward velocity. The direction is along the z-axis of the missile launcher's transform.
             instantiatedProjectile.velocity=transform.TransformDirection(Vector3(0,0,speed));
             
             lastShot=Time.time;
             ammoCount--;
             }
     }
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

2 Replies

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

Answer by RetepTrun · Nov 02, 2011 at 01:54 AM

Aha found it. ty anyway, sounds like good advise.

i tried some more extreme ranges and noticed eventually that even though the projuctile was rotated the right way that it wasnt actually ever traveling up at all, just faster forwards. I figured out it had been given the actual launch direction of the launcher base but not the barrel, which fooled me for awhile because the left-right direction would still be correct and the projectile still got some distance.

Now the thing is DEADLY, the only way to escape is to keep moving, get under the barrel, or run out of its range.

in the fire() function this is the correct code

instantiatedProjectile.velocity=barrel.transform.TransformDirection(Vector3(0,0,speed));

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 WillTAtl · Nov 02, 2011 at 03:30 AM 0
Share

ah, I missed that in skim$$anonymous$$g the code before, was focused on your math. Good to know the integrator - which from what I've gathered since my answer is basically verlet - is not deviating so wildly after all.

Glad you fixed your problem, however you did it!

avatar image
1

Answer by WillTAtl · Nov 01, 2011 at 09:56 PM

I'm not seeing an error in your math, so I'm forced to guess that any discrepancy is the result of integration errors. Not sure what integration method unity uses for it's physics calculations, but it will be based on updating every physics timestep, while the function you're using is the "perfect" prediction.

First, make sure you've got drag set to 0 in the projectile prefab's rigidbody settings; it's 0 by default, so the rest of this post assumes it was already off and you're still off the expected mark.

If that wasn't the problem, two possible ways to deal with this come to mind: first, and easiest, you could shorten the physics timestep; the smaller the steps, the more closely the resulting trajectory will correspond to the "perfect" mathematical trajectory. This will come with a performance hit, how much of one depending on how much is going on in the scene, but if the scenes are relatively simple, physics-wise, it might not be a problem.

Alternately, you could NOT use the physics system at all. Instead, write an update function for your projectile that solves the trajectory function for the current absolute time T every frame. This will be more expensive for the projectiles themselves, but won't have the same increased cost for all rigid bodies in the scene like shortening the timestep might. For how to write the update function, see this article which works through the math for setting up the functions based on initial position, velocity, and angle.

Good luck, hope this helps!

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Increase velocity without changing trajectory 1 Answer

Projectile not firing right - simple angle and velocity problem? 2 Answers

Rigidbody loses speed 1 Answer

Controll 3D Rigidbody Projectile with Joystick 1 Answer

Need some help with firing projectile at player using Rigidbody Velocity 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