- Home /
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:
- Make a cube with this script on it. 
- Make another cube as a child. (no collider) 
- Set the child as the "barrel" var. 
- Set the maxRange variable to desired maximum range. 
- Set any object (at about the same height) as a target 
- 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--;
             }
     }
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));
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!
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!
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                