How to rotate a gun in the right way to anticipate the trajectory of a moving object

I'm trying to create a gun that fires to a moving object, anticipating its future position. To do so, I calculate the horizontal and the vertical angles that the gun has to rotate to anticipate the target's movement. The problem comes when i try to rotate the gun. If I use methods like transform.rotate or transform.rotation = Quaternion.euler .. the rotation is not instant and the projectiles fired by the gun don't intercept the target. If i use the metod transfor.rotation = Quaternion.FromToRotation, the gun starts rotating instantly in the right position, then back in another position that, for me, has no sense.

The only solution I found is to:

create an empty GameObject

GameObject go = new GameObject("go");

set its position to the coordinates calculated from the horizontal and the vertical angle

Vector3 coords = Vector3( Mathf.Sin(horizontalAngle), Mathf.Sin(VerticalAngle), Mathf.Cos(HorizontalAngle));
go.transform.position = gun.transform.InverseTransformPoint(coords);

make the gun point to this empty GameObject using transform.LookAt.


The problem is that all this runs only if the target is moving only horizontally (on the x,z plane) or vertically (on the y,z plane). Note that if the target moves only horizontally, the verticalAngle is 0, while if it moves only vertically the horizontalAngle is 0. If I move the target in both planes the gun goes crazy.

I tried to understand where the problem is, but I can not.

PS: I'm not posting the whole source code just to avoid confusing this message, but if anyone needs it to understand the situation more, I can write it.

Thanks in advance to anyone able to resolve this mess!

Try this answer HERE (if I'm understanding your question correctly). There are a couple of others that pop up if you search for "lead target" here on Unity Answers...

HAHA I totally ran into the same problem :) Since using actual projectiles won't actually hit until you factor in some kind of lead time. Sadly, I am at work and unable to post my code, but my code needs to be re-written to work better anyway. I can't solve the problem for you, but I can give you some pointers that I found useful. First of all, I changed my code to have a "targeting" gameobject and the actual turret gameobject. I then made my "targeting" object a child of the turret. This way, the turret itself that does the firing is able to aim at the position where the target will be, and the targeting gameobject aims at where the target is. Once the targeting gameobject finds a target within range and a rotation, it sets the target of the actual turret, that does the firing, to whatever object it found. Now, for what you're looking for, the tricky part. The way I handle it is I rotate toward a point in space that takes the target position plus the target lead time.

var leadDirection : Vector3 = target.position - transform.position;
leadDirection += leadDirection.magnitude
transform.rotation = Quaternion.RotateTowards(transform.rotation,
                       Quaternion.LookRotation(leadDirection, transform.up),

is the code I am using currently. targetDirection is a Vector3 normalized, and targetSpeed is a float equal to targetDirection.magnitude. If you don't want the extra calculations, you can just get rid of targetSpeed all together and simply not normalize the targetDirection, as it will have the speed in all given Vectors, as I do in my actual code. The trick, really, is to somehow get the velocity of the target you are trying to hit. It all depends on how you're moving your target. I am using physics forces to move my targets, so I put a very simple script on my targets called LeadInfo which takes the rigidbody.velocity and then my turret script takes that value as targetDirection and it works well. If you don't have a rigidbody and can't easily get the velocity, it can be done. I hope this helps you somewhat get on your way, again, I'm sorry I don't have my real code readily available to show you. Check my question for more info :